Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Yonatan Levin] Knock knock! Who's there? Doze.

[Yonatan Levin] Knock knock! Who's there? Doze.

Presentation from GDG DevFest Ukraine 2016.
Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

September 09, 2016
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. Doze, the bro :) No network access No jobs/ No

    syncs No wakelocks No alarms No GPS / Wifi Scans
  2. GCM/FCM Use FCM with High priority - but treat it

    with special care { "to" : "...", "priority" : "high", "notification" : { ... }, "data" : { ... } }
  3. WhiteList • An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SE TTINGS intent

    to take the user directly to the Battery Optimization, where they can add the app.
  4. Note: Google Play policies prohibit apps from requesting direct exemption

    from Power Management features in Android 6.0+ (Doze and App Standby) unless the core function of the app is adversely affected.
  5. public class FinalBattleActivity public void onClick(View v) { switch (v.getId())

    { case R.id.kill_button: StarWarsUtils.makeDecision( LukeDecision.LUKE_KILL_DARTH_VADER, this); break; case R.id.light_side_button: StarWarsUtils.makeDecision( LukeDecision.STAY_ON_LIGHT_SIDE, this); Break; } }
  6. public class StarWarsUtils { public static void makeDecision(LukeDecision decision,Context context)

    { Intent nowIntent = new Intent(context, NowIntentService.class); nowIntent.putExtra(..., decision); context.startService(nowIntent); }
  7. public class NowIntentService extends IntentService { protected void onHandleIntent(Intent intent)

    { LukeDecision decision = (LukeDecision)intent.getSerializableExtra(...); if (decision != null) { makeNetworkCall(decision); } ... }
  8. public class NowIntentService extends IntentService { private void makeNetworkCall(LukeDecision decision)

    { boolean isCompleted = false; if(StarWarsUtils.isNetworkActive()) { isCompleted = doingNetworkCommunication(); } ... }
  9. public class NowIntentService extends IntentService { private void makeNetworkCall(LukeDecision decision)

    { ... if (!isCompleted) { StarWarsUtils.addRetryTask(decision, this); return; } ... }
  10. public void onReceive(Context context, Intent intent) { LukeDecision decisionToRetry =

    StarWarsUtils.getDecisionToRetry(context); StarWarsUtils.makeDecision(decisionToRetry, context); } public class ConnectivityChangeReceiver extends WakefulBroadcastReceiver
  11. public class FinalBattleActivity extends AppCompatActivity private void scheduleHanSoloReport() { AlarmManager

    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); PendingIntent broadcast = getPendingIntent(); alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ONE_MINUTE, broadcast); }
  12. public class HanSoloReceiver public void onReceive(Context context, Intent intent) {

    LocationManager locationService = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); PendingIntent pendingIntent = getPendingIntent(context); String provider = getLocationProvider(locationService); locationService.requestSingleUpdate(provider, pendingIntent); }
  13. public class NowIntentService extends IntentService { @Override protected void onHandleIntent(Intent

    intent) { ... Location HanSoloLocation = intent.getParcelableExtra(LocationManager.KEY_LOCATION_CHANGED); if (HanSoloLocation != null) { checkIfRebelsReady(HanSoloLocation); } }
  14. public class RebelService extends Service implements Handler.Callback public void onCreate()

    { handlerThread = new HandlerThread("RebelServiceHandlerThread"); handlerThread.start(); Looper looper = handlerThread.getLooper(); handler = new Handler(looper, this); handler.sendEmptyMessage(WHAT_MAKE_NETWORK_REQUEST); }
  15. public class RebelService extends Service implements Handler.Callback @Override public boolean

    handleMessage(Message msg) { StarWarsUtils.doingNetworkCommunication(); handler.sendEmptyMessageDelayed( WHAT_MAKE_NETWORK_REQUEST, DELAY_MILLIS); return true; }
  16. What is affected - Pending network transactions will never be

    fired... - Han Solo Alarms will be postponed. - No location updates But...
  17. What? Schedule the task to execute it when certain conditions

    met. (charging, idle, connected to a network or connected to an unmetered network)
  18. Why two? JobScheduler was introduced in API >= 21 (Lollipop).

    GCMNetworkManager - is part of GCM package. When using on devices >= 21, use JobScheduler underneath.
  19. public class StarWarsUtilities Task task = new OneoffTask.Builder().setService(BestTimeService.class) .setExecutionWindow(0, 30)

    .setTag(BestTimeService.LUKE_DECISION) .setUpdateCurrent(false) .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED) .setRequiresCharging(false) .setExtras(bundle) .build();
  20. BestTimeService.java /** * Task run by GcmNetworkManager when all the

    requirements of the scheduled * task are met. */ public class BestTimeService extends GcmTaskService { ... }
  21. BestTimeService.java @Override public int onRunTask(TaskParams taskParams) { switch (taskParams.getTag()) {

    case LUKE_DECISION: ... return GcmNetworkManager.RESULT_SUCCESS; case HAN_SOLO_LOCATION: ... return GcmNetworkManager.RESULT_RESCHEDULE; default: return GcmNetworkManager.RESULT_FAILURE; } }
  22. BestTimeService.java public int onRunTask(TaskParams taskParams) { … case LUKE_DECISION: Bundle

    extras = taskParams.getExtras(); LukeDecision decision = (LukeDecision) extras.getSerializable(...); StarWarsUtils.makeDecision(decision, this); return GcmNetworkManager.RESULT_SUCCESS; … }
  23. BestTimeService.java public int onRunTask(TaskParams taskParams) { … case HAN_SOLO_LOCATION: ..

    request location... return GcmNetworkManager.RESULT_SUCCESS; … }
  24. Not all devices shipped with Play Services int resultCode =

    GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode == ConnectionResult.SUCCESS) { mGcmNetworkManager.schedule(task); } else { // Deal with this networking task some other way }
  25. When Google Play updated it removes all scheduled periodic tasks

    public class BestTimeService extends GcmTaskService { @Override public void onInitializeTasks() { super.onInitializeTasks(); // Reschedule removed tasks here } }
  26. FCM/GCM with High Priority { "to" : "...", "priority" :

    "high", "notification" : { ... }, "data" : { ... } }
  27. public class RebelsMessagingService extends FirebaseMessagingService @Override public void onMessageReceived(RemoteMessage remoteMessage)

    { Intent intent = new Intent(HanSoloReceiver.ACTION); LocalBroadcastManager. getInstance(this). sendBroadcast(intent); }
  28. public class RebelService extends Service implements Handler.Callback public boolean handleMessage(Message

    msg) { StarWarsUtils.doingNetworkCommunication()); handler.sendEmptyMessageDelayed( WHAT_MAKE_NETWORK_REQUEST, DELAY_MILLIS); return true; }
  29. public class RebelService extends Service implements Handler.Callback public void onCreate()

    { Notification notification = ... startForeground(101, notification); }