Push message not getting delivered to Android 2.3 handset

Category: azure mobile engagement

Question

imitestteam on Thu, 12 May 2016 07:26:39


I tried sending push message to my Samsung Duos (Android 2.3) but its not getting delivered.Whereas the same push message got delivered to my LG nexus handset(Android 6.0).Does SDK supports 2.3 devices and do i need to make any changes in my code to support it.

Replies

Guillaume Perrot on Fri, 13 May 2016 21:16:22


Hi, the SDK supports Android 2.3, I could test with an old Nexus S.

It's probably related to the way the SDK is integrated into your application.

Usually this kind of request goes through Customer Support as we will need to look at the AndroidManifest.xml and maybe a testing APK so we can test.

If you don't mind publishing those outside the context of customer support then we can have a quick look at those, but it may require you to use Customer Support if deeper investigation is required.

imitestteam on Wed, 01 Jun 2016 05:29:59


The below is the Manifest file of my app.It works from 4.3 onward but on device 4.0.4 or 2.3,i am unable to receive push notification.I even tried by registering the device id ,but that effort was too in vain.For records,i have tried a sample push notification app using GCM and its working fine on this device.So there is no problem with the device regarding setting up accounts/network connectivity etc.Please check if anything needed to be changed in the manifest file to make it compatible with 4.0.4 handset and below.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mypackage.name">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

   <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>



    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="com.mypackage.name.permission.C2D_MESSAGE" />
    <permission android:name="com.mypackage.name.permission.C2D_MESSAGE" android:protectionLevel="signature" />

    <application
        android:name="com.mypackage.name.App"
        android:allowBackup="true"
        android:clearTaskOnLaunch="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:screenOrientation="portrait"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.SplashActivity"
            android:configChanges="locale"
            android:label="@string/app_name"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       
       <service
            android:name="com.microsoft.azure.engagement.service.EngagementService"
            android:exported="false"
            android:label="myappService"
            android:process=":Engagement" />

       <activity android:name="com.microsoft.azure.engagement.reach.activity.EngagementTextAnnouncementActivity" android:theme="@android:style/Theme.Light">
             <intent-filter>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.ANNOUNCEMENT"/>
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="text/plain" />
             </intent-filter>
         </activity>
         <activity android:name="com.microsoft.azure.engagement.reach.activity.EngagementWebAnnouncementActivity" android:theme="@android:style/Theme.Light">
             <intent-filter>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.ANNOUNCEMENT"/>
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="text/html" />
             </intent-filter>
         </activity>
         <activity android:name="com.microsoft.azure.engagement.reach.activity.EngagementPollActivity" android:theme="@android:style/Theme.Light">
             <intent-filter>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.POLL"/>
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>

         <activity android:name="com.microsoft.azure.engagement.reach.activity.EngagementLoadingActivity" android:theme="@android:style/Theme.Dialog">
             <intent-filter>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.LOADING"/>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
         <receiver android:name="com.microsoft.azure.engagement.reach.EngagementReachReceiver" android:exported="false">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
                 <action android:name="com.microsoft.azure.engagement.intent.action.AGENT_CREATED"/>
                 <action android:name="com.microsoft.azure.engagement.intent.action.MESSAGE"/>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.ACTION_NOTIFICATION"/>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.EXIT_NOTIFICATION"/>
                 <action android:name="com.microsoft.azure.engagement.reach.intent.action.DOWNLOAD_TIMEOUT"/>
             </intent-filter>
         </receiver>
         <receiver android:name="com.microsoft.azure.engagement.reach.EngagementReachDownloadReceiver">
             <intent-filter>
                 <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
             </intent-filter>
         </receiver>


         <meta-data android:name="engagement:reach:notification:icon" android:value="ic_launcher"/>
         <meta-data android:name="engagement:gcm:sender" android:value="<MYPROJECTID>\n" />

         <receiver android:name="com.microsoft.azure.engagement.gcm.EngagementGCMEnabler" android:exported="false">
             <intent-filter>
                 <action android:name="com.microsoft.azure.engagement.intent.action.APPID_GOT" />
             </intent-filter>
         </receiver>

         <receiver android:name="com.microsoft.azure.engagement.gcm.EngagementGCMReceiver"
             android:permission="com.google.android.c2dm.permission.SEND">
             <intent-filter>
                 <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                 <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                 <category android:name="com.mypackage.name" />
             </intent-filter>
         </receiver>


    </application>

</manifest>

Guillaume Perrot on Wed, 01 Jun 2016 18:44:49


I don't see anything wrong in the manifest.

Couple of questions:

  • Do you see your 2.3 / 4.0.3 devices in the monitor tab live sessions? If this does not work there is no chance the push can work.
  • Did you test an in app notification (please test if not)? it could be a problem with rendering the notification icon in the panel, you could also try providing another 25*25dp icon in the manifest. It can also be a drawable folder selection. If you use drawable-hdpi or any other suffix, please have the icon in the drawable folder without suffix as a fall back. Also mipmaps are not supported, only drawables.

