0

我很难通过 c2dm 接收消息。实际上,我偶尔会收到来自我们服务器的消息,但实际上只是数据的一半。(我期待一个 4 位数字,但只收到前 2 位数字.. oO")。但是最近我们的广播接收器保持绝对沉默。因此我开始试验并将我自己的 c2dm 消息推送到谷歌服务器,看看情况如何是做。

在帖子的底部,您可以找到我如何发送和接收 c2dm 消息的示例类。这一切几乎都是独立的,因此您可以将其插入一些活动并拍摄C2dmStaticTest.autopilot( yourSenderId, "foo bar", yourServerSideAuthCode, this, this.getPackageName());

让我概述正在发生的事情:

  • 设置要在 BroadcastReceiver 中使用的静态变量
  • 注册广播接收器并设置动作和类别,androidManifest.xml否则它将如何。
  • 向 c2dm 服务器发送注册意图。

注意:本地内置广播接收器将为每个接收到的意图生成一条日志消息!每次在类中发出日志消息时,标签都会是“c2dmTest”。

当收到带有 registration_id 的 c2dm 答案时,这也会被记录下来,然后会推送一条 c2dm 消息。
我在这里尽可能地模拟我们的服务器以获得更多控制权。作为回测,我还发出了一条模拟实际 Intent 的 fakeC2DM 消息,并测试广播接收器在 RECEIVE 操作上的功能。

虽然我可以从 c2dm 服务器接收注册令牌,但我没有收到我推送到服务器的任何消息。正如介绍中提到的,当我们的 Web 服务器发送消息时,我观察到相同的行为。

我尽了最大努力,我相信我已经相应地实现了广播接收器,并且由于消息发送的服务器响应代码始终为 200/OK,我也相信消息已成功传递到服务器。

然而结果不是预期的,但我真的缺乏任何想法我还能做什么。寻找诸如“无法保证消息传递”之类的段落也不令人鼓舞。我的意思是现在根本没有交付任何东西:C

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

public class C2dmStaticTest {


    private static String       RECEIVE         = "com.google.android.c2dm.intent.RECEIVE";
    private static String       REGISTER        = "com.google.android.c2dm.intent.REGISTER";
    private static String       REGISTRATION    = "com.google.android.c2dm.intent.REGISTRATION";

    private static Context      ctx;
    private static String       packageName;
    private static String       message;
    private static String       auth_code;

    private static IntentFilter mIntFilt        = new IntentFilter();

    //@formatter:off
    private static BroadcastReceiver mBroadRec = new BroadcastReceiver() {

        @Override
        public void onReceive( Context context, Intent intent ) {
            final String broadcastAction = intent.getAction();
            C2dmStaticTest.log("localReceiver onReceive for action: "+ broadcastAction);

            if (C2dmStaticTest.REGISTRATION.equals(broadcastAction)) {
                //execution continues here upon arrival of registration_id
                String registration_id = intent.getStringExtra("registration_id");
                C2dmStaticTest.log("registered for c2dm.\n key is: "+registration_id);


                C2dmStaticTest.log("==> start real self test");
                selfTestC2DM(registration_id, message, auth_code);
                C2dmStaticTest.log("<== real self test done");


                C2dmStaticTest.log("==> start fake test");
                selfTestFake();
                C2dmStaticTest.log("<== fake test done");

                C2dmStaticTest.log("<~~ bye");

            } else if (C2dmStaticTest.RECEIVE.equals(broadcastAction)) {
                C2dmStaticTest.log("Received message: " + intent.getStringExtra("message") );
            }
        }
    };
    //@formatter:on

    public static void autopilot( String sender_id, String message, String auth_code, Context ctx, String packageName ) {
        // setup static variables
        C2dmStaticTest.ctx = ctx;
        C2dmStaticTest.packageName = packageName;
        C2dmStaticTest.message = message;
        C2dmStaticTest.auth_code = auth_code;

        C2dmStaticTest.log("==> register broadcastReceiver");
        mIntFilt.addAction("com.google.android.c2dm.intent.RECEIVE");
        mIntFilt.addAction("com.google.android.c2dm.intent.REGISTRATION");
        mIntFilt.addCategory(packageName);
        ctx.registerReceiver(mBroadRec, mIntFilt);

        C2dmStaticTest.log("==> register for c2dm");
        C2dmStaticTest.registerForC2dm(ctx, sender_id);
        // will continue in localBroadCastReceiver on Receive for REGISTRATION
    }

    private static void registerForC2dm( Context ctx, String sender_id ) {
        Intent registrationIntent = new Intent(C2dmStaticTest.REGISTER);
        registrationIntent.putExtra("app", PendingIntent.getBroadcast(ctx, 0, new Intent(), 0)); // boilerplate
        registrationIntent.putExtra("sender", sender_id);
        ctx.startService(registrationIntent);
    }

    private static void selfTestFake() {
        Intent intent = new Intent();
        intent.setAction(C2dmStaticTest.RECEIVE);
        intent.putExtra("message", "Bender: \"kiss my shiny metal ass!\"");
        intent.addCategory(C2dmStaticTest.packageName);
        C2dmStaticTest.ctx.sendBroadcast(intent);
    }

    public static void selfTestC2DM( String registration_id, String message, String auth_code ) {

        // create HttpClient
        HttpClient mHttpClient = new DefaultHttpClient();

        // create HttpPost
        final HttpPost post = new HttpPost("https://android.apis.google.com/c2dm/send");
        post.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        post.addHeader("Authorization", "GoogleLogin auth=" + auth_code);

        // set payload data ...
        final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("registration_id", registration_id));
        nameValuePairs.add(new BasicNameValuePair("collapse_key", "foo"));
        nameValuePairs.add(new BasicNameValuePair("data.message", message));

        // ... and push it in the post
        try {
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        } catch (final Exception e) {
            e.printStackTrace(); // never had a problem here
        }

        // start it!
        try {
            HttpResponse resp = mHttpClient.execute(post);
            if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // now the message should be send, not?
                C2dmStaticTest.log("Message send.\nServer response: " + resp.getStatusLine().getStatusCode());
            } else {
                C2dmStaticTest.log("Unexpected Server response.\nServer response: " + resp.getStatusLine().getStatusCode());
            }
        } catch (final Exception e) {
            C2dmStaticTest.log("Unexpected Exception in execute()");
            e.printStackTrace();

        }
    }

    public static void log( String message ) {
        Log.d("c2dmTest", message);
    }
}
4

1 回答 1

0

好的,将其呈现给我们的服务器人员,我了解到这status code: 200仅表明通信成功,而不是数据可能存在语义错误。

在这种情况下,我实际上还收到了一个 JSONObject 说明键不匹配的错误。
这就是我所说的各级沟通问题...

于 2012-05-03T19:45:25.810 回答