4

I have developed a device Admin app that applies policies to the device eg restrictions etc.

How my system works

The webapp sends a push notification to the device via FCM. I used to use GCM and a wakelock.(The latter worked fine). When the push notification comes through to the device, the firebase class that receives the push calls an IntentService. This IntentService then processes the message eg "MOBILEDATA_ON" and any data associated with the message. Once the message has been processed eg MOBILEDATA_ON, the service executes code that turns the mobile data on and then calls a webservice relaying the state back to the webapp.

I chose IntentService as it is Async and is capable of making http calls to relay the state back with no extra async code.

All this works fine when the device is awake, even if the app is in the background.

The problem

If the device is unplugged and untouched for a while, it goes into Doze/Standby mode. (it is an Android 6 device). This is normal behaviour, however if i send a push to the device, the device does receive it and executes the correct code to apply the functionality but unfortunately the webcall that relays the new state of the device is not executed.

so for example, if Bluetooth is switched off on my device and it is in doze mode, i can send a push which switched bluetooth on successfully but the webapp never receives the updated state.

I have set the priority to high in FCM when sending the push, and this why i do receive the push when the device is in Doze.

My app is a Device Admin app, the docs says

The app is an active device admin app (for example, a device policy controller). Although they generally run in the background, device admin apps never enter App Standby because they must remain available to receive policy from a server at any time.

Optimizing for doze

Can anyone tell me why the webcalls are not executing sending the state back to server when in Doze/Standby mode?

[EDIT1]

I used the following code to create a wakelock. At first i acquired the lock in the IntentService, executed the functionality then released it all in the same service. This was good for most cases but some of my functionality includes finding device location via another IntentService called Tracking service.

The problem is that GPS could take say 20 seconds to find a lock by which time the original Intentservice has finished and the device went back to sleep.

To get around this i created 2 methods in the application Object to acquire and release the lock. this way, if the push is one for location i can do a check in the initial service(which normally releases it) to see if the push is a location one and not release it there. Instead the tracking service can make a call to the Application Object to release when GPS is found.

A partial wakelock didn't seem to work as intended so i found the following code that uses a full wakelock. This is depreated though. Is the an alternative to using FULL_WAKE_LOCK?

public void acquireWakeLock(){


    wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
            "MyWakelockTag");
    wakeLock.acquire();
    Log.e(TAG, "just acquired wakelock");

}


public void releaseWakeLock(){

    wakeLock.release();
    Log.e(TAG, "just released wakelock");

}

thanks

Matt

turtleboy
  • 8,210
  • 27
  • 100
  • 199
  • Does your intentservice grab a wakelock? Otherwise it is possible that device goes back to sleep before http request is sent. – Okas Jan 18 '18 at 16:16
  • @Okas No, it used to when using GCM but with firebase i thought it gave you a 10 second window. i know this window is to acquire further wakelocks but i thought it would be enough. Should i use a wakelock in the intentService? – turtleboy Jan 18 '18 at 16:18
  • @Okas could i start the IntentService using startWakefulService instead of startService? – turtleboy Jan 18 '18 at 16:24
  • Why not to experiment and let us all know what you find out. – Okas Jan 18 '18 at 16:30
  • @Okas Ok, i've found the following link. i'll try later tonight. https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html – turtleboy Jan 18 '18 at 16:39
  • @Okas Hi, i have managed to get it working. I have posted my code in EDIT1 above. It is using a deprecated flag, could you have a look and advise me if possible? Thanks – turtleboy Jan 18 '18 at 20:37
  • You can use a JobScheduler as per current official advice, or make your service a foreground service. – Okas Jan 19 '18 at 09:27
  • @Okas I'm not sure exactly what you mean. If i don't use a full wake lock would the device stay awake long enough. Also it says in the docs that Doze ignores job scheduler. I want the functionality to be executed striaght away and not at some arbitrary time the job scheduler determines. – turtleboy Jan 19 '18 at 10:06
  • Then make your service a foreground service. – Okas Jan 19 '18 at 10:28
  • @Okas ok thanks, i'll look into it – turtleboy Jan 19 '18 at 10:35

0 Answers0