Android Open Source - 24hAnalogWidget Wear Face






From Project

Back to project page 24hAnalogWidget.

License

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.

Java Source Code

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();
            }
        }
    }
}




Java Source Code List

info.staticfree.android.twentyfourhour.Analog24HClock.java
info.staticfree.android.twentyfourhour.AnalogClockApplication.java
info.staticfree.android.twentyfourhour.ClockUtil.java
info.staticfree.android.twentyfourhour.TwentyFourHourClockWidget3x.java
info.staticfree.android.twentyfourhour.TwentyFourHourClockWidgetResizable.java
info.staticfree.android.twentyfourhour.TwentyFourHourClockWidget.java
info.staticfree.android.twentyfourhour.WearFace.java
info.staticfree.android.twentyfourhour.WidgetDemo.java
info.staticfree.android.twentyfourhour.overlay.DateOverlay.java
info.staticfree.android.twentyfourhour.overlay.DebugOverlay.java
info.staticfree.android.twentyfourhour.overlay.DialOverlay.java
info.staticfree.android.twentyfourhour.overlay.HandsOverlay.java
info.staticfree.android.twentyfourhour.overlay.SunPositionOverlay.java
twentyfourhour.WearFaceDemoActivity.java