+ All Categories
Home > Technology > Knock knock! Who's there? Doze. - Yonatan Levin

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

Date post: 14-Apr-2017
Category:
Upload: droidcontlv
View: 232 times
Download: 3 times
Share this document with a friend
82
Yonatan Levin Google Developer Expert levin.yonatan parahall
Transcript
Page 1: Knock knock! Who's there? Doze. - Yonatan Levin

Yonatan LevinGoogle Developer Expert

levin.yonatanparahall

Page 2: Knock knock! Who's there? Doze. - Yonatan Levin

59 Cities > 20M usersRuby, Go, Python, Microservices

Page 3: Knock knock! Who's there? Doze. - Yonatan Levin

> 1300 members Largest Android Active Community

Page 4: Knock knock! Who's there? Doze. - Yonatan Levin

:)

The story about the shy guy

Doze Mode

Page 5: Knock knock! Who's there? Doze. - Yonatan Levin
Page 6: Knock knock! Who's there? Doze. - Yonatan Levin
Page 7: Knock knock! Who's there? Doze. - Yonatan Levin
Page 8: Knock knock! Who's there? Doze. - Yonatan Levin
Page 9: Knock knock! Who's there? Doze. - Yonatan Levin

Doze, the bro :)

No network access

No jobs/ No syncs

No wakelocks

No alarms

No GPS / Wifi Scans

Page 10: Knock knock! Who's there? Doze. - Yonatan Levin

Doze Mode on Marshmallow

Page 11: Knock knock! Who's there? Doze. - Yonatan Levin
Page 12: Knock knock! Who's there? Doze. - Yonatan Levin
Page 13: Knock knock! Who's there? Doze. - Yonatan Levin

Not shy anymore

Page 14: Knock knock! Who's there? Doze. - Yonatan Levin

Doze Mode on Nougat

Page 15: Knock knock! Who's there? Doze. - Yonatan Levin

When?

All intervals are configurable by Google/Manufacturer.

Page 16: Knock knock! Who's there? Doze. - Yonatan Levin

Statistics on OnePlus 3 (Marshmallow)

Page 17: Knock knock! Who's there? Doze. - Yonatan Levin

Statistics on Nexus 6P (Nougat)

Page 18: Knock knock! Who's there? Doze. - Yonatan Levin

Doze, sweet, Doze,Let me go...

Page 19: Knock knock! Who's there? Doze. - Yonatan Levin

Charge it...

Page 21: Knock knock! Who's there? Doze. - Yonatan Levin

No network access

Page 22: Knock knock! Who's there? Doze. - Yonatan Levin

GCM/FCM

Use FCM with High priority - but treat it with special care

{

"to" : "...",

"priority" : "high",

"notification" : {

...

},

"data" : {

...

}

}

Page 23: Knock knock! Who's there? Doze. - Yonatan Levin

WhiteList

● An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to take the user directly to the Battery Optimization, where they can add the app.

Page 24: Knock knock! Who's there? Doze. - Yonatan Levin

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.

Page 25: Knock knock! Who's there? Doze. - Yonatan Levin

And it’s not all, folks

Page 26: Knock knock! Who's there? Doze. - Yonatan Levin

CONNECTIVITY_CHANGES

Page 27: Knock knock! Who's there? Doze. - Yonatan Levin
Page 28: Knock knock! Who's there? Doze. - Yonatan Levin
Page 29: Knock knock! Who's there? Doze. - Yonatan Levin

My shiny new app

git clone [email protected]:parahall/final_battle_doze.git

Page 30: Knock knock! Who's there? Doze. - Yonatan Levin
Page 31: Knock knock! Who's there? Doze. - Yonatan Levin
Page 32: Knock knock! Who's there? Doze. - Yonatan Levin
Page 33: Knock knock! Who's there? Doze. - Yonatan Levin
Page 34: Knock knock! Who's there? Doze. - Yonatan Levin

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;

}

}

Page 35: Knock knock! Who's there? Doze. - Yonatan Levin

