Android 受打盹模式影响的服务

Android 受打盹模式影响的服务,android,broadcastreceiver,delay,foreground-service,doze,Android,Broadcastreceiver,Delay,Foreground Service,Doze,我的报警应用程序一直很晚,虽然我正在从广播接收器启动前台服务,并且服务的onCreate()及时调用,但是onStartCommand()被延迟调用(有时),我猜是因为手机在执行之前又打瞌睡了 从Log.d中可以看到,服务及时启动,并及时调用PlayerActivity,但在本例中,此服务实际上是在1:40分钟后启动的。 另外,在随机延迟时间过去之前,服务不会进入前台,也不会启动流媒体音乐(维护窗口?) 我们应该如何让设备保持足够长的清醒时间,以实际启动前台服务并及时进入前台? 我正在使用set

我的报警应用程序一直很晚,虽然我正在从
广播接收器
启动
前台服务
,并且
服务的
onCreate()
及时调用,但是
onStartCommand()
被延迟调用(有时),我猜是因为手机在执行之前又打瞌睡了

从Log.d中可以看到,服务及时启动,并及时调用PlayerActivity,但在本例中,此服务实际上是在1:40分钟后启动的。 另外,在随机延迟时间过去之前,服务不会进入前台,也不会启动流媒体音乐(维护窗口?)

我们应该如何让设备保持足够长的清醒时间,以实际启动前台服务并及时进入前台?

我正在使用
setExactAndAllowHileIDLE()
调用AlarmReceiver-这在100%的情况下都能正常工作。延迟发生在启动服务之后

我是否应该提前15分钟启动服务,以确保它在实际警报时间进入前台,并在实际警报时间启动流媒体音乐和呼叫活动

广播接收机

public class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Log.d("Ben", "Alarmreceiver HELLO");

    String label = context.getText(R.string.defaultLabel).toString();
    int id = 1909;

    Bundle extras = intent.getExtras();

    if (extras != null) {

// kill running alarm activity
        if (extras.containsKey("autoKill")) {

            Log.d("Ben", "AlarmReceiver killing running alarm NOW.");

            Intent bc = new Intent("PLAYER_STOP_SELF");
            LocalBroadcastManager.getInstance(context).sendBroadcast(bc);

            context.stopService(new Intent(context, StreamService.class));
            return;
        }

        label = extras.getString("label");
        id = extras.getInt("id");
    }

    Log.d("Ben", "AlarmReceiver ok!");


// CALC NEXT ALARM and start StreamingService...

    if (Build.VERSION.SDK_INT >= 26) {
        context.startForegroundService(new Intent(context, StreamService.class));
        context.startForegroundService(new Intent(context, CalcNextAlarmService.class));
        Log.d("Ben", "SDK >= 26 *** context.startForegroundServices");
    }
    else {
        context.startService(new Intent(context, StreamService.class));
        context.startService(new Intent(context, CalcNextAlarmService.class));
        Log.d("Ben", "SDK < 26 *** context.startServices");
    }
}
相应的日志。d:

07-14 14:30:01.335 D/Ben: Alarmreceiver HELLO
07-14 14:30:01.364 D/Ben: AlarmReceiver ok! (label: Alarm 1 - id: 10001)
07-14 14:30:01.372 D/Ben: SDK < 26 *** context.startServices
07-14 14:30:01.378 D/Ben: StreamService calling PlayerActivity now...
07-14 14:31:41.116 D/Ben: StreamService onStartCommand
07-14 14:31:41.224 D/Ben: StreamService wakeLock.isHeld()
    StreamService wifiLock.isHeld()
    *** onStartCommand ELSE ***
07-14 14:31:41.227 D/Ben: preparing player - start streaming in 2 seconds...
07-14 14:31:41.365 D/Ben: wakeLock.isHeld()
    wifiLock.isHeld()
