2017-04-20 42 views
6

應用程序正在運行SDK 23及更高版本。我在完成任務後使用Service運行一些任務,並使用AlaramManager(setExactAndAllowWhileIdle)安排下一個任務。這工作正常。如果手機連續閒置2或3天,則進入打盹模式。打盹模式後,丟失網絡和喚醒鎖的應用程序也無法正常工作。在打電話時在後臺運行應用程序

即使手機打瞌睡我們是否可以運行與任何網絡干預問題的應用程序。我試圖保持應用程序的列表,但我需要設備根植。

adb shell dumpsys deviceidle whitelist +<Package Name> 

任何人都可以建議我最好的方式來運行應用程序沒有中斷?

回答

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

WakefulBroadcastReceiverstartWakefulService()將讓您的應用程序10秒作爲一個窗口,讓做什麼就需要啓動服務做。

此外,

您可以隨時詢問用戶,讓您的應用程序忽略電池優化功能using-即使不

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> 
1

您可以通過發送高級GCM消息來請求android將您的應用列入白名單。但要記住,這可能使您的應用程序沒有批准由谷歌播放:

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

+0

這很好經Google Play批准。是FCM高優先級消息設備可以從Doze中喚醒多久?我已經實現了這一點。上面的代碼來自應用程序列表。我如何確認? – Sri

+1

@srikanth代碼在運行時要求「ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS」權限。如果你在這裏閱讀:https://developer.android.com/training/monitoring-device-state/doze-standby.html#support_for_other_use_cases,你會看到他們的文檔說,它允許你再次訪問部分喚醒鎖,你的應用程序是缺少 – mehulmpt

+0

這不起作用。 :( – Sri

1

其實沒有這樣做,但不運行前景的服務方式。列入白名單可能不適合您的申請,即使它是,您要求用戶給予您的許可,從最終用戶的角度來看,這可能被視爲危險。

但是,我有一個關於這個技巧。聽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; 
    } 
} 
+0

謝謝你這個答案。 – CauCuKien

0

在Android N之後,沒有應用程序可以永遠在後臺運行。不過,您可以使用Firebase作業調度程序,即使它處於休眠模式,也可以幫助您運行應用程序。在Firebase Job Dispatcher的幫助下,如果提供的條件匹配,您可以告訴系統您的應用應該在特定的時間運行。