diff options
author | Trevor Johns <trevorjohns@google.com> | 2015-08-19 17:25:45 -0700 |
---|---|---|
committer | Trevor Johns <trevorjohns@google.com> | 2015-08-19 17:25:45 -0700 |
commit | 20aaa7c7d052fb8e233fcdfd9eae552831f4b243 (patch) | |
tree | 53726cf8eac123038c229b6002fe540f2e8d4434 /prebuilts/gradle | |
parent | 3b06be3ba7da6b39d4cf24b15dcf488408bb19d3 (diff) | |
download | build-20aaa7c7d052fb8e233fcdfd9eae552831f4b243.tar.gz |
Sync sample prebuilts for mnc-dev
Synced to //developers/samples/android commit 57690c2111.
Change-Id: I1b28dbe4c7285ae83e3b1e090b4f2fa0cf0a72cd
Diffstat (limited to 'prebuilts/gradle')
68 files changed, 907 insertions, 355 deletions
diff --git a/prebuilts/gradle/AgendaData/Application/build.gradle b/prebuilts/gradle/AgendaData/Application/build.gradle index 4ba2225d..5e284131 100644 --- a/prebuilts/gradle/AgendaData/Application/build.gradle +++ b/prebuilts/gradle/AgendaData/Application/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/AgendaData/Wearable/build.gradle b/prebuilts/gradle/AgendaData/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/AgendaData/Wearable/build.gradle +++ b/prebuilts/gradle/AgendaData/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/AlwaysOn/Wearable/build.gradle b/prebuilts/gradle/AlwaysOn/Wearable/build.gradle index 48371a56..e3cee117 100644 --- a/prebuilts/gradle/AlwaysOn/Wearable/build.gradle +++ b/prebuilts/gradle/AlwaysOn/Wearable/build.gradle @@ -21,7 +21,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/BasicContactables/Application/build.gradle b/prebuilts/gradle/BasicContactables/Application/build.gradle index 305b9b0f..839adc5c 100644 --- a/prebuilts/gradle/BasicContactables/Application/build.gradle +++ b/prebuilts/gradle/BasicContactables/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Camera2Basic/Application/build.gradle b/prebuilts/gradle/Camera2Basic/Application/build.gradle index c0ed8ea6..7292999f 100644 --- a/prebuilts/gradle/Camera2Basic/Application/build.gradle +++ b/prebuilts/gradle/Camera2Basic/Application/build.gradle @@ -30,12 +30,12 @@ List<String> dirs = [ 'template'] // boilerplate code that is generated by the sample template process android { - compileSdkVersion 21 + compileSdkVersion 23 buildToolsVersion "23.0.0" defaultConfig { minSdkVersion 21 - targetSdkVersion 21 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Camera2Basic/README.md b/prebuilts/gradle/Camera2Basic/README.md index 73ad24ae..a77df09d 100644 --- a/prebuilts/gradle/Camera2Basic/README.md +++ b/prebuilts/gradle/Camera2Basic/README.md @@ -42,7 +42,7 @@ when you are done. Pre-requisites -------------- -- Android SDK v21 +- Android SDK v23 - Android Build Tools v23.0.0 - Android Support Repository diff --git a/prebuilts/gradle/Camera2Raw/Application/build.gradle b/prebuilts/gradle/Camera2Raw/Application/build.gradle index c0ed8ea6..7292999f 100644 --- a/prebuilts/gradle/Camera2Raw/Application/build.gradle +++ b/prebuilts/gradle/Camera2Raw/Application/build.gradle @@ -30,12 +30,12 @@ List<String> dirs = [ 'template'] // boilerplate code that is generated by the sample template process android { - compileSdkVersion 21 + compileSdkVersion 23 buildToolsVersion "23.0.0" defaultConfig { minSdkVersion 21 - targetSdkVersion 21 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Camera2Raw/README.md b/prebuilts/gradle/Camera2Raw/README.md index 8dd05f7a..36ba36f3 100644 --- a/prebuilts/gradle/Camera2Raw/README.md +++ b/prebuilts/gradle/Camera2Raw/README.md @@ -26,7 +26,7 @@ file for each image captured. Pre-requisites -------------- -- Android SDK v21 +- Android SDK v23 - Android Build Tools v23.0.0 - Android Support Repository diff --git a/prebuilts/gradle/Camera2Video/Application/build.gradle b/prebuilts/gradle/Camera2Video/Application/build.gradle index c0ed8ea6..7292999f 100644 --- a/prebuilts/gradle/Camera2Video/Application/build.gradle +++ b/prebuilts/gradle/Camera2Video/Application/build.gradle @@ -30,12 +30,12 @@ List<String> dirs = [ 'template'] // boilerplate code that is generated by the sample template process android { - compileSdkVersion 21 + compileSdkVersion 23 buildToolsVersion "23.0.0" defaultConfig { minSdkVersion 21 - targetSdkVersion 21 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Camera2Video/README.md b/prebuilts/gradle/Camera2Video/README.md index c6bb215b..ac5084ca 100644 --- a/prebuilts/gradle/Camera2Video/README.md +++ b/prebuilts/gradle/Camera2Video/README.md @@ -43,7 +43,7 @@ your MediaRecorder instance. Pre-requisites -------------- -- Android SDK v21 +- Android SDK v23 - Android Build Tools v23.0.0 - Android Support Repository diff --git a/prebuilts/gradle/DataLayer/Application/build.gradle b/prebuilts/gradle/DataLayer/Application/build.gradle index 4ba2225d..5e284131 100644 --- a/prebuilts/gradle/DataLayer/Application/build.gradle +++ b/prebuilts/gradle/DataLayer/Application/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/DataLayer/Wearable/build.gradle b/prebuilts/gradle/DataLayer/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/DataLayer/Wearable/build.gradle +++ b/prebuilts/gradle/DataLayer/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/DelayedConfirmation/Application/build.gradle b/prebuilts/gradle/DelayedConfirmation/Application/build.gradle index 4ba2225d..5e284131 100644 --- a/prebuilts/gradle/DelayedConfirmation/Application/build.gradle +++ b/prebuilts/gradle/DelayedConfirmation/Application/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/DelayedConfirmation/Wearable/build.gradle b/prebuilts/gradle/DelayedConfirmation/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/DelayedConfirmation/Wearable/build.gradle +++ b/prebuilts/gradle/DelayedConfirmation/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle b/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle index fe9191eb..30875fe0 100644 --- a/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle +++ b/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 9 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/ElizaChat/Application/build.gradle b/prebuilts/gradle/ElizaChat/Application/build.gradle index 305b9b0f..839adc5c 100644 --- a/prebuilts/gradle/ElizaChat/Application/build.gradle +++ b/prebuilts/gradle/ElizaChat/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/FindMyPhone/Application/build.gradle b/prebuilts/gradle/FindMyPhone/Application/build.gradle index 4ba2225d..5e284131 100644 --- a/prebuilts/gradle/FindMyPhone/Application/build.gradle +++ b/prebuilts/gradle/FindMyPhone/Application/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/FindMyPhone/Wearable/build.gradle b/prebuilts/gradle/FindMyPhone/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/FindMyPhone/Wearable/build.gradle +++ b/prebuilts/gradle/FindMyPhone/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/Flashlight/Wearable/build.gradle b/prebuilts/gradle/Flashlight/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/Flashlight/Wearable/build.gradle +++ b/prebuilts/gradle/Flashlight/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/Geofencing/Application/build.gradle b/prebuilts/gradle/Geofencing/Application/build.gradle index 7704a819..47bf7435 100644 --- a/prebuilts/gradle/Geofencing/Application/build.gradle +++ b/prebuilts/gradle/Geofencing/Application/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Geofencing/Wearable/build.gradle b/prebuilts/gradle/Geofencing/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/Geofencing/Wearable/build.gradle +++ b/prebuilts/gradle/Geofencing/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/GridViewPager/Wearable/build.gradle b/prebuilts/gradle/GridViewPager/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/GridViewPager/Wearable/build.gradle +++ b/prebuilts/gradle/GridViewPager/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/HdrViewfinder/Application/build.gradle b/prebuilts/gradle/HdrViewfinder/Application/build.gradle index 2e56aecc..2f72e899 100644 --- a/prebuilts/gradle/HdrViewfinder/Application/build.gradle +++ b/prebuilts/gradle/HdrViewfinder/Application/build.gradle @@ -19,6 +19,7 @@ dependencies { compile "com.android.support:support-v4:23.0.0" compile "com.android.support:support-v13:23.0.0" compile "com.android.support:cardview-v7:23.0.0" + compile 'com.android.support:design:23.0.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/JumpingJack/Wearable/build.gradle b/prebuilts/gradle/JumpingJack/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/JumpingJack/Wearable/build.gradle +++ b/prebuilts/gradle/JumpingJack/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/LNotifications/Application/build.gradle b/prebuilts/gradle/LNotifications/Application/build.gradle index 2e56aecc..7292999f 100644 --- a/prebuilts/gradle/LNotifications/Application/build.gradle +++ b/prebuilts/gradle/LNotifications/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 21 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/MediaRecorder/Application/build.gradle b/prebuilts/gradle/MediaRecorder/Application/build.gradle index cdc8a9ba..1ddc3b77 100644 --- a/prebuilts/gradle/MediaRecorder/Application/build.gradle +++ b/prebuilts/gradle/MediaRecorder/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 16 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/NfcProvisioning/Application/build.gradle b/prebuilts/gradle/NfcProvisioning/Application/build.gradle index 2e56aecc..7292999f 100644 --- a/prebuilts/gradle/NfcProvisioning/Application/build.gradle +++ b/prebuilts/gradle/NfcProvisioning/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 21 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Notifications/Application/build.gradle b/prebuilts/gradle/Notifications/Application/build.gradle index 4ba2225d..5e284131 100644 --- a/prebuilts/gradle/Notifications/Application/build.gradle +++ b/prebuilts/gradle/Notifications/Application/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Notifications/Wearable/build.gradle b/prebuilts/gradle/Notifications/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/Notifications/Wearable/build.gradle +++ b/prebuilts/gradle/Notifications/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/Quiz/Application/build.gradle b/prebuilts/gradle/Quiz/Application/build.gradle index 4ba2225d..5e284131 100644 --- a/prebuilts/gradle/Quiz/Application/build.gradle +++ b/prebuilts/gradle/Quiz/Application/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/Quiz/Wearable/build.gradle b/prebuilts/gradle/Quiz/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/Quiz/Wearable/build.gradle +++ b/prebuilts/gradle/Quiz/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/RecipeAssistant/Application/build.gradle b/prebuilts/gradle/RecipeAssistant/Application/build.gradle index 305b9b0f..839adc5c 100644 --- a/prebuilts/gradle/RecipeAssistant/Application/build.gradle +++ b/prebuilts/gradle/RecipeAssistant/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/RuntimePermissions/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/RuntimePermissions/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java deleted file mode 100644 index 3228927b..00000000 --- a/prebuilts/gradle/RuntimePermissions/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright 2013 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.common.activities; - -import android.os.Bundle; -import android.support.v4.app.FragmentActivity; - -import com.example.android.common.logger.Log; -import com.example.android.common.logger.LogWrapper; - -/** - * Base launcher activity, to handle most of the common plumbing for samples. - */ -public class SampleActivityBase extends FragmentActivity { - - public static final String TAG = "SampleActivityBase"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - protected void onStart() { - super.onStart(); - initializeLogging(); - } - - /** Set up targets to receive log data */ - public void initializeLogging() { - // Using Log, front-end to the logging chain, emulates android.util.log method signatures. - // Wraps Android's native log framework - LogWrapper logWrapper = new LogWrapper(); - Log.setLogNode(logWrapper); - - Log.i(TAG, "Ready"); - } -} diff --git a/prebuilts/gradle/SkeletonWearableApp/Wearable/build.gradle b/prebuilts/gradle/SkeletonWearableApp/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/SkeletonWearableApp/Wearable/build.gradle +++ b/prebuilts/gradle/SkeletonWearableApp/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/SpeedTracker/Wearable/build.gradle b/prebuilts/gradle/SpeedTracker/Wearable/build.gradle index 0ffb59aa..429d035a 100644 --- a/prebuilts/gradle/SpeedTracker/Wearable/build.gradle +++ b/prebuilts/gradle/SpeedTracker/Wearable/build.gradle @@ -21,7 +21,7 @@ dependencies { compile 'com.google.android.gms:play-services-location:7.3.0' compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' compile project(':Shared') } diff --git a/prebuilts/gradle/StorageProvider/.google/packaging.yaml b/prebuilts/gradle/StorageProvider/.google/packaging.yaml index 320257d0..daabce92 100644 --- a/prebuilts/gradle/StorageProvider/.google/packaging.yaml +++ b/prebuilts/gradle/StorageProvider/.google/packaging.yaml @@ -9,7 +9,7 @@ technologies: [Android] categories: [Content] languages: [Java] solutions: [Mobile] -github: android-MyCloud +github: android-StorageProvider level: INTERMEDIATE icon: screenshots/icon-web.png apiRefs: diff --git a/prebuilts/gradle/StorageProvider/Application/build.gradle b/prebuilts/gradle/StorageProvider/Application/build.gradle index e1395285..9b681dec 100644 --- a/prebuilts/gradle/StorageProvider/Application/build.gradle +++ b/prebuilts/gradle/StorageProvider/Application/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 19 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/StorageProvider/Application/src/main/java/com/example/android/storageprovider/MainActivity.java b/prebuilts/gradle/StorageProvider/Application/src/main/java/com/example/android/storageprovider/MainActivity.java index 4d41ff4b..5abfa12f 100644 --- a/prebuilts/gradle/StorageProvider/Application/src/main/java/com/example/android/storageprovider/MainActivity.java +++ b/prebuilts/gradle/StorageProvider/Application/src/main/java/com/example/android/storageprovider/MainActivity.java @@ -36,7 +36,7 @@ public class MainActivity extends SampleActivityBase { public static final String TAG = "MainActivity"; - public static final String FRAGTAG = "MyCloudFragment"; + public static final String FRAGTAG = "StorageProviderFragment"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -45,7 +45,7 @@ public class MainActivity extends SampleActivityBase { if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); - MyCloudFragment fragment = new MyCloudFragment(); + StorageProviderFragment fragment = new StorageProviderFragment(); transaction.add(fragment, FRAGTAG); transaction.commit(); } diff --git a/prebuilts/gradle/StorageProvider/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/StorageProvider/Application/src/main/res/values/base-strings.xml index 1712befd..5fd804c4 100644 --- a/prebuilts/gradle/StorageProvider/Application/src/main/res/values/base-strings.xml +++ b/prebuilts/gradle/StorageProvider/Application/src/main/res/values/base-strings.xml @@ -16,7 +16,7 @@ --> <resources> - <string name="app_name">MyCloud</string> + <string name="app_name">StorageProvider</string> <string name="intro_message"> <![CDATA[ diff --git a/prebuilts/gradle/StorageProvider/README.md b/prebuilts/gradle/StorageProvider/README.md index 9040e7b3..bc343bcd 100644 --- a/prebuilts/gradle/StorageProvider/README.md +++ b/prebuilts/gradle/StorageProvider/README.md @@ -1,5 +1,5 @@ -Android MyCloud Sample +Android StorageProvider Sample =================================== This sample shows how to implement a simple documents provider using the storage access @@ -42,7 +42,7 @@ Support - Stack Overflow: http://stackoverflow.com/questions/tagged/android If you've found an error in this sample, please file an issue: -https://github.com/googlesamples/android-MyCloud +https://github.com/googlesamples/android-StorageProvider Patches are encouraged, and may be submitted by forking this project and submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details. diff --git a/prebuilts/gradle/SynchronizedNotifications/Wearable/build.gradle b/prebuilts/gradle/SynchronizedNotifications/Wearable/build.gradle index 6a5bf94f..360b4db7 100644 --- a/prebuilts/gradle/SynchronizedNotifications/Wearable/build.gradle +++ b/prebuilts/gradle/SynchronizedNotifications/Wearable/build.gradle @@ -20,7 +20,7 @@ repositories { dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' compile project(':Shared') } diff --git a/prebuilts/gradle/Timer/Wearable/build.gradle b/prebuilts/gradle/Timer/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/Timer/Wearable/build.gradle +++ b/prebuilts/gradle/Timer/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/WatchFace/Application/build.gradle b/prebuilts/gradle/WatchFace/Application/build.gradle index 32a632a8..387a6b18 100644 --- a/prebuilts/gradle/WatchFace/Application/build.gradle +++ b/prebuilts/gradle/WatchFace/Application/build.gradle @@ -19,7 +19,7 @@ dependencies { compile "com.android.support:support-v4:23.0.0" compile "com.android.support:support-v13:23.0.0" compile "com.android.support:cardview-v7:23.0.0" - compile 'com.google.android.support:wearable:1.1.+' + compile 'com.google.android.support:wearable:1.3.0' compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' wearApp project(':Wearable') @@ -39,7 +39,7 @@ android { defaultConfig { minSdkVersion 18 - targetSdkVersion 23 + targetSdkVersion 22 } compileOptions { diff --git a/prebuilts/gradle/WatchFace/Application/src/main/AndroidManifest.xml b/prebuilts/gradle/WatchFace/Application/src/main/AndroidManifest.xml index 732e3061..5433c94f 100644 --- a/prebuilts/gradle/WatchFace/Application/src/main/AndroidManifest.xml +++ b/prebuilts/gradle/WatchFace/Application/src/main/AndroidManifest.xml @@ -56,10 +56,10 @@ </activity> <activity - android:name=".TiltWatchFaceConfigActivity" + android:name=".OpenGLWatchFaceConfigActivity" android:label="@string/app_name"> <intent-filter> - <action android:name="com.example.android.wearable.watchface.CONFIG_TILT" /> + <action android:name="com.example.android.wearable.watchface.CONFIG_OPENGL" /> <category android:name="com.google.android.wearable.watchface.category.COMPANION_CONFIGURATION" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> diff --git a/prebuilts/gradle/WatchFace/Application/src/main/java/com/example/android/wearable/watchface/TiltWatchFaceConfigActivity.java b/prebuilts/gradle/WatchFace/Application/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceConfigActivity.java index 303e72ea..49edd961 100644 --- a/prebuilts/gradle/WatchFace/Application/src/main/java/com/example/android/wearable/watchface/TiltWatchFaceConfigActivity.java +++ b/prebuilts/gradle/WatchFace/Application/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceConfigActivity.java @@ -22,16 +22,21 @@ import android.os.Bundle; import android.support.wearable.companion.WatchFaceCompanion; import android.widget.TextView; -public class TiltWatchFaceConfigActivity extends Activity { +/** + * The phone-side config activity for {@code OpenGLWatchFaceService}. The + * activity ({@code OpenGLWatchFaceWearableConfigActivity}) doesn't offer any configurations, but + * provides a template to add your own. + */ +public class OpenGLWatchFaceConfigActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_tilt_watch_face_config); + setContentView(R.layout.activity_opengl_watch_face_config); ComponentName name = getIntent().getParcelableExtra(WatchFaceCompanion.EXTRA_WATCH_FACE_COMPONENT); - TextView label = (TextView)findViewById(R.id.label); + TextView label = (TextView) findViewById(R.id.label); label.setText(label.getText() + " (" + name.getClassName() + ")"); } } diff --git a/prebuilts/gradle/WatchFace/Application/src/main/res/layout/activity_tilt_watch_face_config.xml b/prebuilts/gradle/WatchFace/Application/src/main/res/layout/activity_opengl_watch_face_config.xml index bda2d686..f8c172d3 100644 --- a/prebuilts/gradle/WatchFace/Application/src/main/res/layout/activity_tilt_watch_face_config.xml +++ b/prebuilts/gradle/WatchFace/Application/src/main/res/layout/activity_opengl_watch_face_config.xml @@ -20,7 +20,7 @@ <TextView android:id="@+id/label" - android:text="@string/tilt_config_text" + android:text="@string/opengl_config_text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> diff --git a/prebuilts/gradle/WatchFace/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/WatchFace/Application/src/main/res/values/base-strings.xml index ef8f1d39..1b346c9b 100644 --- a/prebuilts/gradle/WatchFace/Application/src/main/res/values/base-strings.xml +++ b/prebuilts/gradle/WatchFace/Application/src/main/res/values/base-strings.xml @@ -23,8 +23,8 @@ This sample demonstrates how to create watch faces for android wear and includes a phone app and a wearable app. The wearable app has a variety of watch faces including analog, digital, -opengl, calendar, etc. It also includes a watch-side configuration example. The phone app -includes a phone-side configuration example. +opengl, calendar, interactive, etc. It also includes a watch-side configuration example. +The phone app includes a phone-side configuration example. ]]> diff --git a/prebuilts/gradle/WatchFace/Application/src/main/res/values/strings.xml b/prebuilts/gradle/WatchFace/Application/src/main/res/values/strings.xml index aacb108e..6c6834f0 100644 --- a/prebuilts/gradle/WatchFace/Application/src/main/res/values/strings.xml +++ b/prebuilts/gradle/WatchFace/Application/src/main/res/values/strings.xml @@ -16,7 +16,7 @@ <resources> <string name="analog_config_text">This is the config activity for the Analog and Card Bounds watch faces</string> <string name="digital_config_text">Digital watch face configuration</string> - <string name="tilt_config_text">Tilt watch face configuration</string> + <string name="opengl_config_text">OpenGL watch face configuration</string> <string name="digital_config_background">Background</string> <string name="digital_config_hours">Hours</string> <string name="digital_config_minutes">Minutes</string> diff --git a/prebuilts/gradle/WatchFace/README.md b/prebuilts/gradle/WatchFace/README.md index ba9c1639..78c9ed41 100644 --- a/prebuilts/gradle/WatchFace/README.md +++ b/prebuilts/gradle/WatchFace/README.md @@ -4,8 +4,8 @@ Android WatchFace Sample This sample demonstrates how to create watch faces for android wear and includes a phone app and a wearable app. The wearable app has a variety of watch faces including analog, digital, -opengl, calendar, etc. It also includes a watch-side configuration example. The phone app -includes a phone-side configuration example. +opengl, calendar, interactive, etc. It also includes a watch-side configuration example. +The phone app includes a phone-side configuration example. Pre-requisites -------------- diff --git a/prebuilts/gradle/WatchFace/Wearable/build.gradle b/prebuilts/gradle/WatchFace/Wearable/build.gradle index fccfb11b..4aa863c0 100644 --- a/prebuilts/gradle/WatchFace/Wearable/build.gradle +++ b/prebuilts/gradle/WatchFace/Wearable/build.gradle @@ -15,11 +15,12 @@ apply plugin: 'com.android.application' dependencies { + compile 'com.android.support:palette-v7:21.0.0' compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml b/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml index 14fee36c..c96d7305 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml @@ -76,21 +76,21 @@ </service> <service - android:name=".TiltWatchFaceService" - android:label="@string/tilt_name" + android:name=".OpenGLWatchFaceService" + android:label="@string/opengl_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_tilt" /> + android:resource="@drawable/preview_opengl" /> <meta-data android:name="com.google.android.wearable.watchface.preview_circular" - android:resource="@drawable/preview_tilt_circular" /> + android:resource="@drawable/preview_opengl_circular" /> <meta-data android:name="com.google.android.wearable.watchface.companionConfigurationAction" - android:value="com.example.android.wearable.watchface.CONFIG_TILT" /> + android:value="com.example.android.wearable.watchface.CONFIG_OPENGL" /> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService" /> @@ -120,6 +120,27 @@ </intent-filter> </service> + + <service + android:name=".InteractiveWatchFaceService" + android:label="@string/interactive_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_interactive" /> + <meta-data + android:name="com.google.android.wearable.watchface.preview_circular" + android:resource="@drawable/preview_interactive_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=".DigitalWatchFaceService" android:label="@string/digital_name" diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java index 16194b15..fb86ac70 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/AnalogWatchFaceService.java @@ -20,16 +20,18 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; 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.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.support.v7.graphics.Palette; import android.support.wearable.watchface.CanvasWatchFaceService; import android.support.wearable.watchface.WatchFaceService; import android.support.wearable.watchface.WatchFaceStyle; @@ -50,7 +52,7 @@ import java.util.concurrent.TimeUnit; public class AnalogWatchFaceService extends CanvasWatchFaceService { private static final String TAG = "AnalogWatchFaceService"; - /** + /* * Update rate in milliseconds for interactive mode. We update once a second to advance the * second hand. */ @@ -62,55 +64,73 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { } private class Engine extends CanvasWatchFaceService.Engine { - static final int MSG_UPDATE_TIME = 0; + private static final int MSG_UPDATE_TIME = 0; - static final float TWO_PI = (float) Math.PI * 2f; + 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; - Paint mHourPaint; - Paint mMinutePaint; - Paint mSecondPaint; - Paint mTickPaint; - boolean mMute; - Calendar mCalendar; + private static final float CENTER_GAP_AND_CIRCLE_RADIUS = 4f; - /** Handler to update the time once a second in interactive mode. */ - final Handler mUpdateTimeHandler = new Handler() { - @Override - public void handleMessage(Message message) { - switch (message.what) { - case MSG_UPDATE_TIME: - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "updating time"); - } - invalidate(); - if (shouldTimerBeRunning()) { - long timeMs = System.currentTimeMillis(); - long delayMs = INTERACTIVE_UPDATE_RATE_MS - - (timeMs % INTERACTIVE_UPDATE_RATE_MS); - mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs); - } - break; - } - } - }; + private static final int SHADOW_RADIUS = 6; + + private Calendar mCalendar; + private boolean mRegisteredTimeZoneReceiver = false; + private boolean mMuteMode; + + private float mCenterX; + private float mCenterY; - final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() { + private float mSecondHandLength; + private float sMinuteHandLength; + private float sHourHandLength; + + /* Colors for all hands (hour, minute, seconds, ticks) based on photo loaded. */ + private int mWatchHandColor; + private int mWatchHandHightlightColor; + 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(); } }; - boolean mRegisteredTimeZoneReceiver = false; - /** - * Whether the display supports fewer bits for each color in ambient mode. When true, we - * disable anti-aliasing in ambient mode. - */ - boolean mLowBitAmbient; + /* Handler to update the time once a second in interactive mode. */ + private final Handler mUpdateTimeHandler = new Handler() { + @Override + public void handleMessage(Message message) { + + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "updating time"); + } + invalidate(); + if (shouldTimerBeRunning()) { + long timeMs = System.currentTimeMillis(); + long delayMs = INTERACTIVE_UPDATE_RATE_MS + - (timeMs % INTERACTIVE_UPDATE_RATE_MS); + mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs); + } - Bitmap mBackgroundBitmap; - Bitmap mBackgroundScaledBitmap; + } + }; @Override public void onCreate(SurfaceHolder holder) { @@ -125,32 +145,61 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { .setShowSystemUiTime(false) .build()); - Resources resources = AnalogWatchFaceService.this.getResources(); - Drawable backgroundDrawable = resources.getDrawable(R.drawable.bg, null /* theme */); - mBackgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap(); + mBackgroundPaint = new Paint(); + mBackgroundPaint.setColor(Color.BLACK); + mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg); + + /* Set defaults for colors */ + mWatchHandColor = Color.WHITE; + mWatchHandHightlightColor = Color.RED; + mWatchHandShadowColor = Color.BLACK; mHourPaint = new Paint(); - mHourPaint.setARGB(255, 200, 200, 200); - mHourPaint.setStrokeWidth(5.f); + 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.setARGB(255, 200, 200, 200); - mMinutePaint.setStrokeWidth(3.f); + 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.setARGB(255, 255, 0, 0); - mSecondPaint.setStrokeWidth(2.f); + mSecondPaint.setColor(mWatchHandHightlightColor); + mSecondPaint.setStrokeWidth(SECOND_TICK_STROKE_WIDTH); mSecondPaint.setAntiAlias(true); mSecondPaint.setStrokeCap(Paint.Cap.ROUND); - - mTickPaint = new Paint(); - mTickPaint.setARGB(100, 255, 255, 255); - mTickPaint.setStrokeWidth(2.f); - mTickPaint.setAntiAlias(true); + 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); + } + + mWatchHandHightlightColor = palette.getVibrantColor(Color.RED); + mWatchHandColor = palette.getLightVibrantColor(Color.WHITE); + mWatchHandShadowColor = palette.getDarkMutedColor(Color.BLACK); + updateWatchHandStyle(); + } + } + }); mCalendar = Calendar.getInstance(); } @@ -164,18 +213,17 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { @Override public void onPropertiesChanged(Bundle properties) { super.onPropertiesChanged(properties); - mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false); 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(); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "onTimeTick: ambient = " + isInAmbientMode()); - } invalidate(); } @@ -185,26 +233,57 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode); } - if (mLowBitAmbient) { - boolean antiAlias = !inAmbientMode; - mHourPaint.setAntiAlias(antiAlias); - mMinutePaint.setAntiAlias(antiAlias); - mSecondPaint.setAntiAlias(antiAlias); - mTickPaint.setAntiAlias(antiAlias); - } - invalidate(); + mAmbient = inAmbientMode; + + updateWatchHandStyle(); - // Whether the timer should be running depends on whether we're in ambient mode (as well - // as whether we're visible), so we may need to start or stop the timer. + /* Check and trigger whether or not timer should be running (only in active mode). */ updateTimer(); } + 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(mWatchHandHightlightColor); + 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); - if (mMute != inMuteMode) { - mMute = inMuteMode; + + /* 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); @@ -214,92 +293,179 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { - if (mBackgroundScaledBitmap == null - || mBackgroundScaledBitmap.getWidth() != width - || mBackgroundScaledBitmap.getHeight() != height) { - mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap, - width, height, true /* filter */); - } 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); + sMinuteHandLength = (float) (mCenterX * 0.75); + sHourHandLength = (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) { - mCalendar.setTimeInMillis(System.currentTimeMillis()); - - int width = bounds.width(); - int height = bounds.height(); - - // Draw the background, scaled to fit. - canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null); + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "onDraw"); + } + long now = System.currentTimeMillis(); + mCalendar.setTimeInMillis(now); - // Find the center. Ignore the window insets so that, on round watches with a - // "chin", the watch face is centered on the entire screen, not just the usable - // portion. - float centerX = width / 2f; - float centerY = height / 2f; + 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 the ticks. - float innerTickRadius = centerX - 10; - float outerTickRadius = centerX; + /* + * 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 = tickIndex * TWO_PI / 12; + 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(centerX + innerX, centerY + innerY, - centerX + outerX, centerY + outerY, mTickPaint); + canvas.drawLine(mCenterX + innerX, mCenterY + innerY, + mCenterX + outerX, mCenterY + outerY, mTickAndCirclePaint); } - float seconds = - mCalendar.get(Calendar.SECOND) + mCalendar.get(Calendar.MILLISECOND) / 1000f; - float secRot = seconds / 60f * TWO_PI; - float minutes = mCalendar.get(Calendar.MINUTE) + seconds / 60f; - float minRot = minutes / 60f * TWO_PI; - float hours = mCalendar.get(Calendar.HOUR) + minutes / 60f; - float hrRot = hours / 12f * TWO_PI; - - float secLength = centerX - 20; - float minLength = centerX - 40; - float hrLength = centerX - 80; - - if (!isInAmbientMode()) { - float secX = (float) Math.sin(secRot) * secLength; - float secY = (float) -Math.cos(secRot) * secLength; - canvas.drawLine(centerX, centerY, centerX + secX, centerY + secY, mSecondPaint); - } - - float minX = (float) Math.sin(minRot) * minLength; - float minY = (float) -Math.cos(minRot) * minLength; - canvas.drawLine(centerX, centerY, centerX + minX, centerY + minY, mMinutePaint); + /* + * 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 - sHourHandLength, + mHourPaint); + + canvas.rotate(minutesRotation - hoursRotation, mCenterX, mCenterY); + canvas.drawLine( + mCenterX, + mCenterY - CENTER_GAP_AND_CIRCLE_RADIUS, + mCenterX, + mCenterY - sMinuteHandLength, + 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); - float hrX = (float) Math.sin(hrRot) * hrLength; - float hrY = (float) -Math.cos(hrRot) * hrLength; - canvas.drawLine(centerX, centerY, centerX + hrX, centerY + hrY, mHourPaint); + } + 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); + } } @Override public void onVisibilityChanged(boolean visible) { super.onVisibilityChanged(visible); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "onVisibilityChanged: " + visible); - } if (visible) { registerReceiver(); - - // Update time zone in case it changed while we weren't visible. + /* Update time zone in case it changed while we weren't visible. */ mCalendar.setTimeZone(TimeZone.getDefault()); + invalidate(); } else { unregisterReceiver(); } - // Whether the timer should be running depends on whether we're visible (as well as - // whether we're in ambient mode), so we may need to start or stop the timer. + /* Check and trigger whether or not timer should be running (only in active mode). */ updateTimer(); } + @Override + public void onPeekCardPositionUpdate(Rect rect) { + super.onPeekCardPositionUpdate(rect); + mPeekCardBounds.set(rect); + } + private void registerReceiver() { if (mRegisteredTimeZoneReceiver) { return; @@ -318,8 +484,7 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { } /** - * Starts the {@link #mUpdateTimeHandler} timer if it should be running and isn't currently - * or stops it if it shouldn't be running but currently is. + * Starts/stops the {@link #mUpdateTimeHandler} timer based on the state of the watch face. */ private void updateTimer() { if (Log.isLoggable(TAG, Log.DEBUG)) { @@ -332,12 +497,11 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService { } /** - * Returns whether the {@link #mUpdateTimeHandler} timer should be running. The timer should - * only run when we're visible and in interactive mode. + * Returns whether the {@link #mUpdateTimeHandler} timer should be running. The timer + * should only run in active mode. */ private boolean shouldTimerBeRunning() { - return isVisible() && !isInAmbientMode(); + return isVisible() && !mAmbient; } - } } diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/InteractiveWatchFaceService.java b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/InteractiveWatchFaceService.java new file mode 100644 index 00000000..1a6f25b5 --- /dev/null +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/InteractiveWatchFaceService.java @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2015 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.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.os.Bundle; +import android.support.wearable.watchface.CanvasWatchFaceService; +import android.support.wearable.watchface.WatchFaceStyle; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.WindowInsets; + +/** + * Demostrates 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 + * these events as they occur. See the {@code onTapCommand} below. + */ +public class InteractiveWatchFaceService extends CanvasWatchFaceService { + + private static final String TAG = "InteractiveWatchFace"; + + private static final Typeface BOLD_TYPEFACE = + Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); + private static final Typeface NORMAL_TYPEFACE = + Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL); + + @Override + public Engine onCreateEngine() { + return new Engine(); + } + + private class Engine extends CanvasWatchFaceService.Engine { + + private Paint mTextPaint; + private final Paint mPeekCardBackgroundPaint = new Paint(); + + private float mXOffset; + private float mYOffset; + private float mTextSpacingHeight; + private int mScreenTextColor = Color.WHITE; + + private int mTouchCommandTotal; + private int mTouchCancelCommandTotal; + private int mTapCommandTotal; + + private int mTouchCoordinateX; + private int mTouchCoordinateY; + + private final Rect mCardBounds = new Rect(); + + /** + * Whether the display supports fewer bits for each color in ambient mode. When true, we + * disable anti-aliasing in ambient mode. + */ + private boolean mLowBitAmbient; + + @Override + public void onCreate(SurfaceHolder holder) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "onCreate"); + } + super.onCreate(holder); + + /** Accepts tap events via WatchFaceStyle (setAcceptsTapEvents(true)). */ + setWatchFaceStyle(new WatchFaceStyle.Builder(InteractiveWatchFaceService.this) + .setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE) + .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE) + .setShowSystemUiTime(false) + .setAcceptsTapEvents(true) + .build()); + + Resources resources = InteractiveWatchFaceService.this.getResources(); + mTextSpacingHeight = resources.getDimension(R.dimen.interactive_text_size); + + mTextPaint = new Paint(); + mTextPaint.setColor(mScreenTextColor); + mTextPaint.setTypeface(BOLD_TYPEFACE); + mTextPaint.setAntiAlias(true); + + mTouchCommandTotal = 0; + mTouchCancelCommandTotal = 0; + mTapCommandTotal = 0; + + mTouchCoordinateX = 0; + mTouchCoordinateX = 0; + } + + @Override + public void onApplyWindowInsets(WindowInsets insets) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "onApplyWindowInsets: " + (insets.isRound() ? "round" : "square")); + } + super.onApplyWindowInsets(insets); + + /** Loads offsets / text size based on device type (square vs. round). */ + Resources resources = InteractiveWatchFaceService.this.getResources(); + boolean isRound = insets.isRound(); + mXOffset = resources.getDimension( + isRound ? R.dimen.interactive_x_offset_round : R.dimen.interactive_x_offset); + mYOffset = resources.getDimension( + isRound ? R.dimen.interactive_y_offset_round : R.dimen.interactive_y_offset); + + float textSize = resources.getDimension( + isRound ? R.dimen.interactive_text_size_round : R.dimen.interactive_text_size); + + mTextPaint.setTextSize(textSize); + } + + @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 onPropertiesChanged(Bundle properties) { + super.onPropertiesChanged(properties); + + boolean burnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION, false); + mTextPaint.setTypeface(burnInProtection ? NORMAL_TYPEFACE : BOLD_TYPEFACE); + + mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false); + + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "onPropertiesChanged: burn-in protection = " + burnInProtection + + ", low-bit ambient = " + mLowBitAmbient); + } + } + + @Override + public void onAmbientModeChanged(boolean inAmbientMode) { + super.onAmbientModeChanged(inAmbientMode); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode); + } + + if (mLowBitAmbient) { + boolean antiAlias = !inAmbientMode; + mTextPaint.setAntiAlias(antiAlias); + } + invalidate(); + } + + /* + * 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); + } + + mTouchCoordinateX = x; + mTouchCoordinateY = y; + + switch(tapType) { + case TAP_TYPE_TOUCH: + mTouchCommandTotal++; + break; + case TAP_TYPE_TOUCH_CANCEL: + mTouchCancelCommandTotal++; + break; + case TAP_TYPE_TAP: + mTapCommandTotal++; + break; + } + + invalidate(); + } + + @Override + public void onDraw(Canvas canvas, Rect bounds) { + /** Draws background */ + canvas.drawColor(Color.BLACK); + + canvas.drawText( + "TAP: " + String.valueOf(mTapCommandTotal), + mXOffset, + mYOffset, + mTextPaint); + + canvas.drawText( + "CANCEL: " + String.valueOf(mTouchCancelCommandTotal), + mXOffset, + mYOffset + mTextSpacingHeight, + mTextPaint); + + canvas.drawText( + "TOUCH: " + String.valueOf(mTouchCommandTotal), + mXOffset, + mYOffset + (mTextSpacingHeight * 2), + mTextPaint); + + canvas.drawText( + "X, Y: " + mTouchCoordinateX + ", " + mTouchCoordinateY, + mXOffset, + mYOffset + (mTextSpacingHeight * 3), + mTextPaint + ); + + /** Covers area under peek card */ + if (isInAmbientMode()) { + canvas.drawRect(mCardBounds, mPeekCardBackgroundPaint); + } + } + } +} diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/TiltWatchFaceService.java b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceService.java index 879473c9..01adcdb5 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/TiltWatchFaceService.java +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/OpenGLWatchFaceService.java @@ -37,9 +37,9 @@ import java.util.concurrent.TimeUnit; * {@link Gles2ColoredTriangleList}s. The camera moves around in interactive mode and stops moving * when the watch enters ambient mode. */ -public class TiltWatchFaceService extends Gles2WatchFaceService { +public class OpenGLWatchFaceService extends Gles2WatchFaceService { - private static final String TAG = "TiltWatchFaceService"; + private static final String TAG = "OpenGLWatchFaceService"; /** Expected frame rate in interactive mode. */ private static final long FPS = 60; @@ -129,7 +129,7 @@ public class TiltWatchFaceService extends Gles2WatchFaceService { Log.d(TAG, "onCreate"); } super.onCreate(surfaceHolder); - setWatchFaceStyle(new WatchFaceStyle.Builder(TiltWatchFaceService.this) + setWatchFaceStyle(new WatchFaceStyle.Builder(OpenGLWatchFaceService.this) .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT) .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE) .setStatusBarGravity(Gravity.RIGHT | Gravity.TOP) @@ -395,7 +395,7 @@ public class TiltWatchFaceService extends Gles2WatchFaceService { } mRegisteredTimeZoneReceiver = true; IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED); - TiltWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter); + OpenGLWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter); } private void unregisterReceiver() { @@ -403,7 +403,7 @@ public class TiltWatchFaceService extends Gles2WatchFaceService { return; } mRegisteredTimeZoneReceiver = false; - TiltWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver); + OpenGLWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver); } @Override diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java index d547f1ce..0ba2ab93 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/java/com/example/android/wearable/watchface/SweepWatchFaceService.java @@ -20,14 +20,16 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; 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.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; 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; @@ -45,6 +47,7 @@ import java.util.TimeZone; * {@link AnalogWatchFaceService} is similar but has a ticking second hand. */ public class SweepWatchFaceService extends CanvasWatchFaceService { + private static final String TAG = "SweepWatchFaceService"; @Override @@ -53,32 +56,53 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { } private class Engine extends CanvasWatchFaceService.Engine { - static final float TWO_PI = (float) Math.PI * 2f; - Paint mHourPaint; - Paint mMinutePaint; - Paint mSecondPaint; - Paint mTickPaint; - boolean mMute; - Calendar mCalendar; + 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 mWatchHandHightlightColor; + private int mWatchHandShadowColor; - final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() { + 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(); } }; - boolean mRegisteredTimeZoneReceiver = false; - - /** - * Whether the display supports fewer bits for each color in ambient mode. When true, we - * disable anti-aliasing in ambient mode. - */ - boolean mLowBitAmbient; - - Bitmap mBackgroundBitmap; - Bitmap mBackgroundScaledBitmap; @Override public void onCreate(SurfaceHolder holder) { @@ -93,32 +117,61 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { .setShowSystemUiTime(false) .build()); - Resources resources = SweepWatchFaceService.this.getResources(); - Drawable backgroundDrawable = resources.getDrawable(R.drawable.bg, null /* theme */); - mBackgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap(); + mBackgroundPaint = new Paint(); + mBackgroundPaint.setColor(Color.BLACK); + mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg); + + /* Set defaults for colors */ + mWatchHandColor = Color.WHITE; + mWatchHandHightlightColor = Color.RED; + mWatchHandShadowColor = Color.BLACK; mHourPaint = new Paint(); - mHourPaint.setARGB(255, 200, 200, 200); - mHourPaint.setStrokeWidth(5.f); + 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.setARGB(255, 200, 200, 200); - mMinutePaint.setStrokeWidth(3.f); + 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.setARGB(255, 255, 0, 0); - mSecondPaint.setStrokeWidth(2.f); + mSecondPaint.setColor(mWatchHandHightlightColor); + mSecondPaint.setStrokeWidth(SECOND_TICK_STROKE_WIDTH); mSecondPaint.setAntiAlias(true); mSecondPaint.setStrokeCap(Paint.Cap.ROUND); - - mTickPaint = new Paint(); - mTickPaint.setARGB(100, 255, 255, 255); - mTickPaint.setStrokeWidth(2.f); - mTickPaint.setAntiAlias(true); + 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); + } + + mWatchHandHightlightColor = palette.getVibrantColor(Color.RED); + mWatchHandColor = palette.getLightVibrantColor(Color.WHITE); + mWatchHandShadowColor = palette.getDarkMutedColor(Color.BLACK); + updateWatchHandStyle(); + } + } + }); mCalendar = Calendar.getInstance(); } @@ -126,18 +179,17 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { @Override public void onPropertiesChanged(Bundle properties) { super.onPropertiesChanged(properties); - mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false); 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(); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "onTimeTick: ambient = " + isInAmbientMode()); - } invalidate(); } @@ -147,22 +199,56 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode); } - if (mLowBitAmbient) { - boolean antiAlias = !inAmbientMode; - mHourPaint.setAntiAlias(antiAlias); - mMinutePaint.setAntiAlias(antiAlias); - mSecondPaint.setAntiAlias(antiAlias); - mTickPaint.setAntiAlias(antiAlias); - } + 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(mWatchHandHightlightColor); + 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); - if (mMute != inMuteMode) { - mMute = inMuteMode; + + /* 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); @@ -172,13 +258,58 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { - if (mBackgroundScaledBitmap == null - || mBackgroundScaledBitmap.getWidth() != width - || mBackgroundScaledBitmap.getHeight() != height) { - mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap, - width, height, true /* filter */); - } 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 @@ -189,59 +320,95 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { long now = System.currentTimeMillis(); mCalendar.setTimeInMillis(now); - int width = bounds.width(); - int height = bounds.height(); - - // Draw the background, scaled to fit. - canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null); - - // Find the center. Ignore the window insets so that, on round watches with a - // "chin", the watch face is centered on the entire screen, not just the usable - // portion. - float centerX = width / 2f; - float centerY = height / 2f; + 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 the ticks. - float innerTickRadius = centerX - 10; - float outerTickRadius = centerX; + /* + * 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(centerX + innerX, centerY + innerY, - centerX + outerX, centerY + outerY, mTickPaint); + canvas.drawLine(mCenterX + innerX, mCenterY + innerY, + mCenterX + outerX, mCenterY + outerY, mTickAndCirclePaint); } - float seconds = - mCalendar.get(Calendar.SECOND) + mCalendar.get(Calendar.MILLISECOND) / 1000f; - float secRot = seconds / 60f * TWO_PI; - float minutes = mCalendar.get(Calendar.MINUTE) + seconds / 60f; - float minRot = minutes / 60f * TWO_PI; - float hours = mCalendar.get(Calendar.HOUR) + minutes / 60f; - float hrRot = hours / 12f * TWO_PI; - - float secLength = centerX - 20; - float minLength = centerX - 40; - float hrLength = centerX - 80; - - if (!isInAmbientMode()) { - float secX = (float) Math.sin(secRot) * secLength; - float secY = (float) -Math.cos(secRot) * secLength; - canvas.drawLine(centerX, centerY, centerX + secX, centerY + secY, mSecondPaint); - } - - float minX = (float) Math.sin(minRot) * minLength; - float minY = (float) -Math.cos(minRot) * minLength; - canvas.drawLine(centerX, centerY, centerX + minX, centerY + minY, mMinutePaint); + /* + * 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); - float hrX = (float) Math.sin(hrRot) * hrLength; - float hrY = (float) -Math.cos(hrRot) * hrLength; - canvas.drawLine(centerX, centerY, centerX + hrX, centerY + hrY, mHourPaint); + } + 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() && !isInAmbientMode()) { + /* Draw every frame as long as we're visible and in interactive mode. */ + if ((isVisible()) && (!mAmbient)) { invalidate(); } } @@ -252,16 +419,20 @@ public class SweepWatchFaceService extends CanvasWatchFaceService { if (visible) { registerReceiver(); - - // Update time zone in case it changed while we weren't visible. + /* 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; diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/bg.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/bg.png Binary files differindex 5199af2d..c83911a5 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/bg.png +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/bg.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog.png Binary files differindex ed6960db..af43c3de 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog.png +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog_circular.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog_circular.png Binary files differindex a3affe21..cb93b4ef 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog_circular.png +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_analog_circular.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_interactive.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_interactive.png Binary files differnew file mode 100644 index 00000000..cbfedd0f --- /dev/null +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_interactive.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_interactive_circular.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_interactive_circular.png Binary files differnew file mode 100644 index 00000000..9e512401 --- /dev/null +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_interactive_circular.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_tilt.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_opengl.png Binary files differindex aab5f18d..aab5f18d 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_tilt.png +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_opengl.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_tilt_circular.png b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_opengl_circular.png Binary files differindex 31d3a1f9..31d3a1f9 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_tilt_circular.png +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/drawable-hdpi/preview_opengl_circular.png diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/dimens.xml b/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/dimens.xml index aef847b0..4973466e 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/dimens.xml +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/dimens.xml @@ -25,4 +25,11 @@ <dimen name="digital_line_height">25dp</dimen> <dimen name="digital_config_color_picker_item_margin">32dp</dimen> <dimen name="content_padding_start">12dp</dimen> + <dimen name="interactive_text_size">20dp</dimen> + <dimen name="interactive_text_size_round">25dp</dimen> + <dimen name="interactive_x_offset">15dp</dimen> + <dimen name="interactive_x_offset_round">25dp</dimen> + <dimen name="interactive_y_offset">72dp</dimen> + <dimen name="interactive_y_offset_round">84dp</dimen> + <dimen name="interactive_line_height">25dp</dimen> </resources> diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/strings.xml b/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/strings.xml index e54591fd..19bc3e7f 100644 --- a/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/strings.xml +++ b/prebuilts/gradle/WatchFace/Wearable/src/main/res/values/strings.xml @@ -15,7 +15,8 @@ --> <resources> <string name="app_name">WatchFace</string> - <string name="tilt_name">Sample Tilt</string> + <string name="opengl_name">Sample OpenGL</string> + <string name="interactive_name">Sample Interactive</string> <string name="analog_name">Sample Analog</string> <string name="sweep_name">Sample Sweep</string> <string name="card_bounds_name">Sample Card Bounds</string> diff --git a/prebuilts/gradle/WatchFace/screenshots/analog_and_sweep_face.png b/prebuilts/gradle/WatchFace/screenshots/analog_and_sweep_face.png Binary files differindex df0820ed..af43c3de 100644 --- a/prebuilts/gradle/WatchFace/screenshots/analog_and_sweep_face.png +++ b/prebuilts/gradle/WatchFace/screenshots/analog_and_sweep_face.png diff --git a/prebuilts/gradle/WatchFace/screenshots/interactive_face.png b/prebuilts/gradle/WatchFace/screenshots/interactive_face.png Binary files differnew file mode 100644 index 00000000..9e512401 --- /dev/null +++ b/prebuilts/gradle/WatchFace/screenshots/interactive_face.png diff --git a/prebuilts/gradle/WatchViewStub/Wearable/build.gradle b/prebuilts/gradle/WatchViewStub/Wearable/build.gradle index fccfb11b..72fac4a7 100644 --- a/prebuilts/gradle/WatchViewStub/Wearable/build.gradle +++ b/prebuilts/gradle/WatchViewStub/Wearable/build.gradle @@ -19,7 +19,7 @@ dependencies { compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' } // The sample build uses multiple directories to diff --git a/prebuilts/gradle/XYZTouristAttractions/Wearable/build.gradle b/prebuilts/gradle/XYZTouristAttractions/Wearable/build.gradle index 0ffb59aa..429d035a 100644 --- a/prebuilts/gradle/XYZTouristAttractions/Wearable/build.gradle +++ b/prebuilts/gradle/XYZTouristAttractions/Wearable/build.gradle @@ -21,7 +21,7 @@ dependencies { compile 'com.google.android.gms:play-services-location:7.3.0' compile 'com.google.android.gms:play-services-wearable:7.3.0' compile 'com.android.support:support-v13:23.0.0' - compile 'com.google.android.support:wearable:1.2.0' + compile 'com.google.android.support:wearable:1.3.0' compile project(':Shared') } |