07-14 14:31:41.366 D/Ben: PlayerActivity.onCreate()
07-14 14:31:43.229 D/Ben: Start Streaming now! (normal alarm)
07-14 14:31:43.241 D/Ben: buffering
07-14 14:31:43.242 D/Ben: buffering
07-14 14:31:44.345 D/Ben: ready
07-1414:30:01.335d/Ben:Alarmreceiver你好
07-14 14:30:01.364 D/Ben:警报接收器正常!(标签:报警1-id:10001)
07-14 14:30:01.372 D/Ben:SDK<26***context.startServices
07-14 14:30:01.378 D/Ben:StreamService正在呼叫PlayerActivity。。。
07-14 14:31:41.116 D/Ben:StreamService启动命令
07-14 14:31:41.224 D/Ben:StreamService wakeLock.ishelld()
StreamService wifiLock.ishelld()
***onStartCommand-ELSE***
07-14 14:31:41.227 D/Ben:正在准备播放机-2秒钟后开始播放流媒体。。。
7-14 14:31:41.365本:韦克洛克
wifiLock.isHeld()
07-14 14:31:41.366 D/Ben:PlayerActivity.onCreate()
07-14 14:31:43.229丁/本:现在开始播放流媒体!(正常报警)
07-14 14:31:43.241数据/本:缓冲
07-14 14:31:43.242数据/本:缓冲
07-14 14:31:44.345丁/本:准备好了吗
警报在95%的使用时间内都能正常工作,但有时会出现打瞌睡,并延迟1-15分钟启动警报-我已经调试了2个多星期了,重写了整个服务和接收器类2次,开始变得疯狂,请帮助

编辑

我最终使用了一个wakeful BroadcastReceiver和一个wakeful服务(对于所有API<26),然后它负责相应地调用其他服务(我以前在AlarmReceiver中所做的-对于API>=26,现在仍然这样做)

到目前为止,它似乎工作良好-只有在我的一个测试设备上运行的沿袭警报有时会很晚,在我自己的日常使用的手机上,我也运行沿袭,但它只是做得很好。也许SGS 4 mini太旧了(我真的不相信这一点,但只要没有人抱怨,我就不得不假设它能按预期为他们工作)


谢谢你的帮助@Elletlar。

打瞌睡没有帮助。但这种实现在预睡眠设备上也不起作用,因为startService也可以在这些设备上调用onStartCommand之前休眠。在API 22之前的设备上,可以通过在广播接收器中获取静态部分唤醒锁并将其从服务中释放来处理。对于API22-25设备,它是通过使用WakefulBroadcastReceiver来处理的。如果您阅读了本文档的底部部分,它将解释您的pre-26 implementation:Now for 26+doze设备需要进行的改进。如果您的服务处于单独的流程中,这可能会很好。这是谷歌应用程序的标准做法,因为它可以防止用户界面的资源被加载到内存中,从而导致服务流程膨胀,但这也导致谷歌忽略了一些设备上的一个严重缺陷,即在主进程中运行的前台服务可能会被打瞌睡。“当警报发出时,该应用程序还将被添加到系统的临时白名单中约10秒,以允许该应用程序获取更多的唤醒锁,从而完成其工作。”2。两次瞌睡警报之间的最小间隔通常为9分钟。这对于startForegroundService可能很有用,必须具有通知通道和非零ID。感谢提供详细信息。我阅读了关于单独进程的内容,但不确定如何做,我正要在清单中指定它,但我完全可以自由选择进程名称吗?没有通过谷歌找到有用的答案。不同的包名?我可以用“mySeparateProcess”作为进程名吗现在,睡前设备对我来说已经工作了7个多月了,我想我把它们排除在外,只为安卓6+做了一些改变——由于不受欢迎,我想避免wakeful BR,但现在我将为sdk 22-25做一次尝试。
07-14 14:30:01.335 D/Ben: Alarmreceiver HELLO
07-14 14:30:01.364 D/Ben: AlarmReceiver ok! (label: Alarm 1 - id: 10001)
07-14 14:30:01.372 D/Ben: SDK < 26 *** context.startServices
07-14 14:30:01.378 D/Ben: StreamService calling PlayerActivity now...
07-14 14:31:41.116 D/Ben: StreamService onStartCommand
07-14 14:31:41.224 D/Ben: StreamService wakeLock.isHeld()
    StreamService wifiLock.isHeld()
    *** onStartCommand ELSE ***
07-14 14:31:41.227 D/Ben: preparing player - start streaming in 2 seconds...
07-14 14:31:41.365 D/Ben: wakeLock.isHeld()
    wifiLock.isHeld()
07-14 14:31:41.366 D/Ben: PlayerActivity.onCreate()
07-14 14:31:43.229 D/Ben: Start Streaming now! (normal alarm)
07-14 14:31:43.241 D/Ben: buffering
07-14 14:31:43.242 D/Ben: buffering
07-14 14:31:44.345 D/Ben: ready