imitestteam on Fri, 03 Jun 2016 06:23:24


The answers to your questions are below: 
  • Do you see your 2.3 / 4.0.3 devices in the monitor tab live sessions? If this does not work there is no chance the push can work.-Yes i can see it in monitor tab live session.
  • Did you test an in app notification (please test if not)? it could be a problem with rendering the notification icon in the panel, you could also try providing another 25*25dp icon in the manifest. It can also be a drawable folder selection. If you use drawable-hdpi or any other suffix, please have the icon in the drawable folder without suffix as a fall back. Also mipmaps are not supported, only drawables.-  I tested both in-app and system notification and both of them are not working.Regarding icon size and drawable folder,it is as expected and i tried with 25*25 image.That too doesnt seem to work.

 I have figured out one thing,it seems the registration to GCM itself is not happening.I have extended EngagementGCMReceiver and overridden onReceive method of the same.For devices 4.2 and above,while my app starts,it comes to OnReceive method and then registration happens,but for devices like 4.0.4,it never comes to onReceive method and hence i suppose,my device doesn't get registered to GCM at all.Below is the code.Please let me know what can be the root cause of this issue.

import android.content.Context;
import android.content.Intent;

import com.microsoft.azure.engagement.EngagementNativePushToken;
import com.microsoft.azure.engagement.gcm.EngagementGCMReceiver;
import com.microsoft.azure.engagement.nativepush.EngagementNativePushAgent;

import static com.microsoft.azure.engagement.EngagementNativePushToken.Type.GCM;


public class MyGCMReceiver extends EngagementGCMReceiver {
    private static final String INTENT_ACTION_REGISTRATION = "com.google.android.c2dm.intent.REGISTRATION";

    /** Token key in intent result */
    private static final String INTENT_EXTRA_REGISTRATION = "registration_id";

    /** Action when we receive a push */
    public static final String INTENT_ACTION_RECEIVE = "com.google.android.c2dm.intent.RECEIVE";

    @Override
    public void onReceive(Context context, Intent intent)
    {
   // super.onReceive(context,intent);
    // Registration result action *//*
        String action = intent.getAction();
        if (INTENT_ACTION_REGISTRATION.equals(action))
        {
      //* Handle register if successful (otherwise we'll retry next time process is started) *//*
            String registrationId = intent.getStringExtra(INTENT_EXTRA_REGISTRATION);
            if (registrationId != null)
            {
        //* Send registration id to the Engagement Push service *//*
                EngagementNativePushAgent nativePushAgent = EngagementNativePushAgent.getInstance(context);
                nativePushAgent.registerNativePush(new EngagementNativePushToken(registrationId, GCM));
            }
        }

    //* Received message action *//*
        else if (INTENT_ACTION_RECEIVE.equals(action)){
         
           EngagementNativePushAgent.getInstance(context).onPushReceived(intent.getExtras());
        }

    }
}

 

Guillaume Perrot on Sat, 04 Jun 2016 01:28:28


Hi, the com.microsoft.azure.engagement.gcm.EngagementGCMEnabler class is from where we trigger the register call if enabled (and init the GCM part of the SDK).

Can you debug what's happening there? we send an intent to the GCM service to trigger the registration, maybe it fails for some of your devices though I never saw that happening on a legit Google Play device.

imitestteam on Mon, 06 Jun 2016 04:35:23


Hi, I have extended EngagementGCMEnabler and overridden the onRecieve method .Everything works smoothly in that class without any exception.But after  context.startService(registrationIntent) is being executed,the control doesn't move on to the onReceive method of EngagementGCMReceiver class.Here is my code.

public class MyGCMEnabler extends EngagementGCMEnabler {
    @Override
    public void onReceive(Context context, Intent intent) {
       // super.onReceive(context, intent);

    /* Once the application identifier is known */
        if ("com.microsoft.azure.engagement.intent.action.APPID_GOT".equals(intent.getAction()))
        {
      /* Init the native push agent */
            String appId = intent.getStringExtra("appId");
            EngagementNativePushAgent.getInstance(context).onAppIdGot(appId);

      /*
       * Request GCM registration identifier, this is asynchronous, the response is made via a
       * broadcast intent with the <tt>com.google.android.c2dm.intent.REGISTRATION</tt> action.
       */
            String sender = EngagementUtils.getMetaData(context).getString("engagement:gcm:sender");
            if (sender != null)
            {
        /* Launch registration process */
                Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
                registrationIntent.setPackage("com.google.android.gsf");
                registrationIntent.putExtra("app", PendingIntent.getBroadcast(context, 0, new Intent(), 0));
                registrationIntent.putExtra("sender", sender.trim());
                try
                {
                    context.startService(registrationIntent);
                }
                catch (RuntimeException e)
                {
                    e.getMessage();
          /* Abort if the GCM service can't be accessed. */
                }
         
            }
        }
    }
}

imitestteam on Mon, 06 Jun 2016 04:37:33


