Android GCM - 处理收到的消息

Posted

技术标签:

【中文标题】Android GCM - 处理收到的消息【英文标题】:Android GCM - Handling received messages 【发布时间】:2016-05-07 00:17:35 【问题描述】:

我正在尝试将 GCM 添加到我的应用中。 现在我只想查看接收消息的日志。

我的androidManifest.xml 包含以下内容:

    <!-- GCM Receiver -->
    <receiver
        android:name="com.x.android.gcm.MyBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <!--<action android:name="com.google.android.c2dm.intent.REGISTRATION" />-->
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="com.x.android" />
        </intent-filter>
    </receiver>
    <!-- GCM Listener -->
    <service
        android:name="com.x.android.gcm.MyGcmListenerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>
    <!-- GCM InstanceID Listener -->
    <service
        android:name="com.x.android.gcm.MyInstanceIDListenerService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID"/>
        </intent-filter>
    </service>
    <!-- GCM Registration -->
    <service
        android:name="com.x.android.gcm.RegistrationIntentService"
        android:exported="false">
    </service>

MainActivity我有:

private BroadcastReceiver mReceiver;
private boolean isReceiverRegistered;
...
protected void onCreate(Bundle savedInstanceState) 
    ...
    mReceiver= new MyBroadcastReceiver();
    registerReceiver();

    if (checkPlayServices()) 
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    
    ...


private void registerReceiver()
    if(!isReceiverRegistered) 
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(Preferences.REGISTRATION_COMPLETE));
        isReceiverRegistered = true;
    

MyBroadcastReceiver

public class MyBroadcastReceiver extends WakefulBroadcastReceiver 
    @Override
    public void onReceive(Context context, Intent intent) 
        ComponentName comp = new ComponentName(
                MyGcmListenerService.class.getPackage().getName(),
                MyGcmListenerService.class.getName());
        context.startService((intent.setComponent(comp)));
        setResultCode(Activity.RESULT_CANCELED);
    

RegistrationIntentService:

public class RegistrationIntentService extends IntentService 
    private static final String TAG = RegistrationIntentService.class.getSimpleName();
    public RegistrationIntentService()  super(TAG); 

    protected void onHandleIntent(Intent intent) 
        InstanceID instanceID = InstanceID.getInstance(this);
        String senderId = getString(R.string.gcm_defaultSenderId);
        try 
            String token = instanceID.getToken(senderId, GoogleCloudMessaging.INSTANCE_ID_SCOPE);
            sendRegistrationToServer(token);
            subscribeTopics(token); // /topics/global
         catch(...) ...
    
    Intent registrationComplete = new Intent(Preferences.REGISTRATION_COMPLETE);
    LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);

最后是MyGcmListenerService

public class MyGcmListenerService extends GcmListenerService 
    @Override
    public void onMessageReceived(String from, Bundle data) 
        String message = data.getString("message");
        Log.d(TAG, "From: " + from);
        Log.d(TAG, "Message: " + message);
    

我正在尝试的请求是:

"data":  "message": "direct message" , "to": "TOKEN" 
"data":  "message": "topic message" ,  "to": "/topics/global"

我都收到了成功的回复。

问题:

    为什么MyGcmListenerService 没有收到任何消息? 不应该将MyBroadcastReceiver 自动链接到应用程序,而不在MainActivity 中添加所有内容吗? 是使用GcmReceiver 更好还是使用自定义更好?为什么? MyGcmListenerService 不应该处理所有接收消息吗?如果没有,应该由它处理什么,由MyBroadcastReceiver处理什么?

【问题讨论】:

【参考方案1】:

首先更新广播,看看你在日志中得到了什么

public class MyBroadcastReceiver extends WakefulBroadcastReceiver 
    @Override
    public void onReceive(Context context, Intent intent) 

        Bundle extras = intent.getExtras();

        String string = "Bundle";
        for (String key : extras.keySet()) 
            string += " " + key + " => " + extras.get(key) + ";";
        
        string += " Bundle";

        Log.e("string","string"+string);

        ComponentName comp = new ComponentName(
                MyGcmListenerService.class.getPackage().getName(),
                MyGcmListenerService.class.getName());
        context.startService((intent.setComponent(comp)));
        setResultCode(Activity.RESULT_CANCELED);
    

【讨论】:

仍然,我没有收到任何消息。这个方法在我做请求的时候不会被调用。 我在其中实现的日志“字符串”中得到了什么 好吧,没什么,因为onReceive没有被调用。【参考方案2】:

检查这个希望这对你有帮助GCM-Example

【讨论】:

【参考方案3】:

似乎有一个延迟......从服务器发送到 GCM 的消息与在应用程序中接收到消息的时间之间存在很大的延迟。

我重新启动了手机,在它连接到我的 wifi 网络之前,我收到了所有消息。 如果我使用 4G 似乎没有延迟(可能与 3G 相同)。

在谷歌上搜索有关此延迟的信息,似乎它比应有的更常见:

    How to avoid delay in Android GCM messages Receive Android GCM messages so slow? Google Cloud Messaging - messages either received instantly or with long delay

我尝试了第一个 link 中介绍的解决方法,但是当我使用 wifi 时,我立即收到了一些消息,但过了一会儿它就停止了。 当我切换到 4G 时,我又开始接收它们了。

我观察到WhatApp 通知也会发生这种情况,因为在通过 wifi 或 4G 测试此推送通知时,我观察到当我切换到 4G 时,我从 2 小时前开始收到来自应用程序的通知。

另外,根据link#3 的说法,收到消息的最大延迟应该是几分钟,所以也可能是设备有问题,在这种情况下是 Nexus 5。

当我发现有关此问题的更多信息时,我可能会更新此答案。

【讨论】:

以上是关于Android GCM - 处理收到的消息的主要内容,如果未能解决你的问题,请参考以下文章

(新)GCM 消息收到,但如何解析?

未收到来自 Android GCM 的消息

未收到 GCM 消息

Android GCM 不向设备发送通知消息

除非删除 SEND 权限,否则不会收到 GCM 消息

发送 GCM 上游消息后收到空推送消息