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());
    }
}
4

3 回答 3

16

我可以看到的第一个潜在问题是:

元素中的包名与permission元素中的包名不同uses-permission。在我的应用程序(针对 Android 2.2)中,它们是相同的。

<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" />
于 2013-06-07T21:36:54.980 回答
0

如果您使用具有不同 applicationId 的产品风味,请参阅我对GCM 消息在 android 2.3.6 v 上未收到但在 android 4.X v 上正常工作的问题的回答

于 2015-04-28T16:31:29.937 回答
0

GCM 需要在设备上安装 google play 服务,但在 2.3 版本中默认不安装。

于 2015-12-23T07:13:19.793 回答