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

Этот код не разбудит устройство. Однако, когда я снова включаю его, они отображаются. Мне нужно, чтобы они включили экран. Можете ли вы помочь мне с этой проблемой?

3 ответа

Решение

У меня была похожая проблема, и решение было использовать 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(); как только ваша тревога сделала свое дело.

Скорее всего, будильник устройства просыпается. Тем не мение, AlarmManager широковещательные рассылки не включат экран, и устройство вполне может снова заснуть, прежде чем начнется ваша активность.

Вам нужно будет приобрести WakeLock в onReceive() перед звонком startActivity()и выпустить это WakeLock после того, как пользователь откликнется на вашу активность.

Для Служб (может быть, работает и для деятельности), расширьте ваш AlarmReceiver от WakefulBroadcastReceiver, он получает WAKE_LOCK для вас во время обработки намерения.

WakefulBroadcastReceiver документы - https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html

Руководство по поддержанию устройства в рабочем состоянии - https://developer.android.com/training/scheduling/wakelock.html

Другие вопросы по тегам