虽然我已经按照Android Dev Site上的教程(我正在使用更新的GCM API),但我想确保我已经完成了关于GCM设置的一切,所以我会将其分解进入以下部分:
清单文件:
1)我的应用程序包名称是:package =“com.abc.xyz.demo”
<permission android:name="com.abc.xyz.demo.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.abc.xyz.demo.permission.C2D_MESSAGE" />
我的广播接收器&amp;意图服务在清单中如下:
<receiver
android:name="com.abc.xyz.demo.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.abc.xyz.demo" />
</intent-filter>
</receiver>
<service android:name="com.abc.xyz.demo.gcm.GCMIntentService" />
com.abc.xyz.demo.gcm包中有GCMBroadcastReceiver&amp; GCMIntentService。我现在只使用广播接收器(因为教程提到IntentService是可选的),如下所示:
public class GCMBroadcastReceiver extends BroadcastReceiver
{
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
Context ctx;
public TWGCMBroadcastReceiver()
{
Log.i("GCMAudit", "Receiver Instaniated!");
}
@Override
public void onReceive(Context context, Intent intent)
{
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
ctx = context;
String messageType = gcm.getMessageType(intent);
if (messageType != null && messageType.length() > 0)
{
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);
}
else
{
setResultCode(Activity.RESULT_CANCELED);
}
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg)
{
mNM = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent cI = PendingIntent.getActivity(ctx, 0, new Intent(ctx, Main.class), 0);
...
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
请注意我可以成功注册,并将regId发送到我们的应用服务器(我现在无法直接访问服务器)
这里有一些常见问题:
1)我们的Web应用程序服务器或GCM是否需要知道我的软件包名称?如果是这样,我是否需要明确发送出去?目前我只是从Google Project中发送发件人ID。
2)如果包名称存在问题,我如何将Android应用程序的包名称与服务器上的包名称(如果有)匹配?
3)上述广播接收机实施是否足以用于测试目的?或者除非我也写出服务,否则不会出现任何消息? (我不希望如此)
4)我如何对广播接收机进行单元测试?由于我目前无法操纵服务器(只有一个Web UI来发送消息)
答案 0 :(得分:0)
当您注册时,GCM会隐式获取包名称。至于您的服务器获取程序包名称,如果您的服务器将GCM消息发送到多个应用程序,则需要该名称。在这种情况下,当您向服务器发送注册ID时,您将需要发送指定此注册ID所属的应用程序的其他数据。
广播接收器就足够了。您不需要意向服务。
我不确定你在上一个问题中的意思。您是否有办法向您的应用发送消息,或者不是吗?您需要发送消息才能测试广播接收器。
答案 1 :(得分:0)
非常简单。
您的应用与GCM server
对话并获得registration ID
。 register方法需要上下文来内部获取包名。您不需要明确地将其发送到任何地方。
获得注册ID后,您将其发送到您的应用服务器。
您的应用服务器然后使用相同的RegId
向您发送任何推送消息。但应用服务器无法直接与您的手机通信。它使用注册ID和API_KEY
将消息发送到GCM服务器。
GCM服务器已通过唯一的注册ID了解您的手机。因此GCM服务器将推送消息进一步发送到您的移动设备。在整个过程中,只有GCM SERVER能够识别您和您的设备以及 NO ONE 。因此整个过程只能通过GCM Server发生。
另外一个重要的事情是,获取注册ID时使用的包名称会随每个推送消息一起发回。在广播接收器中,可以通过以下方式获得包名称:
String category = intent.getPackage();
希望这有帮助。