在Doze中打电话时在后台运行应用程序

Sri*_*Sri 7 service android android-service android-doze

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

是否有办法即使手机是Doze我们可以运行任何网络插入问题的应用程序.我试图保持应用程序witelist但我需要设备根植.

adb shell dumpsys deviceidle whitelist +<Package Name>
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议我不间断地运行应用程序的最佳方法?

Mer*_*çen 5

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

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

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

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 {
            stopAutomationForegroundService();
            //startAlarmManagerLogic();
            return;
        }
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)


Dar*_*kin 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);
        }
}
Run Code Online (Sandbox Code Playgroud)

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

还,

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

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);
}
Run Code Online (Sandbox Code Playgroud)

并在清单中

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
Run Code Online (Sandbox Code Playgroud)

  • WakefulBroadcastReceiver 现已弃用 (2认同)