Back to project page 24hAnalogWidget.
The source code is released under:
GNU General Public License
If you think the Android project 24hAnalogWidget listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package info.staticfree.android.twentyfourhour; //w ww .java2 s . c o m import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Canvas; import android.graphics.Rect; import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.support.wearable.watchface.CanvasWatchFaceService; import android.support.wearable.watchface.WatchFaceStyle; import android.util.Log; import android.view.Gravity; import android.view.SurfaceHolder; import android.view.WindowInsets; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.google.android.gms.wearable.Wearable; import java.util.TimeZone; import info.staticfree.android.twentyfourhour.overlay.DateOverlay; import info.staticfree.android.twentyfourhour.overlay.HandsOverlay; import info.staticfree.android.twentyfourhour.overlay.SunPositionOverlay; import info.staticfree.android.twentyfourhour.wear.R; public class WearFace extends CanvasWatchFaceService { /** * This is scaled based on the background design. */ public static final float SUN_POSITION_OVERLAY_SCALE = 0.61345f; @Override public Engine onCreateEngine() { return new Engine(); } private class Engine extends CanvasWatchFaceService.Engine { private static final int MSG_UPDATE_TIME = 100; private static final long INTERACTIVE_UPDATE_RATE_MS = 60 * 1000; private final Analog24HClock mClock = new Analog24HClock(WearFace.this); private boolean mRegisteredTimeZoneReceiver; private boolean mViewSizeInvalid = true; private final SunPositionOverlay mSunPositionOverlay = new SunPositionOverlay(WearFace.this); private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(final Bundle bundle) { setLocation(LocationServices.FusedLocationApi .getLastLocation(mGoogleApiClient)); requestLocationUpdate(); } @Override public void onConnectionSuspended(final int i) { } }; private final LocationListener mLocationCallback = new LocationListener() { @Override public void onLocationChanged(final Location location) { setLocation(location); } }; private boolean mIsRound; private void setLocation(@Nullable final Location location) { mSunPositionOverlay.setLocation(location); invalidate(); } private final GoogleApiClient.OnConnectionFailedListener mConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(final ConnectionResult connectionResult) { Log.d("WearFace", "Error connecting to Google Play Services"); } }; @Nullable private final GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(WearFace.this).addApi(LocationServices.API) .addApi(Wearable.API).addConnectionCallbacks(mConnectionCallbacks) .addOnConnectionFailedListener(mConnectionFailedListener).build(); final Handler mUpdateTimeHandler = new Handler() { @Override public void handleMessage(final Message message) { switch (message.what) { case MSG_UPDATE_TIME: invalidate(); if (shouldTimerBeRunning()) { final long timeMs = System.currentTimeMillis(); final 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(final Context context, final Intent intent) { if (intent.hasExtra("time-zone")) { mClock.setTimezone(TimeZone.getTimeZone(intent.getStringExtra("time-zone"))); } } }; private void updateTimer() { mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME); if (shouldTimerBeRunning()) { mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME); } } private boolean shouldTimerBeRunning() { return isVisible() && !isInAmbientMode(); } private void initializeClock() { mClock.clearDialOverlays(); mSunPositionOverlay.setScale(SUN_POSITION_OVERLAY_SCALE); mSunPositionOverlay.setShadeAlpha(60); mClock.addDialOverlay(mSunPositionOverlay); final DateOverlay dateOverlay = new DateOverlay(0.1875f, -0.1875f, 0.0625f); mClock.addDialOverlay(dateOverlay); } @Override public void onCreate(final SurfaceHolder holder) { super.onCreate(holder); initializeClock(); /* configure the system UI */ setWatchFaceStyle(new WatchFaceStyle.Builder(WearFace.this) .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT) .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE) .setShowSystemUiTime(false).setHotwordIndicatorGravity(Gravity.CENTER) .setStatusBarGravity(Gravity.CENTER).setViewProtection( WatchFaceStyle.PROTECT_STATUS_BAR | WatchFaceStyle.PROTECT_HOTWORD_INDICATOR) .setPeekOpacityMode(WatchFaceStyle.PEEK_OPACITY_MODE_TRANSLUCENT).build()); setTouchEventsEnabled(false); } @Override public void onApplyWindowInsets(final WindowInsets insets) { super.onApplyWindowInsets(insets); mIsRound = insets.isRound(); if (mIsRound) { mClock.setHandsOverlay( new HandsOverlay(getApplicationContext(), R.drawable.round_hour_hand, R.drawable.round_minute_hand)); mClock.setFace(R.drawable.round_clock_face); } else { mClock.setHandsOverlay( new HandsOverlay(getApplicationContext(), R.drawable.square_hour_hand, R.drawable.square_minute_hand)); mClock.setFace(R.drawable.square_clock_face); } invalidate(); } @Override public void onPropertiesChanged(final Bundle properties) { super.onPropertiesChanged(properties); /* get device features (burn-in, low-bit ambient) */ } @Override public void onTimeTick() { super.onTimeTick(); invalidate(); } @Override public void onAmbientModeChanged(final boolean inAmbientMode) { super.onAmbientModeChanged(inAmbientMode); if (mIsRound) { mClock.setFace(inAmbientMode ? R.drawable.round_clock_face_ambient : R.drawable.round_clock_face); } else { mClock.setFace(inAmbientMode ? R.drawable.square_clock_face_ambient : R.drawable.square_clock_face); } invalidate(); updateTimer(); } @Override public void onDraw(final Canvas canvas, final Rect bounds) { super.onDraw(canvas, bounds); mClock.setTime(System.currentTimeMillis()); if (mViewSizeInvalid) { mClock.measure(bounds.width(), bounds.height()); mClock.layout(bounds.left, bounds.top, bounds.right, bounds.bottom); mViewSizeInvalid = false; } mClock.draw(canvas); } @Override public void onVisibilityChanged(final boolean visible) { super.onVisibilityChanged(visible); if (visible) { registerTimeZoneReceiver(); // Update time zone in case it changed while we weren't visible. mClock.setTimezone(TimeZone.getDefault()); connectLocationService(); } else { unregisterTimeZoneReceiver(); disconnectLocationService(); } // 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 registerTimeZoneReceiver() { if (mRegisteredTimeZoneReceiver) { return; } mRegisteredTimeZoneReceiver = true; final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); registerReceiver(mTimeZoneReceiver, filter); } private void unregisterTimeZoneReceiver() { if (!mRegisteredTimeZoneReceiver) { return; } mRegisteredTimeZoneReceiver = false; unregisterReceiver(mTimeZoneReceiver); } private void connectLocationService() { if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } private void requestLocationUpdate() { final LocationRequest locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_NO_POWER) .setNumUpdates(1); LocationServices.FusedLocationApi .requestLocationUpdates(mGoogleApiClient, locationRequest, mLocationCallback); } private void disconnectLocationService() { if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi .removeLocationUpdates(mGoogleApiClient, mLocationCallback); mGoogleApiClient.disconnect(); } } } }