Push notifications/GCM 不工作 可能是什么问题?

Push notifications/GCM Not working What can be the issue?

我的 GCM 服务不工作。我在我的清单文件中声明了一些东西,看起来像:

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.SEND"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<permission android:name="com.xxxx.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.xxxx.xxxxxx.permission.C2D_MESSAGE" />

<receiver android:name=".core.push.receiver.GCMBroadcastReceiver" android:exported="true" 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.SEND" />
                <category android:name="com.xxxx.xxxxxx" />
            </intent-filter>
</receiver>
<service android:name=".core.push.service.GCMIntentService" />

我的广播接收器代码如下所示:

public class GCMBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        ComponentName messageProcessingService = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
        context.startService(intent.setComponent(messageProcessingService));
        setResultCode(Activity.RESULT_OK);
    }
}

我的意向服务:

public class GCMIntentService extends IntentService
{
    private static final int NOTIFICATION_NEW_MESSAGE = 0;

    public GCMIntentService()
    {
        super(GCMIntentService.class.getSimpleName());
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty())
        {
            if (!GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
            {
                return;
            }

            // TODO Make more efficient. Load message stream here, not in two places later!
            int newUnreadCount = MessagingController.getInstance().getUnreadCount() + 1;
            MessagingController.getInstance().prepareStream();
            MessagingController.getInstance().setUnreadCount(newUnreadCount);

            final boolean isUserAuthenticated = !TextUtils.isEmpty(AuthenticationController.getInstance().getAuthToken());

            if (isUserAuthenticated)
            {
                new Handler(Looper.getMainLooper()).post(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        App.from(GCMIntentService.this).fire(MessagingEvent.NEW_MESSAGE);
                    }
                });
            }
            else
            {
                displayNotification(newUnreadCount + " New Message" + (newUnreadCount > 1 ? "s" : ""), newUnreadCount);
            }
        }
    }

    private void displayNotification(CharSequence message, int eventCount)
    {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        boolean shouldDisplayMessages = preferences.getBoolean("notifications_new_message", true);

        if (!shouldDisplayMessages)
        {
            return;
        }

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        Intent openMessagingScreen = new Intent(this, LandingActivity.class);
        openMessagingScreen.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        openMessagingScreen.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        preferences.edit().putBoolean(MessagingFragment.PREF_MESSAGE_WAITING, true).apply();

        PendingIntent notificationAction = PendingIntent.getActivity(this, 0, openMessagingScreen, PendingIntent.FLAG_CANCEL_CURRENT);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(getString(R.string.app_name))
                .setStyle(new NotificationCompat.BigTextStyle().bigText(message))
                .setContentText(message)
                .setAutoCancel(true)
                .setContentIntent(notificationAction)
                .setNumber(eventCount);

        Notification notification = notificationBuilder.build();
        notification.defaults |= Notification.DEFAULT_ALL;

        try
        {
            notificationManager.notify(NOTIFICATION_NEW_MESSAGE, notification);
        }
        catch (SecurityException ex)
        {
            // This is required due to a bug in android
            // 
            Log.e("PPDirect", ex.getLocalizedMessage());
        }
    }
}

我有几个关于推送通知的问题:

  1. 哪个回调函数实际检查到达的消息并在推送通知到达时调用?
  2. 自从 google 已将 GCM 更新为 FCM 后,我是否需要更新密钥或将 GCM 迁移到 FCM?
  3. 还有其他原因吗?

如有任何帮助,我们将不胜感激。

1. which call back function actually checks for arrived message and is called once push notification arrives?

对于Android,一般在onMessageReceived中收到GcmListenerService。但是,这也可能取决于应用程序是在后台还是前台。

2. Is it possible that since google have updated GCM to FCM I need to make updates to the key or migrate GCM to FCM?

根据注释here

Starting from Sept. 2016 new server key can only be created in the Firebase Console using the Cloud Messaging tab of the Settings panel. Existing projects that need to create a new server key can be imported in the Firebase console without affecting their existing configuration.

GCM 的新用户需要创建一个 Firebase 项目,无论您是否打算使用 FCM,以获得服务器密钥。迁移步骤可以看我的回答here.

3. Can there be some other reason?

这太宽泛了,无法回答。也许是因为你的有效载荷结构或你的 onMessageReceived() 的实现等