GCM 通知仅到达某些设备

Posted

技术标签:

【中文标题】GCM 通知仅到达某些设备【英文标题】:GCM notifications only arrive to some devices 【发布时间】:2015-07-03 22:38:32 【问题描述】:

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

设备成功注册到通知并将其 ID 发送到我的服务器。从服务器发送通知时我没有收到任何错误,但它们从未到达。我尝试了 wifi 和 3G 连接,都没有运气。

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

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

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



【问题讨论】:

您是否尝试在手机上重新安装您的应用? 我已经删除了,用 Android Studio 重新上传了(不能从商店下载,因为它会指向生产服务器) 【参考方案1】:

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

2.您必须使用 GcmListenerService

扩展您的服务

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

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

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

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

【讨论】:

您对 GCMListenerService 的看法是正确的,我最终没有使用 GCMReceiver 子类,而是在清单中引用 com.google.android.gms.gcm.GcmReceiver 并向我的 GcmListenerService 添加和意图过滤器,因为它在这里完成:github.com/googlesamples/google-services/tree/master/android/…【参考方案2】:

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

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

希望有帮助!

【讨论】:

按照我对另一个答案的评论中所述的操作后,它甚至适用于 4.4【参考方案3】:

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

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

有什么建议吗?

【讨论】:

同样的事情发生在我身上......只需查看我对已接受答案的评论,了解我是如何修复它的。它现在似乎工作正常。

以上是关于GCM 通知仅到达某些设备的主要内容,如果未能解决你的问题,请参考以下文章

在某些设备上下班后收到 Gcm 通知

某些 android 设备未收到 GCM 推送通知

当应用程序未运行时,GCM 推送通知未在某些设备中显示

某些设备在 android 中未收到推送通知

GCM 推送通知仅适用于调试 apk

Android 设备接收无休止的推送通知