GCM messages are not received on android 2.3.6 v but working fine on android 4.X v
Asked Answered
G

2

1

My GCM client is able to register on all versions but messages are received on android above 4.x versions, not on android 2.3.6. I have made many changes but I cannot figure this problem out please help me, thanks in advance.

manifest file code

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />


    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

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

    <permission android:name="com.democlientapp.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.democlientapp.permission.C2D_MESSAGE" />



    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data android:name="com.google.android.gms.version"
               android:value="@integer/google_play_services_version"/>

        <activity android:name="com.google.android.gms.ads.AdActivity"
             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>



        <activity
            android:name="com.democlientapp.RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.democlientapp.MainActivity"
            android:label="@string/app_name" >

        </activity>
         <receiver
            android:name="com.democlientapp.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
              <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
               <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.democlientapp" />
            </intent-filter>
        </receiver>  




        <service android:name="com.democlientapp.GcmIntentService" />
    </application>

</manifest>

GCMBrodcastReceiver.java

package com.democlientapp;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("tag", "****************GcmBroadcastReceiver.java ok*************");
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);

    }


}

GCMIntentService.java

package com.democlientapp;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;

public class GcmIntentService extends IntentService {
    public static  int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
    String TAG="tag";
    SharedPreferences sp;
    StringBuffer sb;

    public GcmIntentService() {

        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("tg", "intent sservice******************");
        String extras1 = intent.getExtras().getString("data");
        //Log.i("tag", "string extras :"+extras1.toString());
        Bundle extras=intent.getExtras();
        //Log.i("tag", "bundle extras :"+extras);

        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
               Log.i("tag", "entered");
            /*
             * Filter messages based on message type. Since it is likely that GCM
             * will be extended in the future with new message types, just ignore
             * any message types you're not interested in, or that you don't
             * recognize.
             */
            if (GoogleCloudMessaging.
                    MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_DELETED.equals(messageType)) {
                sendNotification("Deleted messages on server: " +
                        extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                // This loop represents the service doing some work.
                for (int i=0; i<5; i++) {
                    Log.i(TAG, "Working... " + (i+1)
                            + "/5 @ " + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                Log.i(TAG, "Received: " + extras.toString());
                // Post notification of received message.
                sendNotification("Received: " + extras);

            }
        }
        //Log.i(TAG, "Received11111111111111111111");
        //sendNotification("Received: registeration "+extras);
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        //Log.i(TAG, "Received22222222222222222222222");
        GcmBroadcastReceiver.completeWakefulIntent(intent);
        //Log.i(TAG, "Received3333333333333333");
    }

    // Put the message into a notification and post it.
    // This is just one simple example of what you might choose to do with
    // a GCM message.
    private void sendNotification(String msg) {
        Log.i("tag","GcmBroadcastReceiver.java send notification");
        //storing message in shared preference
        StoreMsg(msg);



        mNotificationManager = (NotificationManager)
                this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("Spy notification")
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
        //mNotificationManager.no
        //NOTIFICATION_ID++;
    }

    public void StoreMsg(String Msg)
    {
        String  name="MyPrefs";
         sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
          sb=new StringBuffer();
         String mg = sp.getString("MESSAGES", "false");

         if (mg.equals("false")) {
         //sb.append(mg);
         sb.append(Msg);
         }
         else{
             sb.append(mg+"\n****************");
             sb.append("\n"+Msg);

         }

        Log.i("tag", "storemsg is: "+sb);
        Editor editor = sp.edit();
         editor.putString("MESSAGES",sb.toString());
         //Log.i("tag","Gcmintentservice.java,MESSAGES storing SharedPreferences");
         editor.commit();
         //Log.i("tag", "registeractivity.java, onclick method client username exists in DB");



    }
    public String getMsg(){
        String  name="MyPrefs";
         sp = this.getSharedPreferences(name, Context.MODE_PRIVATE);
        String prefName = sp.getString("MESSAGES", "false");
        Log.i("tag", "storemsg is: "+sb);
        return prefName;

    }
}
Glutathione answered 8/3, 2015 at 13:27 Comment(3)
Have you set up a Google account on the Android 2.3.6 devices? From the GCM docs: On Android devices, GCM uses an existing connection for Google services. For pre-3.0 devices, this requires users to set up their Google accounts on their mobile devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.Acrylonitrile
Yes, I have already set up google account and the device has play services too. Is there any problem with latest updated GCM?Glutathione
What response do you get on your GCM app server? The response should have a successful response for all, including the Android 2.3.6 clients. If not, there should be some info in the body of the response regarding the root of the issue.Acrylonitrile
D
0

If you are using product flavors maybe you have the same problem than I found.

I found that when using flavors with diferent applicationId, then your package in the AndroidManifest file for the permission and the category is not correct. And this does not matter for Android 5.x, but for Android 2.3 causes that the broadcast receiver will never be called.

The solution I found is use the gradle's placeholder support. Using ${applicationId} the issue is resolved for all the Android versions.

build.gradle:

productFlavors {
    prod {
        applicationId 'com.democlientapp'
    }
    dev {
        applicationId 'com.democlientapp.dev'
    }
}

AndroidManifest.xml:

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />


    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

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

    <permission android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />



    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data android:name="com.google.android.gms.version"
               android:value="@integer/google_play_services_version"/>

        <activity android:name="com.google.android.gms.ads.AdActivity"
             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>



        <activity
            android:name="com.democlientapp.RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.democlientapp.MainActivity"
            android:label="@string/app_name" >

        </activity>
         <receiver
            android:name="com.democlientapp.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
              <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
               <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="${applicationId}" />
            </intent-filter>
        </receiver>    

        <service android:name="com.democlientapp.GcmIntentService" />
    </application>

</manifest>
Declinate answered 28/4, 2015 at 16:23 Comment(0)
G
0

Use Latest dependency/library for GCM for sdk version 4 or heigher

 compile "com.google.android.gms:play-services-gcm:10.2.0"

in build.gradle file in dependency. and add build.gragle level file

classpath 'com.google.gms:google-services:3.0.0'

its works for hiegher versions.

Gregoriagregorian answered 23/2, 2017 at 9:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.