AlarmManager:关闭屏幕时删除了待处理的意图

时间:2016-11-25 07:30:22

标签: android alarmmanager

docs之后我设法用AlarmManager设置闹钟,一旦我不关闭手机的屏幕,它就能很好地工作。

这是屏幕打开时adb shell dumpsys alarm的输出:

Batch{1304da7 num=1 start=190708622 end=190708622 flgs=0x1}:
    RTC_WAKEUP #0: Alarm{f642254 type 0 when 1480059825231 alarm.poc.app}
      tag=*walarm*:alarm.poc.app.ACTION
      type=0 whenElapsed=+5m49s424ms when=2016-11-25 02:43:45
      window=0 repeatInterval=0 count=0 flags=0x1
      operation=PendingIntent{f78d3a6: PendingIntentRecord{f52e1e7 alarm.poc.app broadcastIntent}}

关闭屏幕几秒钟后,我的警报从命令输出中消失,永远不会被调用(它可以在屏幕上运行)。

所以我有这些问题:

  • 还有哪些其他应用可以让闹钟保持活动状态?我可以在adb shell dumpsys alarm的输出中看到,即使我清除了所有最近的应用,也无法删除大量其他闹钟。我可以看到Whatsapp,谷歌和许多其他随机应用程序的警报。
  • 也许所有这些应用都有前台服务?我问这个是因为我设法“解决”问题,创建一个令人讨厌的前台服务,每隔5秒就会写一些内容到日志中。看起来有一个正在运行的服务可以防止这个问题,但它完全是丑陋的,我觉得保持处理器始终处于唤醒状态并不是一个好主意。

这是我设置闹钟的方法:

AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);    
Intent intent = new Intent(AlarmReceiver.MY_ACTION);
intent.putExtra("text", editText.getText().toString());
PendingIntent pending = PendingIntent.getBroadcast(this, 42,
    intent, PendingIntent.FLAG_UPDATE_CURRENT);
// also tried with getBroadcast(this, 0, intent, 0)
manager.setExact(AlarmManager.RTC_WAKEUP, millis, pending);

我有一个WakefulBroadcastReceiver(没有屏幕关闭):

public void onReceive(Context context, Intent receivedIntent) {
  if (MY_ACTION.equals(receivedIntent.getAction())) {
    System.out.println("good!!!");
    String text = receivedIntent.getStringExtra("text");
    Intent intentService = new Intent(context, TestService.class);
    intentService.putExtra("text", text);
    startWakefulService(context, intentService);
    System.out.println("service started");
  }
}

清单:

...
<uses-permission android:name="android.permission.WAKE_LOCK"/>
...
  <service android:name="alarm.poc.app.TestService"
      android:exported="false"/>

  <receiver android:name="alarm.poc.app.AlarmReceiver"
            android:process=":remote">
    <intent-filter>
      <action android:name="alarm.poc.app.ACTION"/>
    </intent-filter>
  </receiver>
...

我正在使用棉花糖手机测试,minSdkVersion 19和targetSdkVersion 24

2 个答案:

答案 0 :(得分:1)

我找到了问题的答案。

问题在于我正在华为手机上进行测试,并且这些功能带有“受保护的应用程序”功能,可以在屏幕关闭时杀死所有应用程序,但配置为受保护的应用程序除外。

dumpsys输出中有这么多其他应用程序的原因是默认情况下华为是一些已被“保护”的热门应用程序。

我发现的唯一解决方案是检测华为手机并要求用户保护该应用。这个答案涵盖了这种方法:

"Protected Apps" setting on Huawei phones, and how to handle it

答案 1 :(得分:1)

收到警报时,您应该使用WakeLocker唤醒设备。使用以下源代码创建一个名为WakeLocker的新类:

package your.packagename;

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();

您还需要获得许可:<uses-permission android:name="android.permission.WAKE_LOCK" />