应用程序正在运行SDK 23及更高版本。我在完成任务并使用AlaramManager(setExactAndAllowWhileIdle)安排下一个任务后使用Service运行一些任务。这工作正常。如果手机连续闲置2或3天,则进入打盹模式。打盹模式后,应用程序丢失网络和唤醒锁也无法正常工作。
即使手机是Doze也有办法,我们可以运行任何网络插入问题的应用程序。我试图保持应用程序的网络,但我需要设备根植。
adb shell dumpsys deviceidle whitelist +<Package Name>
有谁能建议我哪种方式可以不间断地运行应用程序?
答案 0 :(得分:3)
您可以通过发送高pirority 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
答案 1 :(得分:3)
实际上没有运行前台服务就无法做到这一点。列入白名单可能不适合您的应用程序,即使它是,您要求用户给予您许可,从最终用户的角度来看,这可能被视为危险的东西。
然而,我有一个关于此的伎俩。听取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 {
stopAutomationForegroundService();
//startAlarmManagerLogic();
return;
}
AutomationReceiver.completeWakefulIntent(intent);
return;
}
}
答案 2 :(得分:2)
首先,不是直接呼叫AlarmManager
中的服务,而是呼叫广播接收者,然后呼叫该服务。
广播接收器应扩展WakefulBroadcastReceiver
而不是常规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);
}
}
WakefulBroadcastReceiver
和startWakefulService()
会让您的应用在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);
}
并在清单中
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
答案 3 :(得分:0)
在Android N之后,没有应用可以永远在后台运行。但是,您可以使用Firebase Job Dispatcher,它可以帮助您运行应用程序,即使它处于打盹模式。在Firebase Job Dispatcher的帮助下,如果条件匹配,您可以告诉系统您的应用应该在特定时间运行。