0

尽管我已经按照 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" />

我的广播接收器和意图服务在清单中如下:

 <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 和 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 项目中发送发件人 ID。

2) 如果包名称有问题,我如何将 Android 应用程序的包名称与服务器上的包名称(如果有)匹配?

3) 上述广播接收器实现是否足以用于测试目的?或者除非我也写出服务,否则不会出现任何消​​息?(我不希望如此)

4) 如何对广播接收器进行单元测试?由于我目前无法操作服务器(只有一个 Web UI 来发送消息)

4

2 回答 2

0

GCM 会在您注册时隐式获取包名称。至于您的服务器获取包名称,如果您的服务器将 GCM 消息发送到多个应用程序,则需要这样做。在这种情况下,当您向服务器发送注册 ID 时,您需要发送指定此注册 ID 所属应用程序的附加数据。

广播接收器就足够了。您不需要意图服务。

我不确定你在最后一个问题中的意思。你有办法向你的应用程序发送消息吗?您需要发送消息以测试广播接收器。

于 2013-08-12T09:06:51.517 回答
0

它非常简单。

您的应用程序GCM serverregistration ID. register 方法需要上下文来内部获取包名。您无需明确将其发送到任何地方。

获得注册 ID 后,您将其发送到您的应用服务器。

然后,您的应用服务器使用相同RegId的方式向您发送任何推送消息。但应用服务器不会直接与您的手机通信。它使用注册 ID 和API_KEY.

GCM 服务器已经通过唯一的 reg id 知道您的手机。因此 GCM 服务器将推送消息进一步发送到您的手机。在整个过程中,只有 GCM SERVER 知道您和您的设备,没有其他人知道。所以整个过程只能通过 GCM Server 发生。

另外要理解的一件重要的事情是,在获取注册 ID 时使用的包名称会随每条推送消息一起发回。在广播接收器中,可以通过以下方式获取包名:

 String category = intent.getPackage();

希望这可以帮助。

于 2014-07-02T04:07:47.170 回答