I am following this tutorial on how to make a custom watch face. After copying code and setting up the project properly (besides making coordinates dynamic for each and every watch) , I don't know how to actually run the app. I will post the project and code here:
And the code:
public class ZCycleWatchFaceService extends CanvasWatchFaceService{//Made specifically for moto 360
@Override
public Engine onCreateEngine() {
/* provide your watch face implementation */
return new Engine();
}
/* implement service callback methods */
private class Engine extends CanvasWatchFaceService.Engine {
static final int MSG_UPDATE_TIME = 0;
static final int INTERACTIVE_UPDATE_RATE_MS = 1000;
RectF smallCircleRect;
RectF bigCircleRect;
/* a time object */
Time mTime;
/* device features */
boolean mLowBitAmbient;
boolean mBurnInProtection;
float textY = 135;
float textSize = 20;
/* graphic objects */
Paint mHourPaint;
Paint mMinutePaint;
Paint mTextPaint;
/* handler to update the time once a second in interactive mode */
final Handler mUpdateTimeHandler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case MSG_UPDATE_TIME:
invalidate();
if (shouldTimerBeRunning()) {
long timeMs = System.currentTimeMillis();
long delayMs = INTERACTIVE_UPDATE_RATE_MS
- (timeMs % INTERACTIVE_UPDATE_RATE_MS);
mUpdateTimeHandler
.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
}
break;
}
}
};
/* receiver to update the time zone */
final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mTime.clear(intent.getStringExtra("time-zone"));
mTime.setToNow();
}
};
private void updateTimer() {
mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
if (shouldTimerBeRunning()) {
mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
}
}
private boolean shouldTimerBeRunning() {
return isVisible() && !isInAmbientMode();
}
@Override
public void onCreate(SurfaceHolder holder) {
super.onCreate(holder);
/* initialize your watch face */
bigCircleRect = new RectF(5 , 5 , 315 , 280);
smallCircleRect = new RectF(15 , 15 , 305 , 270);
/* create graphic styles */
mHourPaint = new Paint();
mHourPaint.setARGB(255, 77 , 175 , 240);
mHourPaint.setStrokeWidth(5.0f);
mHourPaint.setAntiAlias(true);
mHourPaint.setStrokeCap(Paint.Cap.ROUND);
mHourPaint.setTextSize(textSize);
mMinutePaint = new Paint();
mMinutePaint.setARGB(225 , 240 , 150 , 77);
mMinutePaint.setStrokeWidth(3.5f);
mMinutePaint.setAntiAlias(true);
mMinutePaint.setStrokeCap(Paint.Cap.ROUND);
/* allocate an object to hold the time */
mTime = new Time();
/* configure the system UI */
setWatchFaceStyle(new WatchFaceStyle.Builder(ZCycleWatchFaceService.this)
.setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
.setBackgroundVisibility(WatchFaceStyle
.BACKGROUND_VISIBILITY_INTERRUPTIVE)
.setShowSystemUiTime(false)
.build());
}
@Override
public void onPropertiesChanged(Bundle properties) {
/* get device features (burn-in, low-bit ambient) */
super.onPropertiesChanged(properties);
mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
mBurnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION,
false);
}
@Override
public void onTimeTick() {
/* the time changed */
super.onTimeTick();
invalidate();
}
@Override
public void onAmbientModeChanged(boolean inAmbientMode) {
/* the wearable switched between modes */
boolean wasInAmbientMode = isInAmbientMode();
super.onAmbientModeChanged(inAmbientMode);
if (inAmbientMode != wasInAmbientMode) {
if (mLowBitAmbient) {
boolean antiAlias = !inAmbientMode;
mHourPaint.setAntiAlias(antiAlias);
mMinutePaint.setAntiAlias(antiAlias);
//mSecondPaint.setAntiAlias(antiAlias);
//mTickPaint.setAntiAlias(antiAlias);
}
invalidate();
updateTimer();
}
}
@Override
public void onDraw(Canvas canvas, Rect bounds) {
/* draw your watch face */
// Update the time
mTime.setToNow();
//int width = bounds.width();
//int height = bounds.height();
// Find the center. Ignore the window insets so that, on round watches
// with a "chin", the watch face is centered on the entire screen, not
// just the usable portion.
//float centerX = width / 2f;
//float centerY = height / 2f;
//float circleCenter = centerY + FLAT_TIRE_OFFSET;
float minsPassed = mTime.minute;
float hoursPassed = mTime.hour;
float secsPassed = mTime.second;
float timePassedForBigCircle = minsPassed + hoursPassed * 60;
double radsForBigCircle = 0.87222222292 * timePassedForBigCircle;
double radsForSmallCircle = 10.4666667 * minsPassed;
double degForBigCircle = Math.toDegrees(radsForBigCircle);
double degForSmallCircle = Math.toDegrees(radsForSmallCircle);
canvas.drawArc(bigCircleRect , 0 , (float) degForBigCircle , false , mHourPaint);
canvas.drawArc(smallCircleRect , 0 , (float) degForSmallCircle , false , mMinutePaint);
float textX = 0;
if(hoursPassed >= 10){
textX = 320 - textSize * 4;
}else{
textX = textSize * 5;
}
canvas.drawText(hoursPassed + ":" + minsPassed , textX , textY , mHourPaint);
/*// Compute rotations and lengths for the clock hands.
float secRot = mTime.second / 30f * (float) Math.PI;
int minutes = mTime.minute;
float minRot = minutes / 30f * (float) Math.PI;
float hrRot = ((mTime.hour + (minutes / 60f)) / 6f ) * (float) Math.PI;
float secLength = centerX - 20;
float minLength = centerX - 40;
float hrLength = centerX - 80;
// Only draw the second hand in interactive mode.
/*if (!mAmbient) {
float secX = (float) Math.sin(secRot) * secLength;
float secY = (float) -Math.cos(secRot) * secLength;
canvas.drawLine(centerX, centerY, centerX + secX, centerY +
secY, mSecondPaint);
}*/
/*// Draw the minute and hour hands.
float minX = (float) Math.sin(minRot) * minLength;
float minY = (float) -Math.cos(minRot) * minLength;
canvas.drawLine(centerX, centerY, centerX + minX, centerY + minY,
mMinutePaint);
float hrX = (float) Math.sin(hrRot) * hrLength;
float hrY = (float) -Math.cos(hrRot) * hrLength;
canvas.drawLine(centerX, centerY, centerX + hrX, centerY + hrY,
mHourPaint);*/
}
@Override
public void onVisibilityChanged(boolean visible) {
/* the watch face became visible or invisible */
super.onVisibilityChanged(visible);
if (visible) {
//registerReceiver();
// Update time zone in case it changed while we weren't visible.
mTime.clear(TimeZone.getDefault().getID());
mTime.setToNow();
} else {
//unregisterReceiver();
}
// Whether the timer should be running depends on whether we're visible and
// whether we're in ambient mode), so we may need to start or stop the timer
updateTimer();
}
/*private void registerReceiver() {
if (mRegisteredTimeZoneReceiver) {
return;
}
mRegisteredTimeZoneReceiver = true;
IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
ZCycleWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);
}
private void unregisterReceiver() {
if (!mRegisteredTimeZoneReceiver) {
return;
}
mRegisteredTimeZoneReceiver = false;
ZCycleWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);
}*/
}
}
Most of it doesn't do much yet, I just want to test my drawing mechanics
Manifest files: Manifest file for wear:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.rfsdev.zarkopafilis.zcycle">
<uses-feature android:name="android.hardware.type.watch" />
<application android:allowBackup="true" android:label="@string/app_name"
android:icon="@drawable/ic_launcher" android:theme="@android:style/Theme.DeviceDefault">
</application>
<uses-permission
android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission
android:name="android.permission.WAKE_LOCK" />
</manifest>
Manifest file for mobile/phone:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.rfsdev.zarkopafilis.zcycle">
<application android:allowBackup="true" android:label="@string/app_name"
android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme">
<service
android:name=".ZCycleWatchFaceService"
android:label="@string/analog_name"
android:allowEmbedded="true"
android:taskAffinity=""
android:permission="android.permission.BIND_WALLPAPER" >
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category
android:name=
"com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
</service>
</application>
<uses-permission
android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission
android:name="android.permission.WAKE_LOCK" />
</manifest>
I don't know how to test run this thing. The message says 'No activity found' , but im following the tutorial properly. I have already made android applications and this made me confused.
(I do not want tips and stuff for my drawing code , I just want to know what do I need to do in order to run this)
Edit : I don't want to start the application from 'Start...'
Please remember, that you are not making Android application with Activity, that you can start, but making Android application just with Service. In your case - you should just use option - deploy apk, without starting any Activity