7

应用程序正在运行 SDK 23 及更高版本。在完成任务并使用 AlaramManager (setExactAndAllowWhileIdle) 安排下一个任务后,我正在使用 Service 运行一些任务。这工作正常。如果手机连续闲置 2 或 3 天,则进入打盹模式。打盹模式后,应用程序失去网络和唤醒锁也无法正常工作。

有没有办法即使手机是打瞌睡的,我们可以在任何网络插入问题的情况下运行应用程序。我试图保留应用程序 witelist,但我需要设备被植根。

adb shell dumpsys deviceidle whitelist +<Package Name>

谁能建议我不间断地运行应用程序的最佳方式?

4

4 回答 4

8

实际上,如果不运行前台服务,就没有办法做到这一点。列入白名单可能不适合您的应用程序,即使是,您也要求用户授予您权限,从最终用户的角度来看,这可能被视为危险的事情。

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

您还可以收听打盹模式完成时发送的广播。发生这种情况时,请停止前台服务并使用警报管理器按照您的正常逻辑工作。

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;
    }
}
于 2017-04-25T12:38:25.357 回答
3

编辑-WakefulBroadcastReceiver现在已弃用

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

广播接收器应该扩展 aWakefulBroadcastReceiver而不是常规的BroadcastReceiver

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

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

并且会让你的应用有一个 10 秒的窗口来让你做它需要做的事情WakefulBroadcastReceiverstartWakefulService()

还,

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

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

并在清单中

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
于 2017-04-29T10:25:08.680 回答
3

您可以通过发送高优先级 GCM 消息请求 android 将您的应用列入打盹模式白名单。但请记住,这可能会使您的应用未被 Google Play 批准:

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

于 2017-04-24T19:08:37.390 回答
0

在 Android N 之后,没有任何应用程序可以永远在后台运行。但是,您可以使用 Firebase Job Dispatcher,即使它处于打盹模式,它也可以帮助您运行您的应用程序。在Firebase Job Dispatcher的帮助下,您可以告诉系统如果提供的条件匹配,您的应用应该在特定时间运行。

于 2017-04-28T05:30:43.117 回答