Doze mode, GCM notifications and http requests on Samsung S6
Asked Answered
P

1

6

My problem is linked to stackoverflow's "doze-mode-and-gcm-notifications" and "android-doze-mode-gcm-priority" questions, but since the solution for both is to use Google play Service 8.3.0 it's not helping for my case.

Context

I am sending silent (no direct display to user) push notifications with high priority to my application through GCM. Some of these notifications then trigger various http requests to send or get informations/files to/from my web services. Since we need to be able to do these actions at any time, we must handle the case where the phone enters doze mode.

Problem

GCM notifications awaken the application properly, but http requests are failing on Samsung S6 (they always return a time-out error). cordova-plugin-network-information doesn't give the information that the plugin is offline.

The same test on a Nexus 5 device works perfectly fine.

Bonus problem

GCM notifications with normal priority are processed by my Samsung S6 device while being in IDLE state. (According to the android doze documentation, while in IDLE state the device doesn't receive any GCM notifications with normal priority, those are processed when the device switches to IDLE_MAINTENANCE state.)

Devices informations

  • Samsung galaxy S6
  • Nexus 5

  • Both have developer options and usb debugging activated

  • Both devices are connected using wifi
  • Both devices get the application installed the same way : linked to my computer with a usb cable then run the application from Android Studio
  • The Samsung device is brand new, only base applications are installed.

Application informations

  • Cordova 6.1.1
  • Cordova phonegap-plugin-push 1.7.0
  • Angular 1.5.5 / ngCordova 0.1.26-alpha
  • Android Sdk Tools last updates (except Android support repository 32, don't wan't to update it to 33 right away since it has only been released yesterday)

Tests

I use those commands to activate doze :

adb shell dumpsys battery unplug
adb shell dumpsys deviceidle force-idle

The command to check current state :

adb shell dumpsys deviceidle | grep mState

The command to switch state :

adb shell dumpsys deviceidle step

From there I just use Postman to request the gcm API with the following data :

POST https://android.googleapis.com/gcm/send

Headers :

Authorization : key=<MYAPIKEY>
Content-Type : application/json

Body (RAW) :

{
  "data": { 
    "key": {"key":"value"},
    "content-available": "1"
  },
  "registration_ids": ["<MYAPPTOKEN>"]  
}

And finally my app requests my web services, by using the angular $http method or cordova-plugin-file-transfer if I need to send files

Questions

Did someone encounter the same problem, and did you find a solution for it ?

Does someone know about why the network is unavailable (or whatever state it is in) in this particular case ? (again, the documentation says : "GCM high-priority messages let you reliably wake your app to access the network")

If so, did you also have the problem on other device models ?

Bonus question : does someone knows why the Samsung device processes normal priority notifications while in IDLE state ? (I don't know if I must create a separate question for this one, since it's just cherry on the cake for me, but it may be linked to the main question in some way)

Pish answered 17/6, 2016 at 15:57 Comment(2)
Just an FYI you are a few major versions behind in your GPS version, you should probably update as there have been many changesQuaggy
is this issue solve with someone ? i am facing the same. thanksTelles
L
0

I've run into a networking GCM issue as well. I have a GCM service that does IM like activities. Recently I found that after 10 minutes of sleep on Android 7.0 (Samsung Galaxy S6s and S8) my GCM service can no longer connect to the server. It's very curious because from the documentation it sounds like we have to opt-in for the app to be affected by Doze and App Standby.

I did find a work around though. If you use a full wake lock it some how allows networking to occur. I realize this is a brut force method. But at the moment it is the only solution I could find. Here is essentially what I am doing ...

public class GcmIntentService extends IntentService {
….
    protected void onMessage(Context context, Intent intent) {
    
     PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock((PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "GCMOnMessage");

	try {
       logger.d("Processing incoming GCM message. Connecting test. ");
      
       URL url = new URL("http://www.google.com/";;); 
       HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
       int status = urlConnection.getResponseCode();
       logger.d("status: " + status);
    }   
    catch (MalformedURLException e) {
				e.printStackTrace();
			} 
    finally {
                logger.d("Releasing wake lock.");
                wakeLock.release();
     }
}
Lur answered 16/10, 2017 at 15:59 Comment(1)
Doze is most certainly NOT an opt-in thingQuaggy

© 2022 - 2024 — McMap. All rights reserved.