Update WatchFace project to remove old watch faces that
are no longer good practice and change structure to make sample clearer.
Bug: 32214858
Change-Id: I8f6c2c0e56208e1c557cd9e185ddebd443bb0dab
diff --git a/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml b/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
index 09b914e..5ac66de 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2014 The Android Open Source Project
+ Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -57,7 +57,7 @@
android:required="false"/>
<service
- android:name=".AnalogWatchFaceService"
+ android:name=".watchfaces.AnalogWatchFaceService"
android:label="@string/analog_name"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
@@ -80,27 +80,7 @@
</intent-filter>
</service>
<service
- android:name=".SweepWatchFaceService"
- android:label="@string/sweep_name"
- android:permission="android.permission.BIND_WALLPAPER">
- <meta-data
- android:name="android.service.wallpaper"
- android:resource="@xml/watch_face"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.preview"
- android:resource="@drawable/preview_analog"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.preview_circular"
- android:resource="@drawable/preview_analog_circular"/>
-
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService"/>
-
- <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE"/>
- </intent-filter>
- </service>
- <service
- android:name=".OpenGLWatchFaceService"
+ android:name=".watchfaces.OpenGLWatchFaceService"
android:label="@string/opengl_name"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
@@ -123,30 +103,7 @@
</intent-filter>
</service>
<service
- android:name=".CardBoundsWatchFaceService"
- android:label="@string/card_bounds_name"
- android:permission="android.permission.BIND_WALLPAPER">
- <meta-data
- android:name="android.service.wallpaper"
- android:resource="@xml/watch_face"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.preview"
- android:resource="@drawable/preview_card_bounds"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.preview_circular"
- android:resource="@drawable/preview_card_bounds_circular"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.companionConfigurationAction"
- android:value="com.example.android.wearable.watchface.CONFIG_CARD_BOUNDS"/>
-
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService"/>
-
- <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE"/>
- </intent-filter>
- </service>
- <service
- android:name=".ComplicationSimpleWatchFaceService"
+ android:name=".watchfaces.ComplicationSimpleWatchFaceService"
android:enabled="true"
android:label="@string/complication_simple"
android:permission="android.permission.BIND_WALLPAPER">
@@ -172,7 +129,7 @@
<activity android:name="android.support.wearable.complications.ComplicationHelperActivity"/>
<activity
- android:name=".ComplicationSimpleConfigActivity"
+ android:name=".config.ComplicationSimpleConfigActivity"
android:label="@string/complication_simple">
<intent-filter>
<action android:name="com.example.android.wearable.watchface.CONFIG_COMPLICATION_SIMPLE"/>
@@ -183,7 +140,7 @@
</activity>
<service
- android:name=".InteractiveWatchFaceService"
+ android:name=".watchfaces.InteractiveWatchFaceService"
android:label="@string/interactive_name"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
@@ -202,8 +159,9 @@
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE"/>
</intent-filter>
</service>
+
<service
- android:name=".DigitalWatchFaceService"
+ android:name=".watchfaces.DigitalWatchFaceService"
android:label="@string/digital_name"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
@@ -236,7 +194,7 @@
-->
<activity
- android:name=".DigitalWatchFaceWearableConfigActivity"
+ android:name=".config.DigitalWatchFaceWearableConfigActivity"
android:label="@string/digital_config_name">
<intent-filter>
<action android:name="com.example.android.wearable.watchface.CONFIG_DIGITAL"/>
@@ -246,27 +204,7 @@
</intent-filter>
</activity>
- <service
- android:name=".CalendarWatchFaceService"
- android:label="@string/calendar_name"
- android:permission="android.permission.BIND_WALLPAPER">
- <meta-data
- android:name="android.service.wallpaper"
- android:resource="@xml/watch_face"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.preview"
- android:resource="@drawable/preview_calendar"/>
- <meta-data
- android:name="com.google.android.wearable.watchface.preview_circular"
- android:resource="@drawable/preview_calendar_circular"/>
-
- <intent-filter>
- <action android:name="android.service.wallpaper.WallpaperService"/>
-
- <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE"/>
- </intent-filter>
- </service>
- <service android:name=".DigitalWatchFaceConfigListenerService">
+ <service android:name=".config.DigitalWatchFaceConfigListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
@@ -277,7 +215,7 @@
</intent-filter>
</service>
<service
- android:name=".FitDistanceWatchFaceService"
+ android:name=".watchfaces.FitDistanceWatchFaceService"
android:label="@string/fit_distance_name"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
@@ -300,7 +238,7 @@
</intent-filter>
</service>
<service
- android:name=".FitStepsWatchFaceService"
+ android:name=".watchfaces.FitStepsWatchFaceService"
android:label="@string/fit_steps_name"
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
@@ -320,13 +258,8 @@
</intent-filter>
</service>
- <activity
- android:name=".CalendarWatchFacePermissionActivity"
- android:label="@string/title_activity_calendar_watch_face_permission">
- </activity>
-
<service
- android:name=".provider.RandomNumberProviderService"
+ android:name=".providers.RandomNumberProviderService"
android:icon="@drawable/ic_launcher"
android:label="@string/complications_provider_random_number"
android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
@@ -355,7 +288,7 @@
android:value="600"/>
</service>
<service
- android:name=".provider.UpdateComplicationDataService"
+ android:name=".providers.UpdateComplicationDataService"
android:exported="false">
</service>
</application>
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFacePermissionActivity.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFacePermissionActivity.java
deleted file mode 100644
index 7effd33..0000000
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFacePermissionActivity.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.example.android.wearable.watchface;
-
-import android.Manifest;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.ActivityCompat;
-import android.support.wearable.activity.WearableActivity;
-import android.util.Log;
-import android.view.View;
-
-/**
- * Simple Activity for displaying Calendar Permission Rationale to user.
- */
-public class CalendarWatchFacePermissionActivity extends WearableActivity {
-
- private static final String TAG = "PermissionActivity";
-
- /* Id to identify permission request for calendar. */
- private static final int PERMISSION_REQUEST_READ_CALENDAR = 1;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_calendar_watch_face_permission);
- setAmbientEnabled();
- }
-
- public void onClickEnablePermission(View view) {
- Log.d(TAG, "onClickEnablePermission()");
-
- // On 23+ (M+) devices, GPS permission not granted. Request permission.
- ActivityCompat.requestPermissions(
- this,
- new String[]{Manifest.permission.READ_CALENDAR},
- PERMISSION_REQUEST_READ_CALENDAR);
-
- }
-
- /*
- * Callback received when a permissions request has been completed.
- */
- @Override
- public void onRequestPermissionsResult(
- int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
-
- Log.d(TAG, "onRequestPermissionsResult()");
-
- if (requestCode == PERMISSION_REQUEST_READ_CALENDAR) {
- if ((grantResults.length == 1)
- && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
- finish();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java
deleted file mode 100644
index 98a251c..0000000
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CalendarWatchFaceService.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.wearable.watchface;
-
-import android.Manifest;
-import android.content.BroadcastReceiver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.support.v4.app.ActivityCompat;
-import android.support.wearable.provider.WearableCalendarContract;
-import android.support.wearable.watchface.CanvasWatchFaceService;
-import android.support.wearable.watchface.WatchFaceService;
-import android.support.wearable.watchface.WatchFaceStyle;
-import android.text.DynamicLayout;
-import android.text.Editable;
-import android.text.Html;
-import android.text.Layout;
-import android.text.SpannableStringBuilder;
-import android.text.TextPaint;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-/**
- * Proof of concept sample watch face that demonstrates how a watch face can load calendar data.
- */
-public class CalendarWatchFaceService extends CanvasWatchFaceService {
- private static final String TAG = "CalendarWatchFace";
-
- @Override
- public Engine onCreateEngine() {
- return new Engine();
- }
-
- private class Engine extends CanvasWatchFaceService.Engine {
-
- static final int BACKGROUND_COLOR = Color.BLACK;
- static final int FOREGROUND_COLOR = Color.WHITE;
- static final int TEXT_SIZE = 25;
- static final int MSG_LOAD_MEETINGS = 0;
-
- /** Editable string containing the text to draw with the number of meetings in bold. */
- final Editable mEditable = new SpannableStringBuilder();
-
- /** Width specified when {@link #mLayout} was created. */
- int mLayoutWidth;
-
- /** Layout to wrap {@link #mEditable} onto multiple lines. */
- DynamicLayout mLayout;
-
- /** Paint used to draw text. */
- final TextPaint mTextPaint = new TextPaint();
-
- int mNumMeetings;
- private boolean mCalendarPermissionApproved;
- private String mCalendarNotApprovedMessage;
-
- private AsyncTask<Void, Void, Integer> mLoadMeetingsTask;
-
- private boolean mIsReceiverRegistered;
-
- /** Handler to load the meetings once a minute in interactive mode. */
- final Handler mLoadMeetingsHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_LOAD_MEETINGS:
-
- cancelLoadMeetingTask();
-
- // Loads meetings.
- if (mCalendarPermissionApproved) {
- mLoadMeetingsTask = new LoadMeetingsTask();
- mLoadMeetingsTask.execute();
- }
- break;
- }
- }
- };
-
- private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_PROVIDER_CHANGED.equals(intent.getAction())
- && WearableCalendarContract.CONTENT_URI.equals(intent.getData())) {
- mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
- }
- }
- };
-
- @Override
- public void onCreate(SurfaceHolder holder) {
- super.onCreate(holder);
- Log.d(TAG, "onCreate");
-
- mCalendarNotApprovedMessage =
- getResources().getString(R.string.calendar_permission_not_approved);
-
- /* Accepts tap events to allow permission changes by user. */
- setWatchFaceStyle(new WatchFaceStyle.Builder(CalendarWatchFaceService.this)
- .setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE)
- .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
- .setShowSystemUiTime(false)
- .setAcceptsTapEvents(true)
- .build());
-
- mTextPaint.setColor(FOREGROUND_COLOR);
- mTextPaint.setTextSize(TEXT_SIZE);
-
- // Enables app to handle 23+ (M+) style permissions.
- mCalendarPermissionApproved =
- ActivityCompat.checkSelfPermission(
- getApplicationContext(),
- Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED;
-
- if (mCalendarPermissionApproved) {
- mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
- }
- }
-
- @Override
- public void onDestroy() {
- mLoadMeetingsHandler.removeMessages(MSG_LOAD_MEETINGS);
- super.onDestroy();
- }
-
- /*
- * Captures tap event (and tap type) and increments correct tap type total.
- */
- @Override
- public void onTapCommand(int tapType, int x, int y, long eventTime) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Tap Command: " + tapType);
- }
-
- // Ignore lint error (fixed in wearable support library 1.4)
- if (tapType == WatchFaceService.TAP_TYPE_TAP && !mCalendarPermissionApproved) {
- Intent permissionIntent = new Intent(
- getApplicationContext(),
- CalendarWatchFacePermissionActivity.class);
- permissionIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(permissionIntent);
- }
- }
-
- @Override
- public void onDraw(Canvas canvas, Rect bounds) {
- // Create or update mLayout if necessary.
- if (mLayout == null || mLayoutWidth != bounds.width()) {
- mLayoutWidth = bounds.width();
- mLayout = new DynamicLayout(mEditable, mTextPaint, mLayoutWidth,
- Layout.Alignment.ALIGN_NORMAL, 1 /* spacingMult */, 0 /* spacingAdd */,
- false /* includePad */);
- }
-
- // Update the contents of mEditable.
- mEditable.clear();
-
- if (mCalendarPermissionApproved) {
- mEditable.append(Html.fromHtml(getResources().getQuantityString(
- R.plurals.calendar_meetings, mNumMeetings, mNumMeetings)));
- } else {
- mEditable.append(Html.fromHtml(mCalendarNotApprovedMessage));
- }
-
- // Draw the text on a solid background.
- canvas.drawColor(BACKGROUND_COLOR);
- mLayout.draw(canvas);
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- Log.d(TAG, "onVisibilityChanged()");
- super.onVisibilityChanged(visible);
- if (visible) {
-
- // Enables app to handle 23+ (M+) style permissions.
- mCalendarPermissionApproved = ActivityCompat.checkSelfPermission(
- getApplicationContext(),
- Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED;
-
- if (mCalendarPermissionApproved) {
- IntentFilter filter = new IntentFilter(Intent.ACTION_PROVIDER_CHANGED);
- filter.addDataScheme("content");
- filter.addDataAuthority(WearableCalendarContract.AUTHORITY, null);
- registerReceiver(mBroadcastReceiver, filter);
- mIsReceiverRegistered = true;
-
- mLoadMeetingsHandler.sendEmptyMessage(MSG_LOAD_MEETINGS);
- }
- } else {
- if (mIsReceiverRegistered) {
- unregisterReceiver(mBroadcastReceiver);
- mIsReceiverRegistered = false;
- }
- mLoadMeetingsHandler.removeMessages(MSG_LOAD_MEETINGS);
- }
- }
-
- private void onMeetingsLoaded(Integer result) {
- if (result != null) {
- mNumMeetings = result;
- invalidate();
- }
- }
-
- private void cancelLoadMeetingTask() {
- if (mLoadMeetingsTask != null) {
- mLoadMeetingsTask.cancel(true);
- }
- }
-
- /**
- * Asynchronous task to load the meetings from the content provider and report the number of
- * meetings back via {@link #onMeetingsLoaded}.
- */
- private class LoadMeetingsTask extends AsyncTask<Void, Void, Integer> {
- private PowerManager.WakeLock mWakeLock;
-
- @Override
- protected Integer doInBackground(Void... voids) {
- PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK, "CalendarWatchFaceWakeLock");
- mWakeLock.acquire();
-
- long begin = System.currentTimeMillis();
- Uri.Builder builder =
- WearableCalendarContract.Instances.CONTENT_URI.buildUpon();
- ContentUris.appendId(builder, begin);
- ContentUris.appendId(builder, begin + DateUtils.DAY_IN_MILLIS);
- final Cursor cursor = getContentResolver().query(builder.build(),
- null, null, null, null);
- int numMeetings = cursor.getCount();
-
- Log.d(TAG, "Num meetings: " + numMeetings);
-
- return numMeetings;
- }
-
- @Override
- protected void onPostExecute(Integer result) {
- releaseWakeLock();
- onMeetingsLoaded(result);
- }
-
- @Override
- protected void onCancelled() {
- releaseWakeLock();
- }
-
- private void releaseWakeLock() {
- if (mWakeLock != null) {
- mWakeLock.release();
- mWakeLock = null;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CardBoundsWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CardBoundsWatchFaceService.java
deleted file mode 100644
index 359d7af..0000000
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/CardBoundsWatchFaceService.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.wearable.watchface;
-
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.support.wearable.watchface.CanvasWatchFaceService;
-import android.support.wearable.watchface.WatchFaceStyle;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-/**
- * Proof of concept sample watch face that demonstrates how a watch face can detect where the peek
- * card is. This watch face draws a border around the area where the peeking card is.
- */
-public class CardBoundsWatchFaceService extends CanvasWatchFaceService {
-
- private static final String TAG = "CardBoundsWatchFace";
-
- @Override
- public Engine onCreateEngine() {
- return new Engine();
- }
-
- private class Engine extends CanvasWatchFaceService.Engine {
-
- static final int BORDER_WIDTH_PX = 5;
-
- final Rect mCardBounds = new Rect();
- final Paint mPaint = new Paint();
-
- @Override
- public void onCreate(SurfaceHolder holder) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onCreate");
- }
- super.onCreate(holder);
- setWatchFaceStyle(new WatchFaceStyle.Builder(CardBoundsWatchFaceService.this)
- .setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE)
- .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
- .setShowSystemUiTime(true)
- .setPeekOpacityMode(WatchFaceStyle.PEEK_OPACITY_MODE_TRANSLUCENT)
- .build());
- }
-
- @Override
- public void onAmbientModeChanged(boolean inAmbientMode) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode);
- }
- super.onAmbientModeChanged(inAmbientMode);
- invalidate();
- }
-
- @Override
- public void onPeekCardPositionUpdate(Rect bounds) {
- super.onPeekCardPositionUpdate(bounds);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onPeekCardPositionUpdate: " + bounds);
- }
- super.onPeekCardPositionUpdate(bounds);
- if (!bounds.equals(mCardBounds)) {
- mCardBounds.set(bounds);
- invalidate();
- }
- }
-
- @Override
- public void onDraw(Canvas canvas, Rect bounds) {
- // Clear screen.
- canvas.drawColor(isInAmbientMode() ? Color.BLACK : Color.BLUE);
-
- // Draw border around card in interactive mode.
- if (!isInAmbientMode()) {
- mPaint.setColor(Color.MAGENTA);
- canvas.drawRect(mCardBounds.left - BORDER_WIDTH_PX,
- mCardBounds.top - BORDER_WIDTH_PX,
- mCardBounds.right + BORDER_WIDTH_PX,
- mCardBounds.bottom + BORDER_WIDTH_PX, mPaint);
- }
-
- // Fill area under card.
- mPaint.setColor(isInAmbientMode() ? Color.RED : Color.GREEN);
- canvas.drawRect(mCardBounds, mPaint);
- }
- }
-}
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java
deleted file mode 100644
index a94097f..0000000
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.wearable.watchface;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.support.v7.graphics.Palette;
-import android.support.wearable.watchface.CanvasWatchFaceService;
-import android.support.wearable.watchface.WatchFaceService;
-import android.support.wearable.watchface.WatchFaceStyle;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import java.util.Calendar;
-import java.util.TimeZone;
-
-/**
- * Sample analog watch face with a sweep second hand. In ambient mode, the second hand isn't shown.
- * On devices with low-bit ambient mode, the hands are drawn without anti-aliasing in ambient mode.
- * The watch face is drawn with less contrast in mute mode.
- *
- * {@link AnalogWatchFaceService} is similar but has a ticking second hand.
- */
-public class SweepWatchFaceService extends CanvasWatchFaceService {
-
- private static final String TAG = "SweepWatchFaceService";
-
- @Override
- public Engine onCreateEngine() {
- return new Engine();
- }
-
- private class Engine extends CanvasWatchFaceService.Engine {
-
- private static final float HOUR_STROKE_WIDTH = 5f;
- private static final float MINUTE_STROKE_WIDTH = 3f;
- private static final float SECOND_TICK_STROKE_WIDTH = 2f;
-
- private static final float CENTER_GAP_AND_CIRCLE_RADIUS = 4f;
-
- private static final int SHADOW_RADIUS = 6;
-
- private Calendar mCalendar;
- private boolean mRegisteredTimeZoneReceiver = false;
- private boolean mMuteMode;
-
- private float mCenterX;
- private float mCenterY;
-
- private float mSecondHandLength;
- private float mMinuteHandLength;
- private float mHourHandLength;
-
- /* Colors for all hands (hour, minute, seconds, ticks) based on photo loaded. */
- private int mWatchHandColor;
- private int mWatchHandHighlightColor;
- private int mWatchHandShadowColor;
-
- private Paint mHourPaint;
- private Paint mMinutePaint;
- private Paint mSecondPaint;
- private Paint mTickAndCirclePaint;
-
- private Paint mBackgroundPaint;
- private Bitmap mBackgroundBitmap;
- private Bitmap mGrayBackgroundBitmap;
-
- private boolean mAmbient;
- private boolean mLowBitAmbient;
- private boolean mBurnInProtection;
-
- private Rect mPeekCardBounds = new Rect();
-
- private final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mCalendar.setTimeZone(TimeZone.getDefault());
- invalidate();
- }
- };
-
- @Override
- public void onCreate(SurfaceHolder holder) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onCreate");
- }
- super.onCreate(holder);
-
- setWatchFaceStyle(new WatchFaceStyle.Builder(SweepWatchFaceService.this)
- .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
- .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
- .setShowSystemUiTime(false)
- .build());
-
- mBackgroundPaint = new Paint();
- mBackgroundPaint.setColor(Color.BLACK);
- mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
-
- /* Set defaults for colors */
- mWatchHandColor = Color.WHITE;
- mWatchHandHighlightColor = Color.RED;
- mWatchHandShadowColor = Color.BLACK;
-
- mHourPaint = new Paint();
- mHourPaint.setColor(mWatchHandColor);
- mHourPaint.setStrokeWidth(HOUR_STROKE_WIDTH);
- mHourPaint.setAntiAlias(true);
- mHourPaint.setStrokeCap(Paint.Cap.ROUND);
- mHourPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
-
- mMinutePaint = new Paint();
- mMinutePaint.setColor(mWatchHandColor);
- mMinutePaint.setStrokeWidth(MINUTE_STROKE_WIDTH);
- mMinutePaint.setAntiAlias(true);
- mMinutePaint.setStrokeCap(Paint.Cap.ROUND);
- mMinutePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
-
- mSecondPaint = new Paint();
- mSecondPaint.setColor(mWatchHandHighlightColor);
- mSecondPaint.setStrokeWidth(SECOND_TICK_STROKE_WIDTH);
- mSecondPaint.setAntiAlias(true);
- mSecondPaint.setStrokeCap(Paint.Cap.ROUND);
- mSecondPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
-
- mTickAndCirclePaint = new Paint();
- mTickAndCirclePaint.setColor(mWatchHandColor);
- mTickAndCirclePaint.setStrokeWidth(SECOND_TICK_STROKE_WIDTH);
- mTickAndCirclePaint.setAntiAlias(true);
- mTickAndCirclePaint.setStyle(Paint.Style.STROKE);
- mTickAndCirclePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
-
- /* Extract colors from background image to improve watchface style. */
- Palette.generateAsync(
- mBackgroundBitmap,
- new Palette.PaletteAsyncListener() {
- @Override
- public void onGenerated(Palette palette) {
- if (palette != null) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Palette: " + palette);
- }
-
- mWatchHandHighlightColor = palette.getVibrantColor(Color.RED);
- mWatchHandColor = palette.getLightVibrantColor(Color.WHITE);
- mWatchHandShadowColor = palette.getDarkMutedColor(Color.BLACK);
- updateWatchHandStyle();
- }
- }
- });
-
- mCalendar = Calendar.getInstance();
- }
-
- @Override
- public void onPropertiesChanged(Bundle properties) {
- super.onPropertiesChanged(properties);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onPropertiesChanged: low-bit ambient = " + mLowBitAmbient);
- }
-
- mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
- mBurnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION, false);
- }
-
- @Override
- public void onTimeTick() {
- super.onTimeTick();
- invalidate();
- }
-
- @Override
- public void onAmbientModeChanged(boolean inAmbientMode) {
- super.onAmbientModeChanged(inAmbientMode);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode);
- }
- mAmbient = inAmbientMode;
-
- updateWatchHandStyle();
-
- invalidate();
- }
-
- private void updateWatchHandStyle(){
- if (mAmbient){
- mHourPaint.setColor(Color.WHITE);
- mMinutePaint.setColor(Color.WHITE);
- mSecondPaint.setColor(Color.WHITE);
- mTickAndCirclePaint.setColor(Color.WHITE);
-
- mHourPaint.setAntiAlias(false);
- mMinutePaint.setAntiAlias(false);
- mSecondPaint.setAntiAlias(false);
- mTickAndCirclePaint.setAntiAlias(false);
-
- mHourPaint.clearShadowLayer();
- mMinutePaint.clearShadowLayer();
- mSecondPaint.clearShadowLayer();
- mTickAndCirclePaint.clearShadowLayer();
-
- } else {
- mHourPaint.setColor(mWatchHandColor);
- mMinutePaint.setColor(mWatchHandColor);
- mSecondPaint.setColor(mWatchHandHighlightColor);
- mTickAndCirclePaint.setColor(mWatchHandColor);
-
- mHourPaint.setAntiAlias(true);
- mMinutePaint.setAntiAlias(true);
- mSecondPaint.setAntiAlias(true);
- mTickAndCirclePaint.setAntiAlias(true);
-
- mHourPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
- mMinutePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
- mSecondPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
- mTickAndCirclePaint.setShadowLayer(SHADOW_RADIUS, 0, 0, mWatchHandShadowColor);
- }
- }
-
- @Override
- public void onInterruptionFilterChanged(int interruptionFilter) {
- super.onInterruptionFilterChanged(interruptionFilter);
- boolean inMuteMode = (interruptionFilter == WatchFaceService.INTERRUPTION_FILTER_NONE);
-
- /* Dim display in mute mode. */
- if (mMuteMode != inMuteMode) {
- mMuteMode = inMuteMode;
- mHourPaint.setAlpha(inMuteMode ? 100 : 255);
- mMinutePaint.setAlpha(inMuteMode ? 100 : 255);
- mSecondPaint.setAlpha(inMuteMode ? 80 : 255);
- invalidate();
- }
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- super.onSurfaceChanged(holder, format, width, height);
-
- /*
- * Find the coordinates of the center point on the screen, and 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.
- */
- mCenterX = width / 2f;
- mCenterY = height / 2f;
-
- /*
- * Calculate lengths of different hands based on watch screen size.
- */
- mSecondHandLength = (float) (mCenterX * 0.875);
- mMinuteHandLength = (float) (mCenterX * 0.75);
- mHourHandLength = (float) (mCenterX * 0.5);
-
-
- /* Scale loaded background image (more efficient) if surface dimensions change. */
- float scale = ((float) width) / (float) mBackgroundBitmap.getWidth();
-
- mBackgroundBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
- (int) (mBackgroundBitmap.getWidth() * scale),
- (int) (mBackgroundBitmap.getHeight() * scale), true);
-
- /*
- * Create a gray version of the image only if it will look nice on the device in
- * ambient mode. That means we don't want devices that support burn-in
- * protection (slight movements in pixels, not great for images going all the way to
- * edges) and low ambient mode (degrades image quality).
- *
- * Also, if your watch face will know about all images ahead of time (users aren't
- * selecting their own photos for the watch face), it will be more
- * efficient to create a black/white version (png, etc.) and load that when you need it.
- */
- if (!mBurnInProtection && !mLowBitAmbient) {
- initGrayBackgroundBitmap();
- }
- }
-
- private void initGrayBackgroundBitmap() {
- mGrayBackgroundBitmap = Bitmap.createBitmap(
- mBackgroundBitmap.getWidth(),
- mBackgroundBitmap.getHeight(),
- Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(mGrayBackgroundBitmap);
- Paint grayPaint = new Paint();
- ColorMatrix colorMatrix = new ColorMatrix();
- colorMatrix.setSaturation(0);
- ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
- grayPaint.setColorFilter(filter);
- canvas.drawBitmap(mBackgroundBitmap, 0, 0, grayPaint);
- }
-
- @Override
- public void onDraw(Canvas canvas, Rect bounds) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "onDraw");
- }
- long now = System.currentTimeMillis();
- mCalendar.setTimeInMillis(now);
-
- if (mAmbient && (mLowBitAmbient || mBurnInProtection)) {
- canvas.drawColor(Color.BLACK);
- } else if (mAmbient) {
- canvas.drawBitmap(mGrayBackgroundBitmap, 0, 0, mBackgroundPaint);
- } else {
- canvas.drawBitmap(mBackgroundBitmap, 0, 0, mBackgroundPaint);
- }
-
- /*
- * Draw ticks. Usually you will want to bake this directly into the photo, but in
- * cases where you want to allow users to select their own photos, this dynamically
- * creates them on top of the photo.
- */
- float innerTickRadius = mCenterX - 10;
- float outerTickRadius = mCenterX;
- for (int tickIndex = 0; tickIndex < 12; tickIndex++) {
- float tickRot = (float) (tickIndex * Math.PI * 2 / 12);
- float innerX = (float) Math.sin(tickRot) * innerTickRadius;
- float innerY = (float) -Math.cos(tickRot) * innerTickRadius;
- float outerX = (float) Math.sin(tickRot) * outerTickRadius;
- float outerY = (float) -Math.cos(tickRot) * outerTickRadius;
- canvas.drawLine(mCenterX + innerX, mCenterY + innerY,
- mCenterX + outerX, mCenterY + outerY, mTickAndCirclePaint);
- }
-
- /*
- * These calculations reflect the rotation in degrees per unit of time, e.g.,
- * 360 / 60 = 6 and 360 / 12 = 30.
- */
- final float seconds =
- (mCalendar.get(Calendar.SECOND) + mCalendar.get(Calendar.MILLISECOND) / 1000f);
- final float secondsRotation = seconds * 6f;
-
- final float minutesRotation = mCalendar.get(Calendar.MINUTE) * 6f;
-
- final float hourHandOffset = mCalendar.get(Calendar.MINUTE) / 2f;
- final float hoursRotation = (mCalendar.get(Calendar.HOUR) * 30) + hourHandOffset;
-
- /*
- * Save the canvas state before we can begin to rotate it.
- */
- canvas.save();
-
- canvas.rotate(hoursRotation, mCenterX, mCenterY);
- canvas.drawLine(
- mCenterX,
- mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS,
- mCenterX,
- mCenterY - mHourHandLength,
- mHourPaint);
-
- canvas.rotate(minutesRotation - hoursRotation, mCenterX, mCenterY);
- canvas.drawLine(
- mCenterX,
- mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS,
- mCenterX,
- mCenterY - mMinuteHandLength,
- mMinutePaint);
-
- /*
- * Ensure the "seconds" hand is drawn only when we are in interactive mode.
- * Otherwise, we only update the watch face once a minute.
- */
- if (!mAmbient) {
- canvas.rotate(secondsRotation - minutesRotation, mCenterX, mCenterY);
- canvas.drawLine(
- mCenterX,
- mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS,
- mCenterX,
- mCenterY - mSecondHandLength,
- mSecondPaint);
-
- }
- canvas.drawCircle(
- mCenterX,
- mCenterY,
- CENTER_GAP_AND_CIRCLE_RADIUS,
- mTickAndCirclePaint);
-
- /* Restore the canvas' original orientation. */
- canvas.restore();
-
- /* Draw rectangle behind peek card in ambient mode to improve readability. */
- if (mAmbient) {
- canvas.drawRect(mPeekCardBounds, mBackgroundPaint);
- }
-
- /* Draw every frame as long as we're visible and in interactive mode. */
- if ((isVisible()) && (!mAmbient)) {
- invalidate();
- }
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- super.onVisibilityChanged(visible);
-
- if (visible) {
- registerReceiver();
- /* Update time zone in case it changed while we weren't visible. */
- mCalendar.setTimeZone(TimeZone.getDefault());
- invalidate();
- } else {
- unregisterReceiver();
- }
- }
-
- @Override
- public void onPeekCardPositionUpdate(Rect rect) {
- super.onPeekCardPositionUpdate(rect);
- mPeekCardBounds.set(rect);
- }
-
- private void registerReceiver() {
- if (mRegisteredTimeZoneReceiver) {
- return;
- }
- mRegisteredTimeZoneReceiver = true;
- IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
- SweepWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);
- }
-
- private void unregisterReceiver() {
- if (!mRegisteredTimeZoneReceiver) {
- return;
- }
- mRegisteredTimeZoneReceiver = false;
- SweepWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);
- }
- }
-}
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleConfigActivity.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/ComplicationSimpleConfigActivity.java
similarity index 96%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleConfigActivity.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/ComplicationSimpleConfigActivity.java
index 6d4e521..c63333f 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleConfigActivity.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/ComplicationSimpleConfigActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.config;
import android.app.Activity;
import android.content.ComponentName;
@@ -33,6 +33,9 @@
import android.widget.ImageView;
import android.widget.TextView;
+import com.example.android.wearable.watchface.watchfaces.ComplicationSimpleWatchFaceService;
+import com.example.android.wearable.watchface.R;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceConfigListenerService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/DigitalWatchFaceConfigListenerService.java
similarity index 92%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceConfigListenerService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/DigitalWatchFaceConfigListenerService.java
index 8d99de6..617f3b7 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceConfigListenerService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/DigitalWatchFaceConfigListenerService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.config;
import android.os.Bundle;
import android.util.Log;
@@ -26,6 +26,9 @@
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
+import com.example.android.wearable.watchface.watchfaces.DigitalWatchFaceService;
+import com.example.android.wearable.watchface.utils.DigitalWatchFaceUtil;
+
import java.util.concurrent.TimeUnit;
/**
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/DigitalWatchFaceWearableConfigActivity.java
similarity index 97%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/DigitalWatchFaceWearableConfigActivity.java
index 4b309e6..75527f3 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceWearableConfigActivity.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/config/DigitalWatchFaceWearableConfigActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.config;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
@@ -22,13 +22,11 @@
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
-import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.wearable.view.BoxInsetLayout;
import android.support.wearable.view.CircledImageView;
import android.support.wearable.view.WearableListView;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
@@ -40,6 +38,10 @@
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.Wearable;
+import com.example.android.wearable.watchface.watchfaces.DigitalWatchFaceService;
+import com.example.android.wearable.watchface.utils.DigitalWatchFaceUtil;
+import com.example.android.wearable.watchface.R;
+
/**
* The watch-side config activity for {@link DigitalWatchFaceService}, which allows for setting the
* background color.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/RandomNumberProviderService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/providers/RandomNumberProviderService.java
similarity index 77%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/RandomNumberProviderService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/providers/RandomNumberProviderService.java
index 17d03c2..80f565d 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/RandomNumberProviderService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/providers/RandomNumberProviderService.java
@@ -1,4 +1,20 @@
-package com.example.android.wearable.watchface.provider;
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wearable.watchface.providers;
import android.app.PendingIntent;
import android.content.Intent;
@@ -28,7 +44,6 @@
public void onComplicationActivated(
int complicationId, int dataType, ComplicationManager complicationManager) {
Log.d(TAG, "onComplicationActivated(): " + complicationId);
- super.onComplicationActivated(complicationId, dataType, complicationManager);
}
/*
@@ -103,17 +118,27 @@
}
if (complicationData != null) {
+ // In this case, we have the complication id and ask the system to update only that
+ // complication.
+ //
+ // You could also call ProviderUpdateRequester.requestUpdateAll() instead, which
+ // requests that the system call onComplicationUpdate on the specified provider for ALL
+ // active complications using that provider without requiring the id (a bit easier than
+ // tracking complication id throughout app).
complicationManager.updateComplicationData(complicationId, complicationData);
+
+ } else {
+ // If no data is sent, we still need to inform the ComplicationManager, so the update
+ // job can finish and the wake lock isn't held any longer than necessary.
+ complicationManager.noUpdateRequired(complicationId);
}
}
/*
- * Called when the complication has been deactivated. If you are updating the complication
- * manager outside of this class with updates, you will want to update your class to stop.
+ * Called when the complication has been deactivated.
*/
@Override
public void onComplicationDeactivated(int complicationId) {
Log.d(TAG, "onComplicationDeactivated(): " + complicationId);
- super.onComplicationDeactivated(complicationId);
}
}
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/UpdateComplicationDataService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/providers/UpdateComplicationDataService.java
similarity index 74%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/UpdateComplicationDataService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/providers/UpdateComplicationDataService.java
index 203e491..ae04bf5 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/provider/UpdateComplicationDataService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/providers/UpdateComplicationDataService.java
@@ -1,4 +1,20 @@
-package com.example.android.wearable.watchface.provider;
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wearable.watchface.providers;
import android.app.IntentService;
import android.content.ComponentName;
@@ -12,6 +28,8 @@
*/
public class UpdateComplicationDataService extends IntentService {
+ // TODO (jewalker): Revise to Explicit Broadcast Receiver to handle O changes.
+
private static final String TAG = "UpdateCompService";
public static final String ACTION_UPDATE_COMPLICATION =
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceUtil.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/utils/DigitalWatchFaceUtil.java
similarity index 97%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceUtil.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/utils/DigitalWatchFaceUtil.java
index e13440d..42298d0 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceUtil.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/utils/DigitalWatchFaceUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.utils;
import android.graphics.Color;
import android.net.Uri;
@@ -30,6 +30,8 @@
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.Wearable;
+import com.example.android.wearable.watchface.watchfaces.DigitalWatchFaceService;
+
public final class DigitalWatchFaceUtil {
private static final String TAG = "DigitalWatchFaceUtil";
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/Gles2ColoredTriangleList.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/utils/Gles2ColoredTriangleList.java
similarity index 98%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/Gles2ColoredTriangleList.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/utils/Gles2ColoredTriangleList.java
index 2441c65..cfdd3a3 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/Gles2ColoredTriangleList.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/utils/Gles2ColoredTriangleList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.utils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/AnalogWatchFaceService.java
similarity index 98%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/AnalogWatchFaceService.java
index 9fd73a5..1a9573e 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/AnalogWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -38,6 +38,8 @@
import android.util.Log;
import android.view.SurfaceHolder;
+import com.example.android.wearable.watchface.R;
+
import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
@@ -46,8 +48,6 @@
* Sample analog watch face with a ticking second hand. In ambient mode, the second hand isn't
* shown. On devices with low-bit ambient mode, the hands are drawn without anti-aliasing in ambient
* mode. The watch face is drawn with less contrast in mute mode.
- *
- * {@link SweepWatchFaceService} is similar but has a sweep second hand.
*/
public class AnalogWatchFaceService extends CanvasWatchFaceService {
private static final String TAG = "AnalogWatchFaceService";
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/ComplicationSimpleWatchFaceService.java
similarity index 74%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/ComplicationSimpleWatchFaceService.java
index 4905293..f0a5309 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/ComplicationSimpleWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/ComplicationSimpleWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -38,14 +38,19 @@
import android.support.wearable.complications.ComplicationData;
import android.support.wearable.complications.ComplicationHelperActivity;
import android.support.wearable.complications.ComplicationText;
+import android.support.wearable.complications.SystemProviders;
+import android.support.wearable.complications.rendering.TextRenderer;
import android.support.wearable.watchface.CanvasWatchFaceService;
import android.support.wearable.watchface.WatchFaceService;
import android.support.wearable.watchface.WatchFaceStyle;
-import android.text.TextUtils;
+import android.text.TextPaint;
import android.util.Log;
import android.util.SparseArray;
+import android.view.Gravity;
import android.view.SurfaceHolder;
+import com.example.android.wearable.watchface.R;
+
import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
@@ -83,8 +88,8 @@
private class Engine extends CanvasWatchFaceService.Engine {
private static final int MSG_UPDATE_TIME = 0;
- private static final float COMPLICATION_TEXT_SIZE = 38f;
- private static final int COMPLICATION_TAP_BUFFER = 40;
+ private static final float COMPLICATION_MAIN_TEXT_SIZE = 38f;
+ private static final float COMPLICATION_SUB_TEXT_SIZE = 34f;
private static final float HOUR_STROKE_WIDTH = 5f;
private static final float MINUTE_STROKE_WIDTH = 3f;
@@ -121,15 +126,21 @@
private Bitmap mBackgroundBitmap;
private Bitmap mGrayBackgroundBitmap;
- // Variables for painting Complications
- private Paint mComplicationPaint;
+ // Renders text for complications in specified bounds (shrinks text in some cases).
+ private TextRenderer mLeftMainTextComplicationRenderer;
+ private TextRenderer mLeftSubTextComplicationRenderer;
+ private TextRenderer mRightMainTextComplicationRenderer;
+ private TextRenderer mRightSubTextComplicationRenderer;
- /* To properly place each complication, we need their x and y coordinates. While the width
- * may change from moment to moment based on the time, the height will not change, so we
- * store it as a local variable and only calculate it only when the surface changes
- * (onSurfaceChanged()).
- */
- private int mComplicationsY;
+ // Holds Paint style for all complications.
+ private TextPaint mComplicationMainTextPaint;
+ private TextPaint mComplicationSubTextPaint;
+
+ // Bounds for the upper (main text) and lower (subtext) areas of the complications.
+ private Rect mLeftComplicationMainTextBounds;
+ private Rect mLeftComplicationSubTextBounds;
+ private Rect mRightComplicationMainTextBounds;
+ private Rect mRightComplicationSubTextBounds;
/* Maps active complication ids to the data for that complication. Note: Data will only be
* present if the user has chosen a provider via the settings activity for the watch face.
@@ -140,8 +151,6 @@
private boolean mLowBitAmbient;
private boolean mBurnInProtection;
- private Rect mPeekCardBounds = new Rect();
-
private final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -178,18 +187,35 @@
mCalendar = Calendar.getInstance();
- setWatchFaceStyle(new WatchFaceStyle.Builder(ComplicationSimpleWatchFaceService.this)
- .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
- .setAcceptsTapEvents(true)
- .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
- .setShowSystemUiTime(false)
- .build());
-
+ initializeComplicationDefaults();
initializeBackground();
initializeComplication();
initializeWatchFace();
}
+ /*
+ * Sets a system provider as the default provider for the specified watch face
+ * complication id.
+ *
+ * To set a non-system provider as a default, or to clear a default,
+ * use setDefaultComplicationProvider(int, ComponentName, int).
+ *
+ * Important Note: Call these methods before initializing your watch face with
+ * setWatchFaceStyle(). In this example, we call setWatchFaceStyle() in the
+ * initializeWatchFace() method called after this method in onCreate().
+ */
+ private void initializeComplicationDefaults() {
+ setDefaultSystemComplicationProvider(
+ RIGHT_DIAL_COMPLICATION,
+ SystemProviders.DATE,
+ ComplicationData.TYPE_SHORT_TEXT);
+
+ setDefaultSystemComplicationProvider(
+ LEFT_DIAL_COMPLICATION,
+ SystemProviders.WATCH_BATTERY,
+ ComplicationData.TYPE_SHORT_TEXT);
+ }
+
private void initializeBackground() {
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(Color.BLACK);
@@ -202,11 +228,38 @@
}
mActiveComplicationDataSparseArray = new SparseArray<>(COMPLICATION_IDS.length);
- mComplicationPaint = new Paint();
- mComplicationPaint.setColor(Color.WHITE);
- mComplicationPaint.setTextSize(COMPLICATION_TEXT_SIZE);
- mComplicationPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
- mComplicationPaint.setAntiAlias(true);
+ // Both TextPaint objects are used for all complications.
+ mComplicationMainTextPaint = new TextPaint();
+ mComplicationMainTextPaint.setColor(Color.WHITE);
+ mComplicationMainTextPaint.setTextSize(COMPLICATION_MAIN_TEXT_SIZE);
+ mComplicationMainTextPaint.setTypeface(
+ Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
+ mComplicationMainTextPaint.setAntiAlias(true);
+
+ mComplicationSubTextPaint = new TextPaint();
+ mComplicationSubTextPaint.setColor(Color.WHITE);
+ mComplicationSubTextPaint.setTextSize(COMPLICATION_SUB_TEXT_SIZE);
+ mComplicationSubTextPaint.setTypeface(
+ Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
+ mComplicationSubTextPaint.setAntiAlias(true);
+
+ // By default, all text is aligned to the center. If you want to change the text
+ // alignment, use setAlignment() on your TextRenderer instance.
+ mLeftMainTextComplicationRenderer = new TextRenderer();
+ mLeftMainTextComplicationRenderer.setGravity(Gravity.BOTTOM);
+ mLeftMainTextComplicationRenderer.setPaint(mComplicationMainTextPaint);
+
+ mLeftSubTextComplicationRenderer = new TextRenderer();
+ mLeftSubTextComplicationRenderer.setGravity(Gravity.TOP);
+ mLeftSubTextComplicationRenderer.setPaint(mComplicationSubTextPaint);
+
+ mRightMainTextComplicationRenderer = new TextRenderer();
+ mRightMainTextComplicationRenderer.setGravity(Gravity.BOTTOM);
+ mRightMainTextComplicationRenderer.setPaint(mComplicationMainTextPaint);
+
+ mRightSubTextComplicationRenderer = new TextRenderer();
+ mRightSubTextComplicationRenderer.setGravity(Gravity.TOP);
+ mRightSubTextComplicationRenderer.setPaint(mComplicationSubTextPaint);
setActiveComplications(COMPLICATION_IDS);
}
@@ -261,6 +314,10 @@
}
}
});
+
+ setWatchFaceStyle(new WatchFaceStyle.Builder(ComplicationSimpleWatchFaceService.this)
+ .setAcceptsTapEvents(true)
+ .build());
}
@Override
@@ -321,34 +378,13 @@
&& (complicationData.getType() != ComplicationData.TYPE_NOT_CONFIGURED)
&& (complicationData.getType() != ComplicationData.TYPE_EMPTY)) {
- Rect complicationBoundingRect = new Rect(0, 0, 0, 0);
+ if (mLeftComplicationMainTextBounds.contains(x, y)
+ || mLeftComplicationSubTextBounds.contains(x, y)) {
+ return LEFT_DIAL_COMPLICATION;
+ } else if (mRightComplicationMainTextBounds.contains(x, y)
+ || mRightComplicationSubTextBounds.contains(x, y)) {
+ return RIGHT_DIAL_COMPLICATION;
- switch (COMPLICATION_IDS[i]) {
- case LEFT_DIAL_COMPLICATION:
- complicationBoundingRect.set(
- 0, // left
- mComplicationsY - COMPLICATION_TAP_BUFFER, // top
- (mWidth / 2), // right
- ((int) COMPLICATION_TEXT_SIZE // bottom
- + mComplicationsY
- + COMPLICATION_TAP_BUFFER));
- break;
-
- case RIGHT_DIAL_COMPLICATION:
- complicationBoundingRect.set(
- (mWidth / 2), // left
- mComplicationsY - COMPLICATION_TAP_BUFFER, // top
- mWidth, // right
- ((int) COMPLICATION_TEXT_SIZE // bottom
- + mComplicationsY
- + COMPLICATION_TAP_BUFFER));
- break;
- }
-
- if (complicationBoundingRect.width() > 0) {
- if (complicationBoundingRect.contains(x, y)) {
- return COMPLICATION_IDS[i];
- }
} else {
Log.e(TAG, "Not a recognized complication id.");
}
@@ -416,7 +452,17 @@
updateWatchHandStyle();
// Updates complication style
- mComplicationPaint.setAntiAlias(!inAmbientMode);
+ mComplicationMainTextPaint.setAntiAlias(!inAmbientMode);
+ mComplicationSubTextPaint.setAntiAlias(!inAmbientMode);
+
+ // If the properties of the TextPaint have changed, then the TextRenderer may not be
+ // aware that the layout needs to be updated. In this case, a layout update should be
+ // forced by calling requestUpdateLayout().
+ mLeftMainTextComplicationRenderer.requestUpdateLayout();
+ mLeftSubTextComplicationRenderer.requestUpdateLayout();
+
+ mRightMainTextComplicationRenderer.requestUpdateLayout();
+ mRightSubTextComplicationRenderer.requestUpdateLayout();
// Check and trigger whether or not timer should be running (only in active mode).
updateTimer();
@@ -488,11 +534,28 @@
mCenterX = mWidth / 2f;
mCenterY = mHeight / 2f;
- /*
- * Since the height of the complications text does not change, we only have to
- * recalculate when the surface changes.
- */
- mComplicationsY = (int) ((mHeight / 2) + (mComplicationPaint.getTextSize() / 2));
+ // Calculates Left and Right complications' bounds for TextRenderer.
+ int top, left, bottom, right = 0;
+ int heightOfComplication = height / 6;
+
+ left = 0;
+ top = (height / 2) - heightOfComplication;
+ right = width / 2;
+ bottom = height / 2;
+ mLeftComplicationMainTextBounds = new Rect(left, top, right, bottom);
+
+ left = right;
+ right = width;
+ mRightComplicationMainTextBounds = new Rect(left, top, right, bottom);
+
+ top = height / 2;
+ bottom = top + heightOfComplication;
+ mRightComplicationSubTextBounds = new Rect(left, top, right, bottom);
+
+ right = left;
+ left = 0;
+ mLeftComplicationSubTextBounds = new Rect(left, top, right, bottom);
+
/*
* Calculate lengths of different hands based on watch screen size.
@@ -580,47 +643,52 @@
if (complicationData.getType() == ComplicationData.TYPE_SHORT_TEXT
|| complicationData.getType() == ComplicationData.TYPE_NO_PERMISSION) {
- ComplicationText mainText = complicationData.getShortText();
- ComplicationText subText = complicationData.getShortTitle();
-
- CharSequence complicationMessage =
- mainText.getText(getApplicationContext(), currentTimeMillis);
-
- /* In most cases you would want the subText (Title) under the
- * mainText (Text), but to keep it simple for the code lab, we are
- * concatenating them all on one line.
- */
- if (subText != null) {
- complicationMessage = TextUtils.concat(
- complicationMessage,
- " ",
- subText.getText(getApplicationContext(), currentTimeMillis));
- }
-
- //Log.d(TAG, "Com id: " + COMPLICATION_IDS[i] + "\t" + complicationMessage);
- double textWidth =
- mComplicationPaint.measureText(
- complicationMessage,
- 0,
- complicationMessage.length());
-
- int complicationsX;
-
if (COMPLICATION_IDS[i] == LEFT_DIAL_COMPLICATION) {
- complicationsX = (int) ((mWidth / 2) - textWidth) / 2;
- } else {
- // RIGHT_DIAL_COMPLICATION calculations
- int offset = (int) ((mWidth / 2) - textWidth) / 2;
- complicationsX = (mWidth / 2) + offset;
- }
+ // Set the text every time you draw, even if the ComplicationData has
+ // not changed, in case the text includes a time-dependent value.
+ mLeftMainTextComplicationRenderer.setText(
+ ComplicationText.getText(
+ getApplicationContext(),
+ complicationData.getShortTitle(),
+ currentTimeMillis));
- canvas.drawText(
- complicationMessage,
- 0,
- complicationMessage.length(),
- complicationsX,
- mComplicationsY,
- mComplicationPaint);
+ mLeftSubTextComplicationRenderer.setText(
+ ComplicationText.getText(
+ getApplicationContext(),
+ complicationData.getShortText(),
+ currentTimeMillis));
+
+ // Assuming both the title and text exist.
+ mLeftMainTextComplicationRenderer.draw(
+ canvas,
+ mLeftComplicationMainTextBounds);
+ mLeftSubTextComplicationRenderer.draw(
+ canvas,
+ mLeftComplicationSubTextBounds);
+
+ } else if (COMPLICATION_IDS[i] == RIGHT_DIAL_COMPLICATION) {
+ // Set the text every time you draw, even if the ComplicationData has
+ // not changed, in case the text includes a time-dependent value.
+ mRightMainTextComplicationRenderer.setText(
+ ComplicationText.getText(
+ getApplicationContext(),
+ complicationData.getShortTitle(),
+ currentTimeMillis));
+
+ mRightSubTextComplicationRenderer.setText(
+ ComplicationText.getText(
+ getApplicationContext(),
+ complicationData.getShortText(),
+ currentTimeMillis));
+
+ // Assuming both the title and text exist.
+ mRightMainTextComplicationRenderer.draw(
+ canvas,
+ mRightComplicationMainTextBounds);
+ mRightSubTextComplicationRenderer.draw(
+ canvas,
+ mRightComplicationSubTextBounds);
+ }
}
}
}
@@ -700,11 +768,6 @@
/* Restore the canvas' original orientation. */
canvas.restore();
-
- /* Draw rectangle behind peek card in ambient mode to improve readability. */
- if (mAmbient) {
- canvas.drawRect(mPeekCardBounds, mBackgroundPaint);
- }
}
@Override
@@ -724,12 +787,6 @@
updateTimer();
}
- @Override
- public void onPeekCardPositionUpdate(Rect rect) {
- super.onPeekCardPositionUpdate(rect);
- mPeekCardBounds.set(rect);
- }
-
private void registerReceiver() {
if (mRegisteredTimeZoneReceiver) {
return;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/DigitalWatchFaceService.java
similarity index 98%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/DigitalWatchFaceService.java
index f3f97fb..5b6396e 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/DigitalWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/DigitalWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -47,6 +47,9 @@
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Wearable;
+import com.example.android.wearable.watchface.utils.DigitalWatchFaceUtil;
+import com.example.android.wearable.watchface.R;
+
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/FitDistanceWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/FitDistanceWatchFaceService.java
similarity index 98%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/FitDistanceWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/FitDistanceWatchFaceService.java
index 6dee04e..892af39 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/FitDistanceWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/FitDistanceWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -50,6 +50,8 @@
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.result.DailyTotalResult;
+import com.example.android.wearable.watchface.R;
+
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/FitStepsWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/FitStepsWatchFaceService.java
similarity index 98%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/FitStepsWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/FitStepsWatchFaceService.java
index 1f7b298..22ea3b0 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/FitStepsWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/FitStepsWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
@@ -48,6 +48,8 @@
import android.view.SurfaceHolder;
import android.view.WindowInsets;
+import com.example.android.wearable.watchface.R;
+
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/InteractiveWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/InteractiveWatchFaceService.java
similarity index 97%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/InteractiveWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/InteractiveWatchFaceService.java
index 7a50208..08cb8be 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/InteractiveWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/InteractiveWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -29,6 +29,8 @@
import android.view.SurfaceHolder;
import android.view.WindowInsets;
+import com.example.android.wearable.watchface.R;
+
/**
* Demonstrates interactive watch face capabilities, i.e., touching the display and registering
* three different events: touch, touch-cancel and tap. The watch face UI will show the count of
diff --git a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceService.java b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/OpenGLWatchFaceService.java
similarity index 98%
rename from wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceService.java
rename to wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/OpenGLWatchFaceService.java
index 01adcdb..11e3ebf 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceService.java
+++ b/wearable/wear/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/watchfaces/OpenGLWatchFaceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.example.android.wearable.watchface;
+package com.example.android.wearable.watchface.watchfaces;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -28,6 +28,8 @@
import android.view.Gravity;
import android.view.SurfaceHolder;
+import com.example.android.wearable.watchface.utils.Gles2ColoredTriangleList;
+
import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_calendar_watch_face_permission.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_calendar_watch_face_permission.xml
deleted file mode 100644
index bf0e3f6..0000000
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_calendar_watch_face_permission.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.wearable.view.BoxInsetLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/container"
- android:background="@color/white"
- android:paddingTop="32dp"
- android:paddingLeft="36dp"
- android:paddingRight="22dp"
- tools:context="com.example.android.wearable.watchface.CalendarWatchFacePermissionActivity"
- tools:deviceIds="wear">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:onClick="onClickEnablePermission"
- android:orientation="vertical"
- app:layout_box="all">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="16sp"
- android:paddingBottom="18dp"
- android:textColor="#000000"
- android:text="@string/calendar_permission_text"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <android.support.wearable.view.CircledImageView
- android:id="@+id/circle"
- android:layout_width="40dp"
- android:layout_height="40dp"
- app:circle_radius="20dp"
- app:circle_color="#0086D4"
- android:src="@drawable/ic_lock_open_white_24dp"/>
-
- <android.support.v4.widget.Space
- android:layout_width="8dp"
- android:layout_height="8dp"/>
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="16sp"
- android:textColor="#0086D4"
- android:text="Enable Permission"/>
-
-
- </LinearLayout>
-
- </LinearLayout>
-</android.support.wearable.view.BoxInsetLayout>
\ No newline at end of file
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml
index 01f5cac..d32ea10 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_config.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2016 The Android Open Source Project
+ ~ Copyright (C) 2017 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml
index e995271..6eabc7f 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_complication_simple_list_item.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2016 The Android Open Source Project
+ ~ Copyright (C) 2017 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml
index a368390..1672404 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/activity_digital_config.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml b/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml
index 9b07e2a..0ec5844 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/layout/color_picker_item.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml
index a2e37ac..f1cc40d 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/arrays.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2014 The Android Open Source Project
+ Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml
index 1370192..8dd0d78 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/color.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml
index 0b0672b..d3fc3ef 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml b/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
index e4b2717..6c1a3e1 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,10 +18,9 @@
<string name="opengl_name">Sample OpenGL</string>
<string name="interactive_name">Sample Interactive</string>
<string name="analog_name">Sample Analog</string>
- <string name="complication_simple">Sample Complication Simple</string>
- <string name="sweep_name">Sample Sweep</string>
- <string name="card_bounds_name">Sample Card Bounds</string>
+ <string name="complication_simple">Sample Complication</string>
<string name="digital_name">Sample Digital</string>
+
<string name="digital_background_color">Background color</string>
<string name="digital_config_name">Digital watch face configuration</string>
<string name="digital_am">AM</string>
@@ -34,15 +33,6 @@
<string name="fit_steps">%1$d steps</string>
<string name="fit_distance">%1$,.2f meters</string>
- <string name="calendar_name">Sample Calendar</string>
- <string name="calendar_permission_not_approved"><br><br><br>WatchFace requires Calendar permission. Click on this WatchFace or visit Settings > Permissions to approve.</string>
- <plurals name="calendar_meetings">
- <item quantity="one"><br><br><br>You have <b>%1$d</b> meeting in the next 24 hours.</item>
- <item quantity="other"><br><br><br>You have <b>%1$d</b> meetings in the next 24 hours.</item>
- </plurals>
- <string name="title_activity_calendar_watch_face_permission">Calendar Permission Activity</string>
- <string name="calendar_permission_text">WatchFace requires Calendar access.</string>
-
<string name="complication_simple_config_name">Configuration</string>
<string name="complications_provider_random_number">Random Number</string>
diff --git a/wearable/wear/WatchFace/Wearable/src/main/res/xml/watch_face.xml b/wearable/wear/WatchFace/Wearable/src/main/res/xml/watch_face.xml
index aa2e343..4c46d8f 100644
--- a/wearable/wear/WatchFace/Wearable/src/main/res/xml/watch_face.xml
+++ b/wearable/wear/WatchFace/Wearable/src/main/res/xml/watch_face.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/wearable/wear/WatchFace/gradle/wrapper/gradle-wrapper.properties b/wearable/wear/WatchFace/gradle/wrapper/gradle-wrapper.properties
index 95524ef..55dab1a 100644
--- a/wearable/wear/WatchFace/gradle/wrapper/gradle-wrapper.properties
+++ b/wearable/wear/WatchFace/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Aug 24 16:01:26 PDT 2016
+#Mon Mar 27 09:13:27 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip