【发布时间】:2014-08-22 15:37:13
【问题描述】:
我有一个向 Wear 发送消息的手持应用程序。当 Wear 应用收到消息时,它会启动一个 Activity。 Activity 会在启动后不久根据其他因素自行更新。
如果 Wear 设备在收到消息时完全处于唤醒状态,这一切都没有问题。
但是,如果 Wear 设备在收到传入消息时处于睡眠状态,则会发生以下三种情况之一:
- 根据我在日志中看到的内容,Activity 正在启动,但在 Wear 设备屏幕上不可见
- Activity 启动并且可见 - 但启动后更新没有发生
- 发布后更新仅部分发生
最常见的结果是#3。例如,如果 XML 有一个开始显示“msg”的文本字段,并且发布后更新将此文本更改为“收到的消息” - 实际显示的是“mess”。在这种情况下,触摸屏幕会唤醒设备,然后才会完成 UI 更新。
这一切的实现包括一个 WearableListenerService 子类:
public class ListenerService extends WearableListenerService {
@Override
public void onMessageReceived(MessageEvent messageEvent) {
Intent i = new Intent(this, MessageReceivedActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}
出于这个(简化)示例的目的,我让 Activity 启动一个线程,等待 1 秒,然后进行 UI 更新:
public class MessageReceivedActivity extends Activity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_received);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
new UpdateTask().execute();
}
});
}
private class UpdateTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(1000);
}
catch (Exception ex) {
Log.e(TAG, "UpdateTask.doInBackground: error sleeping", ex);
}
return null;
}
protected void onPostExecute(Void result) {
mTextView.setText("something else");
}
}
}
我试过以下,都没有效果:
- 在 Activity 的布局 XML 中添加了 android:keepScreenOn="true"
- 在Activity的onCreate中添加了getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- 在 ListenerService.onMessageReceived 中获得了 WakeLock(出于测试目的,直到 MessageReceivedActivity.onDestroy 才发布)
似乎因为 Wear 仅因传入消息而唤醒,所以它会在 UI 线程空闲的那一刻重新进入睡眠状态 - 即使有 WakeLock。还有其他方法可以让 Wear 保持清醒吗?
【问题讨论】:
-
android:keepScreenOn="true" 对我来说非常有效,但与您的设置不同的是,我没有从服务启动 Activity。在我的应用中,Service 会发布一个通知,当用户点击通知中的某个操作时,会启动一个布局中包含 android:keepScreenOn="true" 的 Activity。
标签: android wear-os android-wake-lock