Android Wear циферблат часов вибрирует с выключенным экраном

У меня есть циферблат Android Wear, который я пытаюсь заставить часы вибрировать в час. Это работает за исключением случаев, когда экран часов выключен. Согласно операторам журнала, метод-обработчик вызывается каждую минуту, а метод chime вызывается в час. Если я отлаживаю по bluetooth с Мото 360, он работает даже с выключенным экраном. Если я устанавливаю релиз apk, он вибрирует только при включенном экране. Если экран выключен в верхней части часа, он не будет вибрировать, пока экран не включится снова. Я попытался получить замок для пробуждения до того, как вибрировать, но не повезло. Я думаю, что это может сработать, если я получу блокировку от пробуждения в onCreate и отпущу ее в onDestroy, но я бы предпочел не делать этого, чтобы сохранить заряд батареи. Еще один интересный момент заключается в том, что у меня есть еще одна функция, которая вибрирует при изменении определенных данных в API данных для носимых устройств и работает с выключенным экраном. Может быть, WearableListenerService будит часы достаточно долго, чтобы возникала вибрация. Что-то не так с моей логикой или это ограничение некоторых устройств Android Wear?

Обработчик изменения времени:

final Handler mUpdateTimeHandler = new Handler() {
    @Override
    public void handleMessage(Message message) {
        switch (message.what) {
            case MSG_UPDATE_TIME:
                MyLog.d("Time Tick Message Handler");
                doTimeTickStuff();

                long timeMs = System.currentTimeMillis();
                long delayMs = mInteractiveUpdateRateMs - (timeMs % mInteractiveUpdateRateMs);

                mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);

                break;
        }
    }
};

doTimeTickStuff ()

private void doTimeTickStuff()
{
    MyLog.d("timetickstuff");

    try {
        mCalendar = Calendar.getInstance();

        int currMin = mCalendar.get(Calendar.MINUTE);

        if (currMin == 0) {
            hourlyChime();
        }
    }
    catch(Exception ex)
    {
        MyLog.e(ex, "Error occurred in time tick handler");
    }

    if (mIsVisible) {
        invalidate();
    }
}

почасовой сигнал()

private void hourlyChime(){
    Vibrator v = (Vibrator) getBaseContext().getSystemService(VIBRATOR_SERVICE);
    if (v.hasVibrator()) {
        MyLog.d("vibrating");
        v.vibrate(1000);
    } 
    else {
        MyLog.d("No vibrator");
    }
}

Обновление Решение, которое работало, состояло в том, чтобы создать AlarmManager и зарегистрировать его с широковещательным приемником на циферблате onCreate, затем отменить регистрацию получателя в onDestroy

OnCreate()

@Override
public void onCreate(SurfaceHolder holder) {
    super.onCreate(holder);

    mChimeAlarmManager =
            (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    Intent ambientStateIntent = new Intent("packagename.HOURLY_CHIME");
    mChimePendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
        1234, ambientStateIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    WeatherTime.this.registerReceiver(chimeReceiver,
        new IntentFilter("packagename.HOURLY_CHIME"));

    long alarmMs = getMsTillNextHour() + System.currentTimeMillis();

    mChimeAlarmManager.setExact(
        AlarmManager.RTC_WAKEUP,
        alarmMs,
        mChimePendingIntent);
}

Приемник вещания

private BroadcastReceiver chimeReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent) {
        hourlyChime();

        mChimeAlarmManager.setExact(
            AlarmManager.RTC_WAKEUP,
            getMsTillNextHour() + System.currentTimeMillis(),
            mChimePendingIntent);
    }
};

OnDestroy()

@Override
public void onDestroy() {
    mChimeAlarmManager.cancel(mChimePendingIntent);

    super.onDestroy();
}

2 ответа

Решение

Когда часы переходят в режим окружающей среды, они погружаются в глубокий сон. В результате код, написанный с Handler не побежит. В результате вы должны использовать AlarmManager, Для получения подробной информации о том, как реализовать это, вы должны обратиться к разделу "Обновлять чаще" на этой странице о постоянно включенной функциональности Android Wear.

Что касается режима отладки Bluetooth, я подозреваю, что он работает, потому что часы никогда не уходят в глубокий сон. То же самое происходит, когда я разрабатываю приложения, когда часы пристыкованы.

Наконец, что касается частоты пробуждения, я думаю, что ваша функциональность в порядке, так как она срабатывает только раз в час. Для тех, кто читает это, пожалуйста, не будите часы чаще, чем раз в минуту, так как это серьезно повлияет на срок службы батареи. Всегда проверяйте циферблат на время автономной работы перед загрузкой в ​​Play Store.

В моем проекте я использую Alarm Manager с MyIntentService, расширяет IntentService. Чтобы разбудить (на экране) устройство в onHandleIntent, используйте следующее:

if (intent.getAction() != null) {
    tmp = intent.getAction();
    PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
    wakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), TAG);
    wakeLock.setReferenceCounted(true);
    if(!wakeLock.isHeld()) {
        wakeLock.acquire();
    }
}
Другие вопросы по тегам