【问题标题】:c2dm messages never receivedc2dm 消息从未收到
【发布时间】:2012-05-04 03:45:25
【问题描述】:

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

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

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

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

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

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

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

我尽了最大的努力,我相信我已经相应地实现了广播接收器,并且由于消息发送的服务器响应代码始终为 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);
    }
}

【问题讨论】:

    标签: android android-c2dm


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多