GCM 通知仅到达某些设备

GCM notifications only arrive to some devices

我在商店中有一个 android 应用程序,它使用 GCM 推送通知。问题是通知只到达我发送它们的一些设备。特别是我注意到它们到达平板电脑而不是 phones,但我只尝试了两个平板电脑和两个 phones,所以这可能有意义也可能没有意义。这两款平板电脑都有 Android 5.0 或 5.1,以及 phone 之一。另一个 phone 有 4.4。

设备成功注册到通知并将它们的 ID 发送到我的服务器。从服务器发送通知时我没有收到任何错误,但它们永远不会到达。我尝试使用 wifi 和 3G 连接,但都没有成功。

我在网上的某处找到了执行此操作的代码,但记不清是在哪里了。问题是我不完全理解它是如何工作的,但当时它似乎已经足够好了,因为我在其中一台接收通知的设备上进行了测试。我会post所有相关代码,如果有什么不对的地方,也许有人可以告诉我。

这是我的清单(删除了不相关的部分)

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>

    <permission
        android:name="edu.galileo.estudiantes.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="edu.galileo.estudiantes.permission.C2D_MESSAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />


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

        ...

        <receiver
            android:name=".util.EstudiantesGcmReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />

                <category android:name="my.package.name.gcm" /> <!-- I do have my actual package name here-->
            </intent-filter>
        </receiver>

        <service android:name=".util.EstudiantesGcmListenerService" />

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

</manifest>

这是接收器

public class EstudiantesGcmReceiver extends WakefulBroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Explicitly specify that GcmMessageHandler will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                EstudiantesGcmListenerService.class.getName());

        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }
}

这是IntentService

public class EstudiantesGcmListenerService extends IntentService
{
    public EstudiantesGcmListenerService() {
        super("EstudiantesGcmListenerService");
    }

    @Override
    public void onCreate() {

        super.onCreate();
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();        

        if (extras != null && extras.containsKey("msg"))
        {
            String message = extras.getString("msg");
            new Handler().post(() -> showNotification("Bla bla", message));

        }
        EstudiantesGcmReceiver.completeWakefulIntent(intent);

    }

    void showNotification(String title, String desc)
    {
        NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        long id = getLastNotificationId(this) + 1;
        NotificationCompat.Builder b = new NotificationCompat.Builder(this)
                                           .setContentTitle(title)
                                           .setContentText(desc)
                                           .setSmallIcon(R.drawable.small_icon)
                                           .setTicker(desc)
                                           .setAutoCancel(true).setVibrate(new long[]{300, 300, 300, 300});

        Intent i = new Intent(this, LoginActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(this, 0, i, 0);

        b.setContentIntent(intent);
        manager.notify((int) id, b.build());
        storeLastNotificationId(id, this);
    }


}

1.Google 建议使用 GCMReceiver 而不是 WakefulBroadcastReceiver

2.And 您必须使用 GcmListenerService

扩展您的服务

3.Also,我们必须使用 InstanceId,因为 gcm.register() 已被弃用。(它仍会为您生成 gcm 密钥)。

https://developers.google.com/cloud-messaging/android/client

他们的使用示例代码“https://github.com/google/gcm

一周前我遇到了类似的问题,尤其是在 Micromax 和 Infocus 手机中。现在,通知工作正常。

如问题中所述,GCM 在安装了 Android 5.0+ 而不是 4.4.x 版本的设备上工作。

除了@m0rpheus5 建议的更改之外,请检查您是否在具有 4.4.x 版本的设备上安装了最新版本的 Google Play 服务。大多数时候将其更新到最新版本是有效的!!

希望对您有所帮助!

根据 Google 提供的新示例,我开始使用 GcmListenerService,然后我开始遇到奇怪的问题。

我可以在少数设备上接收 GCM,但我无法在 QMobile 上接收 GCM,QMobile 是本地品牌 Android 4.4.2,但我的旧应用程序带有 WakefulBroadcastReceiver 实施在同一设备上运行良好。

有什么建议吗?