无法收到使用Google Cloud Messaging for Android(非helper库)的消息

7
有没有人能帮我提供一个使用 Google Cloud Messaging for Android 接收消息的工作示例?我已经尝试了两种方式(辅助库和 GoogleCloudMessaging 类),但似乎都不起作用。我正在使用一个显示以下内容的 PHP 脚本:

多播 ID:5.2108110103215E+18 成功处理的消息数:1 处理错误的消息数:0 规范化 ID:0

所以显然一切正常。我可以使用辅助库(gcm.jar)和使用 GoogleCloudMessaging 类的两种方式注册设备。问题是,没有办法让我通过 PHP 发送的消息到达,或者至少我不知道如何正确处理它。这是我的清单中的权限和接收器:
<permission android:name="com.example.gcm.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />    
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />

<receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>

            <!-- Receives the actual messages. -->
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <!-- Receives the registration id. -->
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.example.gcm" />
        </intent-filter>
    </receiver>
<service android:name=".GCMIntentService" />

最后,这是服务类

public class GCMIntentService extends GCMBaseIntentService {

private static final String PROJECT_ID = "49XXXXXXXX6";    
private static final String TAG = "GCM Intent Service";

public GCMIntentService()
{
    super(PROJECT_ID);
    Log.d(TAG, "GCMIntentService init");
}


@Override
protected void onError(Context ctx, String sError) {

    Log.d(TAG, "Error: " + sError);     
}

@Override
protected void onMessage(Context ctx, Intent intent) {

    Log.d(TAG, "Message Received");

    String message = intent.getStringExtra("message");

    sendGCMIntent(ctx, message);

}


private void sendGCMIntent(Context ctx, String message) {

    Intent broadcastIntent = new Intent();
    broadcastIntent.setAction("GCM_RECEIVED_ACTION");

    broadcastIntent.putExtra("gcm", message);

    ctx.sendBroadcast(broadcastIntent);

}

@Override
protected void onRegistered(Context ctx, String regId) {

    Log.d(TAG, regId);

    // Notify main UI to update registration status
    Intent registrationIntent = new Intent();
    registrationIntent.setAction("registered");
    registrationIntent.putExtra("regId", regId);
    sendBroadcast(registrationIntent);      
}

@Override
protected void onUnregistered(Context ctx, String regId) {
    //...

}
}

以下是使用GoogleCloudMessaging类的代码(我更改了清单文件以使用自定义接收器):
public class GCMBroadcastReceiver extends BroadcastReceiver {

private static final String TAG = "GCM Receiver";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
private Context ctx;

@Override
public void onReceive(Context context, Intent intent) {

    Log.d(TAG, "Message received");

    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
    ctx = context;
    String messageType = gcm.getMessageType(intent);
    if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
        sendNotification("Send error: " + intent.getExtras().toString());
    }
    else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
            .equals(messageType)) {
        sendNotification("Deleted messages on server: "
                + intent.getExtras().toString());
    }
    else {
        sendNotification("Received: " + intent.getExtras().toString());
    }
    setResultCode(Activity.RESULT_OK);
}

// Put the GCM message into a notification and post it.
private void sendNotification(String msg) {
    mNotificationManager = (NotificationManager) ctx
            .getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
            new Intent(ctx, MainActivity.class), 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            ctx).setSmallIcon(R.drawable.ic_launcher_temp)
            .setContentTitle("GCM Notification")
            .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
            .setContentText(msg);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}

问题在于一切看起来都很正常,但是消息却没有到达。有什么想法吗?

提前感谢。


这里有非常好的教程:http://tech-papers.org/google-cloud-messaging-gcm-for-android-and-push-notifications-2/ - Balwinder SIngh
5个回答

7
请在您的清单文件中添加以下内容。
 <permission
    android:name="PACKAGE_NAME.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE" />

<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

抱歉,你是对的,但是在将清单复制到帖子时出现了问题。我的清单实际上有权限,并且我已经更新了帖子。还有其他想法吗?谢谢。 - Alejandro Casanova

2
你的清单文件缺少一些权限:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

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

编辑:

在你的清单文件中,你正在使用com.google.android.gcm.GCMBroadcastReceiver。这是旧的助手库(gcm.jar)中的一个类,它启动一个意图服务。如果你想使用助手库,你应该在清单文件中定义意图服务。

如果你不想使用助手库,你应该将清单文件中的GCMBroadcastReceiver包更改为你在问题中包含的GCMBroadcastReceiver类的包。否则,该类将不会被使用。


抱歉,你是对的,但是在将清单复制到帖子时出现了问题。我的清单实际上有权限,并且我已经更新了帖子。还有其他想法吗?谢谢。 - Alejandro Casanova
如果您正在使用您在问题中提到的GCMBroadcastReceiver类,则不需要GCMIntentService。但是,您的清单引用了com.google.android.gcm.GCMBroadcastReceiver。您在问题中包含的GCMBroadcastReceiver的包是什么?它可能不是com.google.android.gcm(如果是,那就不应该是)。我猜测您的清单引用了Google默认的GCMBroadcastReceiver,这就是为什么您的代码无法工作的原因。 - Eran
我已经使用缺失的GCMIntentService更新了清单。实际上,我有两个示例,但都无法正常工作。第一个示例使用带有GCMIntentService和辅助库的当前清单。我认为这次没有遗漏任何内容。 第二个项目不使用辅助库,清单中的接收器如下:这次没有GCMIntentService。第二个示例中的接收器是问题所在。仍然卡住了 :( - Alejandro Casanova

1
在纠正了上述问题后,仍然无法推送消息。问题在于403错误。看起来该服务在古巴不可用,因此解决方案是使用类似“your freedom”或“thor”等工具。

0

你正在使用已被Google弃用的GCMBaseIntentService。(但它应该仍然可以工作。)我按照最新的教程http://developer.android.com/google/gcm/client.html操作,并成功接收到了消息。你也可以试一试。

另一个可能的原因是你可能已经收到了消息,但通知没有成功显示。在方法中添加这行代码:sendNotification(String msg)

    Log.i(TAG, msg);

0

别忘了将 'com.example.gcm' 改为你的包名,例如 'com.yourdomain.yourapp'


那是我用于演示应用程序的包。 - Alejandro Casanova

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接