我想在某个时间显示某个活动。为此,我使用的是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));
}
}
此代码不会唤醒设备。但是,当我再次将其关闭时,它们会显示出来。我需要让他们打开屏幕。你能帮我解决这个问题吗?
答案 0 :(得分:56)
我有类似的问题,解决方案是使用WakeLocker。应该这样做(最好是接收器中的第一件事),或者设备将在收到警报时醒来,但会在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();
。
答案 1 :(得分:30)
最有可能的是,闹钟正在唤醒设备。但是,AlarmManager
广播不会打开屏幕,设备可能会在您的活动开始之前重新入睡。
在致电WakeLock
之前,您需要在onReceive()
中获取startActivity()
,并在用户回复您的活动后发布WakeLock
。
答案 2 :(得分:8)
对于服务(也可以用于活动),从WakefulBroadcastReceiver
扩展你的AlarmReceiver,它会在处理意图时为你获取WAKE_LOCK。
WakefulBroadcastReceiver
文档 -
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html
保持设备清醒指南 - https://developer.android.com/training/scheduling/wakelock.html