public class StarWarsUtils {

public static void makeDecision(LukeDecision decision,Context

context) {

Intent nowIntent = new Intent(context, NowIntentService.class);

nowIntent.putExtra(..., decision);

context.startService(nowIntent);

}

Page 36: Knock knock! Who's there? Doze. - Yonatan Levin

public class NowIntentService extends IntentService {

protected void onHandleIntent(Intent intent) {

LukeDecision decision =

(LukeDecision)intent.getSerializableExtra(...);

if (decision != null) {

makeNetworkCall(decision);

}

...

}

Page 37: Knock knock! Who's there? Doze. - Yonatan Levin

public class NowIntentService extends IntentService {

private void makeNetworkCall(LukeDecision decision) {

boolean isCompleted = false;

if(StarWarsUtils.isNetworkActive()) {

isCompleted = doingNetworkCommunication();

}

...

}

Page 38: Knock knock! Who's there? Doze. - Yonatan Levin

public class NowIntentService extends IntentService {

private void makeNetworkCall(LukeDecision decision) {

...

if (!isCompleted) {

StarWarsUtils.addRetryTask(decision, this);

return;

}

...

}

Page 39: Knock knock! Who's there? Doze. - Yonatan Levin

How we will retry the request if it’s failed?

Page 40: Knock knock! Who's there? Doze. - Yonatan Levin

Connectivity Manager

Page 41: Knock knock! Who's there? Doze. - Yonatan Levin

AndroidManifest.xml

<receiver android:name=".ConnectivityChangeReceiver">

<intent-filter>

<action

android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

</intent-filter>

</receiver>

Page 42: Knock knock! Who's there? Doze. - Yonatan Levin

public void onReceive(Context context, Intent intent) {

LukeDecision decisionToRetry =

StarWarsUtils.getDecisionToRetry(context);

StarWarsUtils.makeDecision(decisionToRetry, context);

}

public class ConnectivityChangeReceiver extends WakefulBroadcastReceiver

Page 43: Knock knock! Who's there? Doze. - Yonatan Levin
Page 44: Knock knock! Who's there? Doze. - Yonatan Levin

Han Solo reporting to Rebels

Page 45: Knock knock! Who's there? Doze. - Yonatan Levin
Page 46: Knock knock! Who's there? Doze. - Yonatan Levin

public class FinalBattleActivity extends AppCompatActivity

protected void onCreate(Bundle savedInstanceState) {

...

scheduleHanSoloReport();

...

}

Page 47: Knock knock! Who's there? Doze. - Yonatan Levin

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

}

Page 48: Knock knock! Who's there? Doze. - Yonatan Levin

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

}

Page 49: Knock knock! Who's there? Doze. - Yonatan Levin

public class NowIntentService extends IntentService {

@Override protected void onHandleIntent(Intent intent) {

...

Location HanSoloLocation =

intent.getParcelableExtra(LocationManager.KEY_LOCATION_CHANGED);

if (HanSoloLocation != null) {

checkIfRebelsReady(HanSoloLocation);

}

}

Page 50: Knock knock! Who's there? Doze. - Yonatan Levin

RebelService

Page 51: Knock knock! Who's there? Doze. - Yonatan Levin

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

}

Page 52: Knock knock! Who's there? Doze. - Yonatan Levin

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;

}

Page 53: Knock knock! Who's there? Doze. - Yonatan Levin

So what is affected by Doze my app?

Page 54: Knock knock! Who's there? Doze. - Yonatan Levin

What is affected

- Pending network transactions will never be fired...- Han Solo Alarms will be postponed.- No location updates

But...

Page 55: Knock knock! Who's there? Doze. - Yonatan Levin

There is still some place for...

Page 56: Knock knock! Who's there? Doze. - Yonatan Levin

JobScheduler/GCMNetworkManager

Page 57: Knock knock! Who's there? Doze. - Yonatan Levin

What?

Schedule the task to execute it when certain conditions met.

(charging, idle, connected to a network or connected to an unmetered network)

Page 58: Knock knock! Who's there? Doze. - Yonatan Levin

Why two?

JobScheduler was introduced in API >= 21 (Lollipop).

GCMNetworkManager - is part of GCM package. When using on devices >= 21, use JobScheduler underneath.

Page 59: Knock knock! Who's there? Doze. - Yonatan Levin

build.gradledependencies {

...

compile 'com.google.android.gms:play-services-gcm:9.4.0'

...

}

Page 60: Knock knock! Who's there? Doze. - Yonatan Levin

public class StarWarsUtilities

void addRetryTask(LukeDecision decision,Context context){

GcmNetworkManager gcmNetworkManager =

GcmNetworkManager.getInstance(context);

}

Page 61: Knock knock! Who's there? Doze. - Yonatan Levin

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

Page 62: Knock knock! Who's there? Doze. - Yonatan Levin

public class StarWarsUtilities

void addRetryTask(LukeDecision decision,Context context){

...

gcmNetworkManager.schedule(task);

}

Page 63: Knock knock! Who's there? Doze. - Yonatan Levin

AndroidManifest.xml<service

android:name=".BestTimeService" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"android:exported="true">

<intent-filter>

<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>

</intent-filter>

</service>

Page 64: Knock knock! Who's there? Doze. - Yonatan Levin

BestTimeService.java/**

* Task run by GcmNetworkManager when all the

requirements of the scheduled

* task are met.

*/

public class BestTimeService extends GcmTaskService {

...

}

Page 65: Knock knock! Who's there? Doze. - Yonatan Levin

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;

}

}

