无法使用 GCM 在设备上接收消息

Posted

技术标签:

【中文标题】无法使用 GCM 在设备上接收消息【英文标题】:can't receive messages on device using GCM 【发布时间】:2013-04-13 20:20:30 【问题描述】:

我已按照 google 说明启动 gcm 服务器和客户端。 我的问题是虽然我从服务器获得了成功的 gcm:

MulticastResult(multicast_id=8287827393174436535,total=1,success=1,failure=0,canonical_ids=0,结果: [[ messageId=0:1366468335181772%8e1522ac00000031 ]]

我看不到在客户端接收消息的任何动作 - 未调用 onMessage()。 据我所知,客户端 ID 和服务器 ID 都是正确的。

我会很感激任何帮助... :)

服务器端代码:

try 

Sender sender = new Sender(API_KEY);
Message message = new Message.Builder().collapseKey("1")
        .timeToLive(3)
        .delayWhileIdle(true)
        .addData("message",
                "this text will be seen in notification bar!!").build();

ArrayList<String> devices = new ArrayList<String>();

devices.add(DEVICE_ID1); 
//devices.add(DEVICE_ID2);

MulticastResult result = sender.send(message, devices, 2);
//Result result = sender.send(message, DEVICE_ID1, 2);
System.out.println(result.toString());
if (result.getResults() != null) 
    int canonicalRegId = result.getCanonicalIds();
    if (canonicalRegId != 0) 
    
 else 
    int error = result.getFailure();
    System.out.println(error);

 catch (Exception e) 
    // TODO: handle exception

客户端代码: 注册:

GCMRegistrar.checkDevice(this);
        GCMRegistrar.checkManifest(this);
        final String regId = GCMRegistrar.getRegistrationId(this);
        if (regId.equals("")) 
          GCMRegistrar.register(this, SENDER_ID); // Note: get the sender id from configuration.
          String regIdString = GCMRegistrar.getRegistrationId(this);
          Log.v(TAG, "RegisterId, regId: " + regIdString);
         else 

          Log.v(TAG, "Already registered, regId: " + regId);
        

和 gcmIntentServiceCreated(部分):

public class GCMIntentService extends GCMBaseIntentService 
public GCMIntentService()
        super(SENDER_ID);       
    
@Override
    protected void onMessage(Context context, Intent intent) 
         Log.i("Registration", "Got a message!");
             Log.i("Registration", context.toString() + " " + intent.toString());
    
...

客户清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <permission android:protectionLevel="signature" android:name="com.example.myapp.permission.C2D_MESSAGE"></permission>
    <uses-permission android:name="com.example.myapp.permission.C2D_MESSAGE"/>
    <!-- App receives GCM messages. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <!-- GCM connects to Google Services. -->
    <uses-permission android:name="android.permission.INTERNET" /> 
    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.myapp.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name="com.google.android.gcm.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="com.example.myapp" />
          </intent-filter>
        </receiver>
        <service android:name=".GCMIntentService" />
    </application>

</manifest>

【问题讨论】:

【参考方案1】:

为了最大限度地提高您收到消息的机会,我不会将 time_to_live 设置为仅 3 秒。我将完全省略此参数,以便它采用默认值 4 周。我还将 delay_while 设置为 false,以便手机即使在空闲时也能收到消息。

【讨论】:

谢谢,但没有帮助。服务器发送了它的消息,但即使模拟器在客户端应用程序中打开,它看起来不像收到消息,因为它不在 logcat 上。 可惜,除了用调试器检查注册ID是否正确(在“已经注册”位中有断点)之外,不知道有什么建议【参考方案2】:

您的消息肯定会发送到您的设备,因为 gcm 发送的成功状态为 1。请尝试检查您应用的 GCMReceiver 代码。

【讨论】:

谢谢,有一个 GCMReceiver 代码,据我所知,我的类扩展 GCMBaseIntentService 应该做接收? 是的。这就是我的意思。检查接收器的正确性。因为似乎 gcm 发件人正在发送。所以在那之后检查 wat 出了问题【参考方案3】:

在您的 onMessage 方法中更改以下代码:

Log.i("Registration", "Got a message!");
             Log.i("Registration", context.toString() + " " + intent.toString());

到这里:

String message=intent.getStringExtra("message"); 
Log.w("The message received is", message);

希望有帮助

【讨论】:

以上是关于无法使用 GCM 在设备上接收消息的主要内容,如果未能解决你的问题,请参考以下文章

GCM 无法使用公司 Google 帐户

无法使用 Node.js + XMPP 接收上游 GCM 消息

GCM(谷歌云消息)无法覆盖所有注册用户?

在 Android 上的代理后面接收 FCM (GCM)

当设备连接互联网时,我无法收到旧消息-GCM

Android GCM - 无法接收消息