summaryrefslogtreecommitdiffstats
path: root/samples/browseable/AlwaysOn
diff options
context:
space:
mode:
authorTrevor Johns <trevorjohns@google.com>2015-05-08 19:29:42 -0700
committerTrevor Johns <trevorjohns@google.com>2015-05-08 19:29:42 -0700
commit434d41c45df023fd543a94e88b0bda2dc5c7844d (patch)
tree11589625b30085c4803f5edb544de3305c2fa3fe /samples/browseable/AlwaysOn
parent03236391f11efe2a9ce89ab92602c58ba717f626 (diff)
downloadandroid_development-434d41c45df023fd543a94e88b0bda2dc5c7844d.tar.gz
android_development-434d41c45df023fd543a94e88b0bda2dc5c7844d.tar.bz2
android_development-434d41c45df023fd543a94e88b0bda2dc5c7844d.zip
Update samples prebuilts for lmp-mr1-ub-docs
Synced to developers/samples/android commit 54bab34b386e343e9d0ea75a5fb8d13db2c71eb5. Change-Id: I1c9d9d2c1f53a051d7b4d85303d5c01ab6f16e68
Diffstat (limited to 'samples/browseable/AlwaysOn')
-rw-r--r--samples/browseable/AlwaysOn/AndroidManifest.xml45
-rw-r--r--samples/browseable/AlwaysOn/_index.jd9
-rw-r--r--samples/browseable/AlwaysOn/res/layout/activity_main.xml28
-rw-r--r--samples/browseable/AlwaysOn/res/layout/rect_activity_main.xml59
-rw-r--r--samples/browseable/AlwaysOn/res/layout/round_activity_main.xml59
-rw-r--r--samples/browseable/AlwaysOn/res/values/dimens.xml23
-rw-r--r--samples/browseable/AlwaysOn/res/values/strings.xml23
-rw-r--r--samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java332
8 files changed, 578 insertions, 0 deletions
diff --git a/samples/browseable/AlwaysOn/AndroidManifest.xml b/samples/browseable/AlwaysOn/AndroidManifest.xml
new file mode 100644
index 000000000..c0fce9f27
--- /dev/null
+++ b/samples/browseable/AlwaysOn/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.wearable.wear.alwayson">
+
+ <uses-sdk android:minSdkVersion="20" android:targetSdkVersion="22" />
+
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
+
+ <uses-feature android:name="android.hardware.type.watch" />
+
+ <application
+ android:allowBackup="false"
+ android:label="@string/app_name">
+
+ <!--If you want your app to run on pre-22, then set required to false -->
+ <uses-library android:name="com.google.android.wearable" android:required="false" />
+
+ <activity android:name="com.example.android.wearable.wear.alwayson.MainActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleInstance"
+ android:configChanges="orientation|keyboardHidden"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
diff --git a/samples/browseable/AlwaysOn/_index.jd b/samples/browseable/AlwaysOn/_index.jd
new file mode 100644
index 000000000..b6057821b
--- /dev/null
+++ b/samples/browseable/AlwaysOn/_index.jd
@@ -0,0 +1,9 @@
+page.tags="AlwaysOn"
+sample.group=Wearable
+@jd:body
+
+<p>
+
+ Demonstrates a native Android Wear app using ambient screen support.
+ >
+ </p>
diff --git a/samples/browseable/AlwaysOn/res/layout/activity_main.xml b/samples/browseable/AlwaysOn/res/layout/activity_main.xml
new file mode 100644
index 000000000..d808e6bbb
--- /dev/null
+++ b/samples/browseable/AlwaysOn/res/layout/activity_main.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+<android.support.wearable.view.WatchViewStub
+ 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:id="@+id/watch_view_stub"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:rectLayout="@layout/rect_activity_main"
+ app:roundLayout="@layout/round_activity_main"
+ tools:context=".MainActivity"
+ tools:deviceIds="wear">
+</android.support.wearable.view.WatchViewStub>
diff --git a/samples/browseable/AlwaysOn/res/layout/rect_activity_main.xml b/samples/browseable/AlwaysOn/res/layout/rect_activity_main.xml
new file mode 100644
index 000000000..bfb814770
--- /dev/null
+++ b/samples/browseable/AlwaysOn/res/layout/rect_activity_main.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:paddingTop="@dimen/square_top_margin"
+ android:paddingLeft="@dimen/square_left_margin"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ tools:context=".MainActivity"
+ tools:deviceIds="wear_square">
+
+ <TextView
+ android:id="@+id/time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="24sp"
+ android:text="Hello, time!"/>
+
+ <TextView
+ android:id="@+id/time_stamp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, timestamp!"/>
+
+ <TextView
+ android:id="@+id/state"
+ android:textColor="@color/green"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, state!"/>
+
+ <TextView
+ android:id="@+id/update_rate"
+ android:textColor="@color/green"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, update rate!"/>
+
+ <TextView
+ android:id="@+id/draw_count"
+ android:textColor="@color/green"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, draw count!"/>
+</LinearLayout>
diff --git a/samples/browseable/AlwaysOn/res/layout/round_activity_main.xml b/samples/browseable/AlwaysOn/res/layout/round_activity_main.xml
new file mode 100644
index 000000000..8fa7a2df4
--- /dev/null
+++ b/samples/browseable/AlwaysOn/res/layout/round_activity_main.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:paddingTop="@dimen/round_top_margin"
+ android:paddingLeft="@dimen/round_left_margin"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity"
+ tools:deviceIds="wear_round">
+
+ <TextView
+ android:id="@+id/time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="24sp"
+ android:text="Hello, time!"/>
+
+ <TextView
+ android:id="@+id/time_stamp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, timestamp!"/>
+
+ <TextView
+ android:id="@+id/state"
+ android:textColor="@color/green"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, state!"/>
+
+ <TextView
+ android:id="@+id/update_rate"
+ android:textColor="@color/green"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, update rate!"/>
+
+ <TextView
+ android:id="@+id/draw_count"
+ android:textColor="@color/green"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello, draw count!"/>
+</LinearLayout>
diff --git a/samples/browseable/AlwaysOn/res/values/dimens.xml b/samples/browseable/AlwaysOn/res/values/dimens.xml
new file mode 100644
index 000000000..d44096abc
--- /dev/null
+++ b/samples/browseable/AlwaysOn/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="square_top_margin">24dp</dimen>
+ <dimen name="square_left_margin">16dp</dimen>
+
+ <dimen name="round_top_margin">34dp</dimen>
+ <dimen name="round_left_margin">34dp</dimen>
+</resources>
diff --git a/samples/browseable/AlwaysOn/res/values/strings.xml b/samples/browseable/AlwaysOn/res/values/strings.xml
new file mode 100644
index 000000000..7d4c2f63f
--- /dev/null
+++ b/samples/browseable/AlwaysOn/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name">Always On Example</string>
+ <string name="timestamp_label">Timestamp: %1$d</string>
+ <string name="mode_active_label">Active Mode (Handler)</string>
+ <string name="mode_ambient_label">Ambient Mode (Alarm)</string>
+ <string name="update_rate_label">Update rate: %1$d sec</string>
+ <string name="draw_count_label">Draw count: %1$d</string>
+</resources>
diff --git a/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java b/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java
new file mode 100644
index 000000000..51f287d81
--- /dev/null
+++ b/samples/browseable/AlwaysOn/src/com.example.android.wearable.wear.alwayson/MainActivity.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.wear.alwayson;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.wearable.activity.WearableActivity;
+import android.support.wearable.view.WatchViewStub;
+import android.util.Log;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Demonstrates support for Ambient screens by extending WearableActivity and overriding
+ * onEnterAmbient, onUpdateAmbient, and onExitAmbient.
+ *
+ * There are two modes (Active and Ambient). To trigger future updates (data/screen), we use a
+ * custom Handler for the "Active" mode and an Alarm for the "Ambient" mode.
+ *
+ * Why don't we use just one? Handlers are generally less battery intensive and can be triggered
+ * every second. However, they can not wake up the processor (common in Ambient mode).
+ *
+ * Alarms can wake up the processor (what we need for Ambient), but they struggle with quick updates
+ * (less than one second) and are much less efficient compared to Handlers.
+ *
+ * Therefore, we use Handlers for "Active" mode (can trigger every second and are better on the
+ * battery), and we use Alarms for "Ambient" mode (only need to update once every 20 seconds and
+ * they can wake up a sleeping processor).
+ *
+ * Again, the Activity waits 20 seconds between doing any processing (getting data, updating screen
+ * etc.) while in ambient mode to conserving battery life (processor allowed to sleep). If you can
+ * hold off on updates for a full minute, you can throw away all the Alarm code and just use
+ * onUpdateAmbient() to save even more battery life.
+ *
+ * As always, you will still want to apply the performance guidelines outlined in the Watch Faces
+ * documention to your app.
+ *
+ * Finally, in ambient mode, this Activity follows the same best practices outlined in the
+ * Watch Faces API documentation, e.g., keep most pixels black, avoid large blocks of white pixels,
+ * use only black and white, and disable anti-aliasing.
+ *
+ */
+public class MainActivity extends WearableActivity {
+
+ private static final String TAG = "MainActivity";
+
+ /** Custom 'what' for Message sent to Handler. */
+ private static final int MSG_UPDATE_SCREEN = 0;
+
+ /** Milliseconds between updates based on state. */
+ private static final long ACTIVE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(1);
+ private static final long AMBIENT_INTERVAL_MS = TimeUnit.SECONDS.toMillis(20);
+
+ /** Tracks latest ambient details, such as burnin offsets, etc. */
+ private Bundle mAmbientDetails;
+
+ private TextView mTimeTextView;
+ private TextView mTimeStampTextView;
+ private TextView mStateTextView;
+ private TextView mUpdateRateTextView;
+ private TextView mDrawCountTextView;
+
+ private final SimpleDateFormat sDateFormat =
+ new SimpleDateFormat("HH:mm:ss", Locale.US);
+
+ private volatile int mDrawCount = 0;
+
+
+ /**
+ * Since the handler (used in active mode) can't wake up the processor when the device is in
+ * ambient mode and undocked, we use an Alarm to cover ambient mode updates when we need them
+ * more frequently than every minute. Remember, if getting updates once a minute in ambient
+ * mode is enough, you can do away with the Alarm code and just rely on the onUpdateAmbient()
+ * callback.
+ */
+ private AlarmManager mAmbientStateAlarmManager;
+ private PendingIntent mAmbientStatePendingIntent;
+
+ /**
+ * This custom handler is used for updates in "Active" mode. We use a separate static class to
+ * help us avoid memory leaks.
+ */
+ private final Handler mActiveModeUpdateHandler = new UpdateHandler(this);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.d(TAG, "onCreate()");
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_main);
+
+ setAmbientEnabled();
+
+ mAmbientStateAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ Intent ambientStateIntent = new Intent(getApplicationContext(), MainActivity.class);
+
+ mAmbientStatePendingIntent = PendingIntent.getActivity(
+ getApplicationContext(),
+ 0 /* requestCode */,
+ ambientStateIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+
+ /** Determines whether watch is round or square and applies proper view. **/
+ final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
+ stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
+ @Override
+ public void onLayoutInflated(WatchViewStub stub) {
+
+ mTimeTextView = (TextView) stub.findViewById(R.id.time);
+ mTimeStampTextView = (TextView) stub.findViewById(R.id.time_stamp);
+ mStateTextView = (TextView) stub.findViewById(R.id.state);
+ mUpdateRateTextView = (TextView) stub.findViewById(R.id.update_rate);
+ mDrawCountTextView = (TextView) stub.findViewById(R.id.draw_count);
+
+ refreshDisplayAndSetNextUpdate();
+ }
+ });
+ }
+
+ /**
+ * This is mostly triggered by the Alarms we set in Ambient mode and informs us we need to
+ * update the screen (and process any data).
+ */
+ @Override
+ public void onNewIntent(Intent intent) {
+ Log.d(TAG, "onNewIntent(): " + intent);
+ super.onNewIntent(intent);
+
+ setIntent(intent);
+
+ refreshDisplayAndSetNextUpdate();
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG, "onDestroy()");
+
+ mActiveModeUpdateHandler.removeMessages(MSG_UPDATE_SCREEN);
+ mAmbientStateAlarmManager.cancel(mAmbientStatePendingIntent);
+
+ super.onDestroy();
+ }
+
+ /**
+ * Prepares UI for Ambient view.
+ */
+ @Override
+ public void onEnterAmbient(Bundle ambientDetails) {
+ Log.d(TAG, "onEnterAmbient()");
+ super.onEnterAmbient(ambientDetails);
+
+ /**
+ * In this sample, we aren't using the ambient details bundle (EXTRA_BURN_IN_PROTECTION or
+ * EXTRA_LOWBIT_AMBIENT), but if you need them, you can pull them from the local variable
+ * set here.
+ */
+ mAmbientDetails = ambientDetails;
+
+ /** Clears Handler queue (only needed for updates in active mode). */
+ mActiveModeUpdateHandler.removeMessages(MSG_UPDATE_SCREEN);
+
+ /**
+ * Following best practices outlined in WatchFaces API (keeping most pixels black,
+ * avoiding large blocks of white pixels, using only black and white,
+ * and disabling anti-aliasing anti-aliasing, etc.)
+ */
+ mStateTextView.setTextColor(Color.WHITE);
+ mUpdateRateTextView.setTextColor(Color.WHITE);
+ mDrawCountTextView.setTextColor(Color.WHITE);
+
+ mTimeTextView.getPaint().setAntiAlias(false);
+ mTimeStampTextView.getPaint().setAntiAlias(false);
+ mStateTextView.getPaint().setAntiAlias(false);
+ mUpdateRateTextView.getPaint().setAntiAlias(false);
+ mDrawCountTextView.getPaint().setAntiAlias(false);
+
+ refreshDisplayAndSetNextUpdate();
+ }
+
+ /**
+ * Updates UI in Ambient view (once a minute). Because we need to update UI sooner than that
+ * (every ~20 seconds), we also use an Alarm. However, since the processor is awake for this
+ * callback, we might as well call refreshDisplayAndSetNextUpdate() to update screen and reset
+ * the Alarm.
+ *
+ * If you are happy with just updating the screen once a minute in Ambient Mode (which will be
+ * the case a majority of the time), then you can just use this method and remove all
+ * references/code regarding Alarms.
+ */
+ @Override
+ public void onUpdateAmbient() {
+ Log.d(TAG, "onUpdateAmbient()");
+ super.onUpdateAmbient();
+
+ refreshDisplayAndSetNextUpdate();
+ }
+
+ /**
+ * Prepares UI for Active view (non-Ambient).
+ */
+ @Override
+ public void onExitAmbient() {
+ Log.d(TAG, "onExitAmbient()");
+ super.onExitAmbient();
+
+ /** Clears out Alarms since they are only used in ambient mode. */
+ mAmbientStateAlarmManager.cancel(mAmbientStatePendingIntent);
+
+ mStateTextView.setTextColor(Color.GREEN);
+ mUpdateRateTextView.setTextColor(Color.GREEN);
+ mDrawCountTextView.setTextColor(Color.GREEN);
+
+ mTimeTextView.getPaint().setAntiAlias(true);
+ mTimeStampTextView.getPaint().setAntiAlias(true);
+ mStateTextView.getPaint().setAntiAlias(true);
+ mUpdateRateTextView.getPaint().setAntiAlias(true);
+ mDrawCountTextView.getPaint().setAntiAlias(true);
+
+ refreshDisplayAndSetNextUpdate();
+ }
+
+ /**
+ * Loads data/updates screen (via method), but most importantly, sets up the next refresh
+ * (active mode = Handler and ambient mode = Alarm).
+ */
+ private void refreshDisplayAndSetNextUpdate() {
+
+ loadDataAndUpdateScreen();
+
+ long timeMs = System.currentTimeMillis();
+
+ if (isAmbient()) {
+ /** Prevents time drift while calculating trigger time (based on state). */
+ long delayMs = AMBIENT_INTERVAL_MS - (timeMs % AMBIENT_INTERVAL_MS);
+ long triggerTimeMs = timeMs + delayMs;
+
+ mAmbientStateAlarmManager.cancel(mAmbientStatePendingIntent);
+ mAmbientStateAlarmManager.setExact(
+ AlarmManager.RTC_WAKEUP,
+ triggerTimeMs,
+ mAmbientStatePendingIntent);
+
+ } else {
+ /** Prevents time drift. */
+ long delayMs = ACTIVE_INTERVAL_MS - (timeMs % ACTIVE_INTERVAL_MS);
+
+ mActiveModeUpdateHandler.removeMessages(MSG_UPDATE_SCREEN);
+ mActiveModeUpdateHandler.sendEmptyMessageDelayed(MSG_UPDATE_SCREEN, delayMs);
+ }
+ }
+
+ /**
+ * Updates display based on Ambient state. If you need to pull data, you should do it here.
+ */
+ private void loadDataAndUpdateScreen() {
+
+ mDrawCount += 1;
+ long currentTimeMs = System.currentTimeMillis();
+ Log.d(TAG, "loadDataAndUpdateScreen(): " + currentTimeMs + "(" + isAmbient() + ")");
+
+ if (isAmbient()) {
+
+ mTimeTextView.setText(sDateFormat.format(new Date()));
+ mTimeStampTextView.setText(getString(R.string.timestamp_label, currentTimeMs));
+
+ mStateTextView.setText(getString(R.string.mode_ambient_label));
+ mUpdateRateTextView.setText(
+ getString(R.string.update_rate_label, (AMBIENT_INTERVAL_MS / 1000)));
+
+ mDrawCountTextView.setText(getString(R.string.draw_count_label, mDrawCount));
+
+ } else {
+ mTimeTextView.setText(sDateFormat.format(new Date()));
+ mTimeStampTextView.setText(getString(R.string.timestamp_label, currentTimeMs));
+
+ mStateTextView.setText(getString(R.string.mode_active_label));
+ mUpdateRateTextView.setText(
+ getString(R.string.update_rate_label, (ACTIVE_INTERVAL_MS / 1000)));
+
+ mDrawCountTextView.setText(getString(R.string.draw_count_label, mDrawCount));
+ }
+ }
+
+ /**
+ * Handler separated into static class to avoid memory leaks.
+ */
+ private static class UpdateHandler extends Handler {
+ private final WeakReference<MainActivity> mMainActivityWeakReference;
+
+ public UpdateHandler(MainActivity reference) {
+ mMainActivityWeakReference = new WeakReference<MainActivity>(reference);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ MainActivity mainActivity = mMainActivityWeakReference.get();
+
+ if (mainActivity != null) {
+ switch (message.what) {
+ case MSG_UPDATE_SCREEN:
+ mainActivity.refreshDisplayAndSetNextUpdate();
+ break;
+ }
+ }
+ }
+ }
+} \ No newline at end of file