Also due to time zone difference,i have to wait for almost an entire day to get reply for my queries.If you can tell me whether there is any chat forum type where i can troubleshoot my issues in a faster manner.Thanks in advance.

Guillaume Perrot on Mon, 06 Jun 2016 07:49:32


Hi, from what I am aware of there is only this forum, stack overflow and azure customer support.

Your problem is really a first. Do you have Google Play being installed on the device and can you install applications from those devices? For pre-3.0 devices, this requires users to set up their Google accounts on their mobile devices (this last statement is from Google documentation).

Also does the Google package name resolve correctly for this device? ("com.google.android.gsf"). 

You could also try the Google SDK to initiate the registering, but we are not using the instance ID. You have to use the deprecated register method from https://developers.google.com/android/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#public-methods. Getting the registration ID that way should also trigger the intent.

If you can get the registration ID that way but the intent is not triggered you can still call our SDK the way the receiver does it to pass the registration identifier. You still need both our receivers in the manifest either way for other reasons (for context init and message receiving).



imitestteam on Mon, 06 Jun 2016 09:42:22


Firstly GooglePlay is installed in the device and i m logged into Google account.Now i tried the following and is able to receive registration id.I have commented registrationIntent.setPackage("com.google.android.gsf") in the EngagementGCMEnabler class for pre 4.2 devices.It now goes to EngagementGCMReceiver class onReceive method where the action retrieved is com.google.android.c2dm.intent.REGISTRATION and hence the registration process follows.

But when i push a message,the action again comes as com.google.android.c2dm.intent.REGISTRATION instead of com.google.android.c2dm.intent.RECEIVE and hence i am not able to receive any messages.Please help.

imitestteam on Mon, 06 Jun 2016 09:52:09


It tried simple method to programatically find out if package "com.google.android.gsf" is installed in my device and it seems it is not.But i am able to open Google play store and also logged in with Gmail account

imitestteam on Mon, 06 Jun 2016 09:58:02


I tested the same on another device Nexus5 AndroidM,there also the above package is not found,but i am able to receive messages smoothly on that handset. So my assumption is,even if "com.google.android.gsf" is not installed in the phone,it doesnt effect push notification. 

Guillaume Perrot on Mon, 06 Jun 2016 15:32:00


Hi, on an android 2.3 emulator and Nexus S I could make our SDK work without any modification. The intent with setpackage works as expected. I just needed to add/login a google account in the phone settings for this to work.

If you have registration intent being fired that means we should have received the registration identifier server side and that your device should be eligible to be pushed as soon as an analytics session is done.

You can check that the token has been sent on the server by doing the following. Get your logical deviceId by calling EngagementAgent.getDeviceId(...), then go to the monitor tab of your application in engagement portal, then in Troubleshooting check that you have :

First/last seen some date / some date

Last Info  some date

Native Push Enabled Yes

Technicals

Should be populated with phone info / app version

If one of these fields are N/A, the push will not work at activate campaign time. 

imitestteam on Tue, 07 Jun 2016 03:50:40


hey,i verified the TroubleShooting info with my device id and here are my observations.

Last location-NA

Carrier (name/country)-NA/India

Network (type/sub-type)-Wifi/NA

Country-NA

Region-NA

Locality-NA

So is any of the above fields being NA effects my Push Registration/Push Receive ?


N/A
N/A

imitestteam on Tue, 07 Jun 2016 03:52:44


I hope not because i verified my LG Nexus device which registers and receives Push messages properly but has the above fields as NA. 

Guillaume Perrot on Tue, 07 Jun 2016 19:03:17


Having at least 1 technicals set is fine, you have network type and carrier country which means the log was sent successfully.

Can you communicate the Engagement appId (application identifier from connection string) and Engagement deviceId?

imitestteam on Wed, 08 Jun 2016 04:14:06


one thing i observed,in devices 4.0.3,while registering my device,i get action as com.google.android.c2dm.intent.REGISTRATION where in the extras i get key as registration_id and it gets registered.But when i push a message through announcement,i get action again as com.google.android.c2dm.intent.REGISTRATION where i get key from extras as unregistered. Why my device is getting unregistered automatically? What can be the issue? Anything related to Manifest file?

Guillaume Perrot on Wed, 08 Jun 2016 23:25:13


I can't find what is wrong with the manifest you uploaded earlier.

I created a very simple application compatible with android 2.3.3 (API level 10).

I tested push on a real Nexus S (API level 10 - 2.3.6) device and also a 4.0.3 (API level 15) emulator with Google Apis image.

I could receive notifications on both devices without issue.

Here is the code for this app, containing the mobile engagement SDK, and a connection string that you can use or edit (in the launcher activity): https://onedrive.live.com/redir?resid=83156F138B08E2E7!1722&authkey=!AGnuYgzrZvyytjU&ithint=folder%2czip

I can give you access to my engagement portal if needed, I just need the email you use in engagement portal to invite you.

You can now compare my sample working app with yours and see what are the differences.