当应用程序在后台被杀死且设备被锁定时,警报管理器将无法工作
Alarm Manager won't work when the app is killed in the background and device is locked
卡在这个状态很久了...
我想使用闹钟管理器在特定时间显示通知,现在它在下面列出的情况下工作:
- 当应用程序在后台运行时,无论设备是否锁定,都会在正确的时间显示通知。
- 应用程序在后台被杀死后,设备未锁定时我仍然会收到正确的通知,但是当设备锁定时情况就不对了,我无法收到任何通知。
这是代码 AlarmReceiver.java,所有需要的权限已添加到 AndroidManifest.xml 中:
@Override
public void onReceive(Context context, Intent intent) {
WakeLocker.acquire(context);
String action = intent.getAction();
Log.d(TAG, action); //when app is killed and device is locked, no info is shown at the logcat
if (ACTION_ALARM.equals(action)) {
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2 * 1000);
notify(context, "Jello!");
}
WakeLocker.release();
}
public static void alarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction(ACTION_ALARM);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5 * 1000, pi);
} else {
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5 * 1000, pi);
}
}
private void notify(Context context, String msg) {
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, InfoActivity.class), 0);
Notification notification =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(context.getString(R.string.alarm))
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setAutoCancel(true)
.setContentIntent(contentIntent).build();
notificationManager.notify(1, notification);
}
添加的权限:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
有一天我遇到了类似的问题,并在网上找到了一个解决方案,即在调用 broadcastreceiver 时唤醒 phone。
因此,请尝试创建此 class,并在调用广播接收器时调用 MyWakeLock.acquire()
。当你完成你的警报时,你也应该调用 MyWakeLock.release()
。
package your.package.name;
import android.content.Context;
import android.os.PowerManager;
public abstract class MyWakeLock {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context c) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) c.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;
}
}
我刚刚找到解决方案,将名为 FLAG_INCLUDE_STOPPED_PACKAGES 的标志设置为警报的意图,事情就会顺利进行。
这是Android Developers
中的插图
我遇到了这个问题,最后发现错误的targetSdkVersion is above 22 and no handle permission。
设置 targetSdkVersion 22 并工作 ^_^
卡在这个状态很久了...
我想使用闹钟管理器在特定时间显示通知,现在它在下面列出的情况下工作:
- 当应用程序在后台运行时,无论设备是否锁定,都会在正确的时间显示通知。
- 应用程序在后台被杀死后,设备未锁定时我仍然会收到正确的通知,但是当设备锁定时情况就不对了,我无法收到任何通知。
这是代码 AlarmReceiver.java,所有需要的权限已添加到 AndroidManifest.xml 中:
@Override
public void onReceive(Context context, Intent intent) {
WakeLocker.acquire(context);
String action = intent.getAction();
Log.d(TAG, action); //when app is killed and device is locked, no info is shown at the logcat
if (ACTION_ALARM.equals(action)) {
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2 * 1000);
notify(context, "Jello!");
}
WakeLocker.release();
}
public static void alarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction(ACTION_ALARM);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5 * 1000, pi);
} else {
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5 * 1000, pi);
}
}
private void notify(Context context, String msg) {
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, InfoActivity.class), 0);
Notification notification =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(context.getString(R.string.alarm))
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setAutoCancel(true)
.setContentIntent(contentIntent).build();
notificationManager.notify(1, notification);
}
添加的权限:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
有一天我遇到了类似的问题,并在网上找到了一个解决方案,即在调用 broadcastreceiver 时唤醒 phone。
因此,请尝试创建此 class,并在调用广播接收器时调用 MyWakeLock.acquire()
。当你完成你的警报时,你也应该调用 MyWakeLock.release()
。
package your.package.name;
import android.content.Context;
import android.os.PowerManager;
public abstract class MyWakeLock {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context c) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) c.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;
}
}
我刚刚找到解决方案,将名为 FLAG_INCLUDE_STOPPED_PACKAGES 的标志设置为警报的意图,事情就会顺利进行。 这是Android Developers
中的插图我遇到了这个问题,最后发现错误的targetSdkVersion is above 22 and no handle permission。 设置 targetSdkVersion 22 并工作 ^_^