Андроид AlarmManager не пробуждает телефон вверх
Я хочу, чтобы активность отображалась в определенное время. Для этого я использую AlarmManager.
Он отлично работает, когда устройство бодрствует, но оно не разбудит его, если оно спит.
Мой код для настройки будильника:
Calendar alarmTime = Calendar.getInstance();
alarmTime.set(Calendar.HOUR_OF_DAY, alarm.hour);
alarmTime.set(Calendar.MINUTE, alarm.minute);
alarmTime.set(Calendar.SECOND, 0);
if (alarmTime.before(now))
alarmTime.add(Calendar.DAY_OF_MONTH, 1);
Intent intent = new Intent(ctxt, AlarmReceiver.class);
intent.putExtra("alarm", alarm);
PendingIntent sender = PendingIntent.getBroadcast(ctxt, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime.getTimeInMillis(), sender);
Мой радиоприемник:
@Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
final Alarm alarm = (Alarm) bundle.getSerializable("alarm");
Intent newIntent;
if (alarm.type.equals("regular")) {
newIntent = new Intent(context, RegularAlarmActivity.class);
} else if (alarm.type.equals("password")) {
newIntent = new Intent(context, PasswordAlarmActivity.class);
} else if (alarm.type.equals("movement")) {
newIntent = new Intent(context, MovementAlarmActivity.class);
} else {
throw new Exception("Unknown alarm type");
}
newIntent.putExtra("alarm", alarm);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
Log.e("AlarmReceiver", Log.getStackTraceString(e));
}
}
Этот код не активирует устройство. Однако, когда я верну его обратно, они отображаются. Мне нужно заставить их включить экран. Можете ли вы помочь мне с этой проблемой?
Ответы
Ответ 1
У меня была аналогичная проблема, и решение было использовать WakeLocker. Это должно быть сделано (желательно как 1-е место в приемнике), или устройство проснется при получении сигнала тревоги, но снова заснет перед context.startActivity(newIntent)
; называется.
(Я также наблюдал поведение, когда этого не происходит, поэтому он кажется немного произвольным)
Итак, легкий и быстрый ответ:
Создайте новый класс под названием WakeLocker с помощью этого исходного кода:
package mypackage.test;
import android.content.Context;
import android.os.PowerManager;
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, MainActivity.APP_TAG);
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
а в вашем приемнике вызывают WakeLocker.acquire(context);
как первое.
Дополнительно: было бы аккуратно позвонить WakeLocker.release();
после того, как ваш будильник выполнит свою работу.
Ответ 2
Скорее всего, будильник пробуждает устройство. Тем не менее, трансляции AlarmManager
не включат экран, и устройство может снова заснуть перед началом вашей активности.
Вам нужно будет приобрести WakeLock
в onReceive()
перед вызовом startActivity()
и освободить это WakeLock
после того, как пользователь ответит на вашу активность.
Ответ 3
Для служб (возможно, для работы также), расширьте свой AlarmReceiver с WakefulBroadcastReceiver
, он приобретает WAKE_LOCK для вас, пока намерение обрабатывается.
WakefulBroadcastReceiver
docs -
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html
Поддержание проводного руководства -
https://developer.android.com/training/scheduling/wakelock.html