Page 66: Knock knock! Who's there? Doze. - Yonatan Levin

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;

}

}

Page 67: Knock knock! Who's there? Doze. - Yonatan Levin

Han Solo Recurring Location task?

Page 68: Knock knock! Who's there? Doze. - Yonatan Levin

Task task = new PeriodicTask.Builder()

.setService(BestTimeService.class)

.setPeriod(SIXTY_SEC)

.setFlex(10)

.setTag(BestTimeService.HAN_SOLO_LOCATION)

.setPersisted(true)

.build();

public class FinalBattleActivity

Page 69: Knock knock! Who's there? Doze. - Yonatan Levin

BestTimeService.javapublic int onRunTask(TaskParams taskParams) {

case HAN_SOLO_LOCATION:

.. request location...

return GcmNetworkManager.RESULT_SUCCESS;

}

Page 70: Knock knock! Who's there? Doze. - Yonatan Levin

Canceling TaskmGcmNetworkManager.cancelAllTasks(BestTimeService.class);

mGcmNetworkManager.cancelTask(

TAG,

BestTimeService.class

);

Page 71: Knock knock! Who's there? Doze. - Yonatan Levin

There is a problem hiding here

Page 72: Knock knock! Who's there? Doze. - Yonatan Levin

Not all devices shipped with Play Servicesint resultCode =

GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

if (resultCode == ConnectionResult.SUCCESS) {

mGcmNetworkManager.schedule(task);

} else {

// Deal with this networking task some other way

}

Page 73: Knock knock! Who's there? Doze. - Yonatan Levin

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

}

}

Page 74: Knock knock! Who's there? Doze. - Yonatan Levin

Can we do better?

Page 75: Knock knock! Who's there? Doze. - Yonatan Levin

FCM/GCM with High Priority

{

"to" : "...",

"priority" : "high",

"notification" : {

...

},

"data" : {

...

}

}

Page 76: Knock knock! Who's there? Doze. - Yonatan Levin

AndroidManifest.xml

<service

android:name=".RebelsMessagingService">

<intent-filter>

<action

android:name="com.google.firebase.MESSAGING_EVENT"/>

</intent-filter>

</service>

Page 77: Knock knock! Who's there? Doze. - Yonatan Levin

public class RebelsMessagingService extends FirebaseMessagingService

@Override public void onMessageReceived(RemoteMessage remoteMessage) { Intent intent = new Intent(HanSoloReceiver.ACTION);

LocalBroadcastManager. getInstance(this). sendBroadcast(intent); }

Page 78: Knock knock! Who's there? Doze. - Yonatan Levin

Some dirty tricks. Be aware when using it…

Page 79: Knock knock! Who's there? Doze. - Yonatan Levin

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;

}

Page 80: Knock knock! Who's there? Doze. - Yonatan Levin

public class RebelService extends Service implements Handler.Callback

public void onCreate() {

Notification notification =

...

startForeground(101, notification);

}

Page 81: Knock knock! Who's there? Doze. - Yonatan Levin
Page 82: Knock knock! Who's there? Doze. - Yonatan Levin

Yonatan LevinGoogle Developer Expert

levin.yonatanparahall


Recommended