【问题标题】:Android 4.x devices receive GCM messages, but Android 2.3 devices Don'tAndroid 4.x 设备接收 GCM 消息,但 Android 2.3 设备不接收
【发布时间】:2013-06-07 21:24:02
【问题描述】:

我的 android 应用在 2.3 设备上从不接收 GCM 消息,但在 4.x 设备上却可以。我可以成功注册所有设备(2.3 和 4.x)。我认为这可能与this issue 有关,但似乎我的 android 清单配置正确。任何人都能够关注我的 IntentService 和 BroadcastReceiver 并查看他们是否发现任何问题?任何帮助将不胜感激。请注意,当我连接了调试器时,在发送通知时,Android 2.3 永远不会调用 onHandeIntent()。我检查了 4.x 设备,它们确实在 onHandleIntent() 中触发了调试器。 谢谢!

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>

广播接收器:

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

通知意图服务

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

【问题讨论】:

    标签: android notifications push-notification google-cloud-messaging android-2.3-gingerbread


    【解决方案1】:

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

    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" />
    

    【讨论】:

    • 是的,你是对的。我不知何故认为 matchtracker 是这个post 的第二个答案的必要配置的一部分。现在我知道得更清楚了。感谢您帮助我!
    • @Eran 我看到你对大多数 GCM 问题发表评论,这让我得出结论,你一定对 GCM 有很好的理解。所以,我想请你给我一些关于 GCM 的信息。我完成了 AndroidHive 教程,但由于他们中的许多人都面临 我也无法在设备上接收通知,尽管在​​服务器上成功注册。阅读更多文章,我猜他们是对 GCM 的一些更新,与 AndroidHive 教程相比,所以请让我知道更新是什么以及在该教程中进行哪些更改。
    • @AnasAzeem 感谢您的称赞 :)。我不知道 AndroidHive 教程。您可以使用您正在使用的代码(清单、广播接收器等)、它无法运行的 Android 版本、您遇到的错误(如果有)发布问题,我会尽力提供帮助。
    • @Eran 感谢您伸出援助之手,我会尽快发布问题并在此处放置链接。
    • @AnasAzeem,你是通过 wifi 而不是 3G/4G 运行的吗?如果是这样,请确保您的路由器/防火墙允许相关端口上的流量。具体请看下面的帖子。请注意,某些防火墙规则仅允许有状态访问,特别是如果在接收流量之前在该端口上建立了传出连接,则该端口只能在某些情况下接收流量。这可能会导致未经请求的流量被阻止,这可以解释为什么注册有效,但接收无效。 stackoverflow.com/questions/11398470/…
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2014-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-06
        • 1970-01-01
        • 2013-12-10
        • 1970-01-01
        • 2013-04-13
        相关资源
        最近更新 更多