Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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());
    }
}
like image 850
Daniel Avatar asked Jun 07 '13 21:06

Daniel


1 Answers

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" />
like image 91
Eran Avatar answered Nov 20 '22 02:11

Eran