Android 4.x devices receive GCM messages, but Android 2.3 devices Don't
H

3

8

My android app never receives GCM messages on 2.3 devices, but it does on 4.x devices. I can register all devices (2.3 and 4.x) successfully. I thought it might have something to do with this issue, but it seems like I have my android manifest configured properly. Would anyone be able to eyeball my IntentService and BroadcastReceiver and see if they notice any problems? Any help would be greatly appreciated. Note that onHandeIntent() is never called for Android 2.3 when sending notifications while I have the debugger attached. I checked 4.x devices, and they do trigger the debugger in onHandleIntent(). Thanks!

Android Manfest:

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

    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="my.package.matchtracker.permission.C2D_MESSAGE" />
    <permission android:name="my.package.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <receiver
            android:name=".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="my.package" />
            </intent-filter>
        </receiver>
        <service android:name=".NotificationIntentService" android:enabled="true" />
        <activity android:name="com.gigya.socialize.android.GSWebViewActivity" />
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|screenSize"
            android:theme="@android:style/Theme.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Broadcast Receiver:

package my.package;

import android.app.*;
import android.content.*;

public class GcmBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationIntentService.runIntentInService(context, intent);
        setResultCode(Activity.RESULT_OK);
    }
}

Notification Intent Service

public class NotificationIntentService extends IntentService {
    private String TAG = "NotificationIntentService";
    public NotificationIntentService() {
        super(AppConstants.GCM_SENDER_ID);
    }

    public NotificationIntentService(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    private static PowerManager.WakeLock sWakeLock;
    private static final Object LOCK = NotificationIntentService.class;

    static void runIntentInService(Context context, Intent intent) {
        synchronized(LOCK) {
            if (sWakeLock == null) {
                PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
                sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "my_wakelock");
            }
        }
        sWakeLock.acquire();
        intent.setClassName(context, NotificationIntentService.class.getName());
        context.startService(intent);
    }

    public final void onHandleIntent(Intent intent) {
        try {
            String action = intent.getAction();
            if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
                //don't care.
            } else if (action.equals("com.google.android.c2dm.intent.RECEIVE")) {
                handleMessage(intent);
            }
        } finally {
            synchronized(LOCK) {
                sWakeLock.release();
            }
        }
    }

    private void handleMessage(Intent intent) {
        Bundle b = intent.getExtras();
        String text = b.getString("text"),
               title = b.getString("title"),
               largeImageUrl = b.getString("largeImageUrl");
        Log.i(TAG, "Message is " + text);
        NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        Bitmap bit=null;
        if (largeImageUrl != null && !largeImageUrl.isEmpty()) {
            try{bit = BitmapFactory.decodeStream((InputStream)new URL(largeImageUrl).getContent());
            } catch (Exception e){}
        }
        NotificationCompat.Builder nc = new NotificationCompat.Builder(this)
                                            .setContentTitle(title)
                                            .setContentText(text)
                                            .setSmallIcon(R.drawable.ic_launcher)
                                            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                                            .setAutoCancel(true) //notification disappears when clicked
                                            .setContentIntent(PendingIntent.getActivity(this, 0,
                                                    new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT));
        //bit = Bitmap.createScaledBitmap(bit, android.R.dimen.notification_large_icon_width, android.R.dimen.notification_large_icon_height, true);
        if (bit != null) nc.setLargeIcon(bit);
        nm.notify(0, nc.build());
    }
}
Heatherheatherly answered 7/6, 2013 at 21:24 Comment(0)
B
16

The first potential problem I can see is this :

The package name in the permission element is not the same as the one in the uses-permission element. In my app (which targets Android 2.2) they are identical.

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="my.package.matchtracker.permission.C2D_MESSAGE" />
<permission android:name="my.package.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
Banderole answered 7/6, 2013 at 21:36 Comment(7)
Yep, you're right. I somehow thought that matchtracker was part of a necessary configuration from the 2nd answer to this post. Now I know better. Thanks for helping me with this!Heatherheatherly
@Banderole I see you commenting on most of the GCM questions, and that leads me to a conclusion that you must be having a very good understanding of GCM. So, I would ask you to provide me some info about GCM. I did the AndroidHive tutorial, but as many of them are facing I too is unable to receive notifications on the device, despite of the successful registration on the server. Reading further articles I am guessing that their is some update to the GCM as compared to the AndroidHive tutorial, so plz let me know that what the updates are and what changes to make in that tutorial.Quintain
@AnasAzeem Thanks for the compliment :). I don't know the AndroidHive tutorial. You can post a question with the code you are using (manifest, broadcast receiver, etc...), the Android version on which it doesn't work, the errors you get (if any) and I'll try to help.Banderole
@Banderole Thanks for extending a helping hand, i'll soon post the question and put a link here.Quintain
@AnasAzeem, are you running over wifi instead of 3G/4G? If so, make sure that your router/firewall allows traffic on the relevant ports. See post below for specifics. Note that some firewall rules only allow stateful access, specifically that a port can only receive traffic in certain cases if an outgoing connection was made on that port prior to receiving traffic. This can cause unsolicited traffic to be blocked, which might explain why registration works, but reception does not. #11398970Heatherheatherly
I have both identical, but still problem exists. According to #16027236 this might be about category.Beccafico
@Beccafico Yes, the package in the category of the broadcast receiver should also match the package of the app, but in this question that wasn't the problem (as you can see in the manifest in this question).Banderole
P
0

If you are using product flavor with different applicationId, see my answer to the question GCM messages are not received on android 2.3.6 v but working fine on android 4.X v

Paganini answered 28/4, 2015 at 16:31 Comment(0)
S
0

GCM need google play services installed on device but in version 2.3 it's not installed by default.

Sext answered 23/12, 2015 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.