Android GCM Manifest和应用程序设置和单元测试

时间:2013-08-12 08:21:58

标签: android push-notification google-cloud-messaging

虽然我已经按照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来发送消息)

2 个答案:

答案 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();

希望这有帮助。