Android Wear отключается при запуске Activity из WearableListenerService

У меня есть портативное приложение, которое отправляет сообщение в Wear. Когда приложение Wear получает сообщение, оно запускает Activity. Затем действие обновляется вскоре после запуска на основе других факторов.

Если устройство Wear полностью проснулось, когда оно получает сообщение, все это работает без проблем.

Однако, если устройство Wear спит при получении входящего сообщения, происходит одно из трех:

  1. Основываясь на том, что я вижу в журнале, Activity запускается, но не отображается на экране устройства Wear
  2. Активность запускается и видна - но обновление после запуска не происходит
  3. Обновление после запуска происходит только частично

Наиболее распространенным результатом является № 3. Например, если в XML есть текстовое поле, которое начинается с сообщения "msg", а обновление после запуска изменяет этот текст на "сообщение получено" - на самом деле отображается "mes". В этом случае прикосновение к экрану пробуждает устройство и только после этого оно завершает обновление пользовательского интерфейса.

Реализация всего этого включает подкласс 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 секунду и затем обновляет пользовательский интерфейс:

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");
        }
    }
}

Я пробовал следующее, все безрезультатно:

  • добавлен android:keepScreenOn="true" в XML макета Действия
  • добавлен getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) в onCreate действия
  • приобрел WakeLock в ListenerService.onMessageReceived (для целей тестирования не выпускается до MessageReceivedActivity.onDestroy)

Похоже, что из-за того, что Wear только проснулся из-за входящего сообщения, он возвращается в спящий момент, когда поток пользовательского интерфейса становится бездействующим - даже несмотря на WakeLock. Есть ли какой-нибудь другой способ сказать Уира, чтобы он не спал?

1 ответ

Ситуация, которую вы описываете, заключается в том, что ваша служба запускается, что вызывает пробуждение ЦП, но затем ЦП возвращается в спящий режим, прежде чем у вас есть время для завершения всех ваших операций.

Решением этой проблемы является использование Wakelock, чтобы не дать процессору спать до завершения работы. Можете ли вы опубликовать свой код Wakelock?

Также убедитесь, что у вас есть разрешение.;)

<uses-permission android:name="android.permission.WAKE_LOCK" />
Другие вопросы по тегам