首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Doze中运行手机后台应用程序

在Doze中运行手机后台应用程序
EN

Stack Overflow用户
提问于 2017-04-20 01:38:24
回答 4查看 6.6K关注 0票数 7

应用程序正在运行SDK 23及更高版本。在完成任务并使用AlaramManager (setExactAndAllowWhileIdle)调度下一个任务之后,我正在使用服务运行一些任务。这很好用。如果手机连续闲置2或3天,那么它就会进入Doze模式。在Doze模式下,应用程序松掉网络和唤醒也不起作用。

有没有办法,即使手机是Doze,我们可以运行任何网络插入式的应用程序,我试着保持应用程序的机智,但我需要设备的根。

代码语言:javascript
复制
adb shell dumpsys deviceidle whitelist +<Package Name>

有人能建议我哪种不间断地运行应用程序的最佳方式吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-29 10:25:08

Edit-WakefulBroadcastReceiver现在被弃用了

首先,不直接调用AlarmManager中的服务,而是调用广播接收器,然后广播接收器调用该服务。

广播接收器应该扩展WakefulBroadcastReceiver而不是普通的BroadcastReceiver

然后,让广播接收器调度一个新的警报,使用startWakefulService()而不是startService()启动服务。

代码语言:javascript
复制
public class MyAwesomeReceiver extends WakefulBroadcastReceiver {
int interval=2*60*60*1000;
    @Override
    public void onReceive(Context context, Intent intent) {

        Intent serviceIntent = new Intent(context, MyAwesomeService.class);
        Intent receiverIntent = new Intent(context, MyAwesomeReceiver.class);

        PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 11, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+interval,alarmIntent);
        startWakefulService(context, serviceIntent);
        }
}

WakefulBroadcastReceiverstartWakefulService()会让你的应用程序有10秒的时间来做它需要做的事情。

另外,

您可以随时要求用户让您的应用程序忽略电池优化功能,使用-

代码语言:javascript
复制
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
Intent intent=new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
     intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
}
else {
     intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
     intent.setData(Uri.parse("package:" + getPackageName()));
     startActivity(intent);
}

在舱单上

代码语言:javascript
复制
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
票数 3
EN

Stack Overflow用户

发布于 2017-04-25 12:38:25

实际上,如果不运行前台服务,就无法做到这一点。在白名单中列出可能不适合您的应用程序,即使是这样,您也会请求用户给予您许可,从最终用户的角度来看,这可能是一种危险的东西。

不过,我对此有个窍门。收听android的广播,当你听到该设备进入打瞌睡模式时,启动前台服务。在大多数情况下,用户将无法看到前景通知图像,也不知道您正在运行服务。因为设备处于打瞌睡模式,这意味着它在某个用户不看的地方是稳定的。所以你可以做任何需要的事。

当打瞌睡模式结束时,您也可以收听发送的广播。当这种情况发生时,停止前台服务,并与警报管理人员一起按照正常的逻辑工作。

代码语言:javascript
复制
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if(intent.getAction().equals("android.os.action.DEVICE_IDLE_MODE_CHANGED")){
        if (pm.isDeviceIdleMode()) {
            startForegroundService();
            //stopAlarmManagerLogic();
        } else {
            stopForegroundService();
            //startAlarmManagerLogic();
            return;
        }
        return;
    }
}
票数 8
EN

Stack Overflow用户

发布于 2017-04-24 19:08:37

您可以要求android白名单您的应用程序打瞌睡模式,发送高盗版GCM信息。但是请记住,这可能会使你的应用程序不被Google Play批准:

代码语言:javascript
复制
Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (pm.isIgnoringBatteryOptimizations(packageName))
    intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
else {
    intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intent.setData(Uri.parse("package:" + packageName));
}
context.startActivity(intent);

https://developer.android.com/training/monitoring-device-state/doze-standby.html#whitelisting-cases

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43508748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档