一些可穿戴應用在可見的情況下對使用者是非常有用的.比如跑步可以看跑的距離用的時間,或者記錄一些食品列表這樣在市場買東西的時候很方便.使你的應用可見對穿戴式設備的電池電量有影響,因此在添加這個特性到你的應用上時需要慎重考慮.
運行android 5.1或者更高版本的穿戴式設備允許應用保持在前臺,同時節省電池電量.在低功耗環境模式時穿戴式設備可以控制屏幕上顯示的內容.在環境和交互模式下的應用也被稱為永遠在線的應用.
在可穿戴應用中開啟環境模式
對于新的或者已經存在的工程,你可以升級開發工程配置使你的可穿戴式應用支持環境模式.當你完成這個配置之后,繼承WearableActivity這個類,它提供了使你的應用支持環境模式的所有方法.
配置開發工程
為了在你的應用中支持環境模式,需要升級SDK,并配置你的開發工程.
- 升級SDK到android 5.1或者更高的版本,它提供了使activity支持環境模式的API.關于如何更新SDK,可以看Adding SDK Packages
- 創建新的工程或者修改工程目標到android 5.1或者更高.即在清單文件中將targetSdkVersion設置為22或者更高
- 在清單文件中將minSdkVersion設置為20或者更高,
- 在
build.gradle
中添加或者更新依賴
dependencies {
...
compile 'com.google.android.support:wearable:1.2.0'
provided 'com.google.android.wearable:wearable:1.0.0'
}
注意
provided
依賴可以保證在運行時加載類支持環境模式同時在編譯時也支持.
- 在清單文件中添加分享庫條目
<application>
<uses-library android:name="com.google.android.wearable"
android:required="false" />
...
</application>
- 添加WAKE_LOCK權限
<uses-permission android:name="android.permission.WAKE_LOCK" />
創建支持環境模式的activity
為了確保你的activity支持環境模式,使用WearableActivity這個類和相關方法.
1.創建自己的activity繼承WearableActivity
2.在你的onCreate()方法中調用setAmbientEnabled()方法
public class MainActivity extends WearableActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setAmbientEnabled();
...
}
處理模式之間的轉換
當穿戴式設備展示時用戶在一段時間內沒有交互,或者用戶用手蓋住設備屏幕,系統應該切換activity的環境模式.在應用切換模式之后,更新UI減少電池消耗.你應該使用黑背景和較小的白圖形和文字.為了從交互模式切換到環境模式減少用戶的反應,盡量保持和原來模式下相同的放置.
注意:當你的應用運行在沒有物理按鈕的設備上時,控制你的應用不會切換模式.否則它會使應用退出顯示HOME頁面.這個行為可以保證用戶能優雅的退出應用.但是當屏幕超時時,這些設備仍然進入環境模式.
注意:在環境模式,交互元素是禁用的比如按鈕.如何在永遠生存的應用中設計用戶交互可以參考App Structure for Android Wear
當activity切換到環境模式時,系統會調用onEnterAmbient()在你的activity中.下面的代碼展示在切換到環境模式后如何將文本設為為白色和禁用抗鋸齒.
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
mStateTextView.setTextColor(Color.WHITE);
mStateTextView.getPaint().setAntiAlias(false);
}
當用戶敲擊屏幕或者舉起他們的手臂時,將會切換到交互模式.此時系統調用onExitAmbient()方法.下面的代碼展示修改文本為綠色同時使抗鋸齒可用.
@Override
public void onExitAmbient() {
super.onExitAmbient();
mStateTextView.setTextColor(Color.GREEN);
mStateTextView.getPaint().setAntiAlias(true);
}
在環境模式下更新內容
環境模式允許使用用戶的信息更新屏幕,但是需要小心的平衡更新.你應該慎重考慮重寫onUpdateAmbient()方法在環境模式每分鐘更新一次.如果你的應用要求更頻繁的更新,請考慮電池電量和頻繁更新兩者的權衡.為了省電,更新不能超過10s一次這個頻率.實際中你應該更少的更新你的應用.
每分鐘更新一次
為了保持電池電量大多數穿戴式應用在環境模式都不應該頻繁的更新屏幕.推薦在這個模式下每分鐘更新一次.系統提供一個回調方法onUpdateAmbient(),在這個推薦的頻率下更新屏幕.
@Override
public void onUpdateAmbient() {
super.onUpdateAmbient();
// Update the content
}
更加頻繁的更新
對于需要更加頻繁更新的應用,比如健身,計時.使用AlarmManager這個類的對象去喚醒進程完成更加頻繁的更新屏幕.
- 準備一個alarm管理器
- 設置更新頻率
- 如果當前是環境模式或者當切換到環境模式時調度下一次更新
- 當切換到交互模式或者activity停止時取消alarm
alarm 管理器可以被創建一個實例當他們被觸發的時候.為了防止這種情況,確保你的activity在清單文件中聲明了android:launchMode="singleInstance"
這個參數.
準備alarm管理器
alarm管理器啟動更新屏幕的隱式意圖并且調度下一次更新.下面的代碼展示了如何聲明一個alarm管理器.
private AlarmManager mAmbientStateAlarmManager;
private PendingIntent mAmbientStatePendingIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setAmbientEnabled();
mAmbientStateAlarmManager =
(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent ambientStateIntent =
new Intent(getApplicationContext(), MainActivity.class);
mAmbientStatePendingIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
ambientStateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
...
}
當alarm被觸發就會啟動一個隱式意圖,更新屏幕并調度下一次更新通過重寫onNewIntent()這個方法.
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
// Described in the following section
refreshDisplayAndSetNextUpdate();
}
更新屏幕并切調度更新數據
在這個示例activity中alarm管理器每20s觸發一次.當定時器計時,alarm觸發更新屏幕的意圖同時設置下一次更新的延遲.
下面的代碼展示了如何在屏幕上更新信息以及如何設置下一次更新.
// Milliseconds between waking processor/screen for updates
private static final long AMBIENT_INTERVAL_MS = TimeUnit.SECONDS.toMillis(20);
private void refreshDisplayAndSetNextUpdate() {
if (isAmbient()) {
// Implement data retrieval and update the screen for ambient mode
} else {
// Implement data retrieval and update the screen for interactive mode
}
long timeMs = System.currentTimeMillis();
// Schedule a new alarm
if (isAmbient()) {
// Calculate the next trigger time
long delayMs = AMBIENT_INTERVAL_MS - (timeMs % AMBIENT_INTERVAL_MS);
long triggerTimeMs = timeMs + delayMs;
mAmbientStateAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMs,
mAmbientStatePendingIntent);
} else {
// Calculate the next trigger time for interactive mode
}
}
調度下一次觸發更新
通過重寫onEnterAmbient()和onUpdateAmbient()這兩個方法當activity在進入環境模式或者activity已經是環境模式調度下次更新屏幕的報警器.
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
refreshDisplayAndSetNextUpdate();
}
@Override
public void onUpdateAmbient() {
super.onUpdateAmbient();
refreshDisplayAndSetNextUpdate();
}
注意:在這個例子中當屏幕需要更新是
refreshDisplayAndSetNextUpdate()
這個方法就會被調用.更多的例子可以參考AlwaysOn
取消定時器
當切換回道交互模式,在onExitAmbient()這個方法里取消定時器.
@Override
public void onExitAmbient() {
super.onExitAmbient();
mAmbientStateAlarmManager.cancel(mAmbientStatePendingIntent);
}
當用戶退出或者停止你的這個activity的時候需要在onDestroy()這個方法里取消定時器.
@Override
public void onDestroy() {
mAmbientStateAlarmManager.cancel(mAmbientStatePendingIntent);
super.onDestroy();
}
保持向后兼容
Activities that support ambient mode automatically fall back to normal activities on Wear devices that are on Android versions prior to 5.1 (API level 22). No special app code is required to support devices on these versions of Android. When the device switches to ambient mode, the device returns to the home screen and exits your activity.
如果你的應用不應在5.1之前的android版本安裝或者更新,在清單文件中設置如下配置.
<uses-library android:name="com.google.android.wearable" android:required="true" />