任何在 Android 上做 C2DM 的人

Posted

技术标签:

【中文标题】任何在 Android 上做 C2DM 的人【英文标题】:Anyone doing C2DM on Android 【发布时间】:2010-10-25 12:12:15 【问题描述】:

我需要在我的应用程序中实现 c2dm。有没有人也在这样做?请帮助..一些教程将非常有帮助,或者如果您已完成 c2dm 实现,那么教程将不胜感激。

请帮忙。

【问题讨论】:

我实现了 C2DM,它对我来说运行良好。你可以查看这个链接github.com/commonsguy/cw-advandroid/tree/…我希望这对你有帮助。 如何实现第三方服务器部分。您使用的是哪种语言——php/pyhtong?你能帮我实现服务器端吗? 使用 php 完成服务器端实现。很简单,它从设备接收 registration_id 和 device_id 并将其存储在一个表中。服务器使用 curl URL(在示例中给出)从 c2dm 服务器获取身份验证令牌,服务器返回一个身份验证令牌,然后使用下一个 URL 向设备发送通知。 嗨,你能帮帮我吗? 我尝试了你提供的链接,我得到 E/AndroidRuntime(1508): java.lang.RuntimeException: Unable to instance service com.commonsware.android.c2dm.C2DMReceiver: java.lang. ClassNotFoundException: com.commonsware.android.c2dm.C2DMReceiver in loader dalvik.system.PathClassLoader[/data/app/com.commonsware.android.c2dm-2.apk] .. 你能帮我解决这个问题,还告诉我服务器将如何发送消息 【参考方案1】:

我继续下载了适用于 Android 的 Chrome2Phone 源代码,并通过该示例了解了它的工作原理,我在实现应用程序的服务器端时遇到了最大的麻烦。

从以下位置下载: http://code.google.com/p/chrometophone/source/checkout

或svn它:

svn checkout http://chrometophone.googlecode.com/svn/trunk/ chrometophone-read-only

你应该了解的基本知识。

在 C2DMBaseReciever 类中你有:

@Override
    public final void onHandleIntent(Intent intent) 
        try 
            Context context = getApplicationContext();
            if (intent.getAction().equals(REGISTRATION_CALLBACK_INTENT)) 
                handleRegistration(context, intent);
             else if (intent.getAction().equals(C2DM_INTENT)) 
                onMessage(context, intent);
             else if (intent.getAction().equals(C2DM_RETRY)) 
                C2DMessaging.register(context, senderId);
            
         finally 
            //  Release the power lock, so phone can get back to sleep.
            // The lock is reference counted by default, so multiple 
            // messages are ok.

            // If the onMessage() needs to spawn a thread or do something else,
            // it should use it's own lock.
            mWakeLock.release();
        
    

此方法从 C2DM 服务接收意图并处理它们。

在 handleRegistration 方法中,你会看到一些类似这样的代码:

 else 
            try 
                onRegistrered(context, registrationId);
                C2DMessaging.setRegistrationId(context, registrationId);
                //Add some code here to send your server the registration ID for this phone.
             catch (IOException ex) 
                Log.e(TAG, "Registration error " + ex.getMessage());
            
        

然后您必须使用 google oAuth 登录服务将您的服务器注册到该服务,完成后您可以发送消息。我在测试时使用 curl 向服务器发送 http post 请求。

从服务器注册:

curl https://www.google.com/accounts/ClientLogin -d Email=theEmailYouWhitelisted -d Passwd=pass****word -d accountType=HOSTED_OR_GOOGLE -d source=Google-cURL-Example -d service=ac2dm

您将收到一条带有身份验证 ID 的消息。然后,您使用它来发送消息。要发送消息,请使用:

curl --header "Authorization: GoogleLogin auth=**authFromRegistrationAbove**" "https://android.apis.google.com/c2dm/send" -d registration_id=**phoneRegistrationId(reciever)** -d "data.message=StringToPass" -d collapse_key=something -k

从以下位置下载 curl: CURL

希望这会有所帮助。

【讨论】:

我得到了身份验证令牌,但在 /send 上运行 curl 会返回“...

未授权

错误 401

...”。知道可能出了什么问题吗?
您确定您使用的令牌正确吗?您必须从响应中获取子字符串。 一切似乎都很好,尝试使用伪造的电子邮件和/或密码进行注册,以便您知道其凭据错误,检查是否返回 Auth Token,如果返回,可能是您的注册,如果没有,我们可以排除。我刚刚重新运行了我在这里描述的测试服务器,它仍然工作得很好,我猜你要么没有被列入白名单,要么你使用了错误的电子邮件或类似的东西。 使用另一个电子邮件地址给我Error=BadAuthentication。很奇怪。 这是我在 PHP 服务器中使用的 exec。复制它并尝试一下,它有效。 exec("curl --header \"Authorization: GoogleLogin auth=".$auth."\" \"https://android.apis.google.com/c2dm/send\" -d registration_id=".$id." -d \"data.message=".$mensaje."\" -d collapse_key=something -k");【参考方案2】:

关于 c2dm 客户端/服务器注册和发送/接收消息的教程。

http://android.arnodenhond.com/tutorials/cloud-to-device-messaging

打算申请一个注册ID receiver 接收注册 ID 调用注册服务器的url 发送消息的调用网址 广播接收者接收消息

【讨论】:

以上是关于任何在 Android 上做 C2DM 的人的主要内容,如果未能解决你的问题,请参考以下文章

Android C2DM ROLE 账号和包名

com.google.android.c2dm.intent.RECEIVE 还在使用吗?

如何在android中实现C2DM?

Android中关于C2DM的一些查询

将数据从 web 服务推送到 android 应用程序:C2DM

c2dm android推送通知每天广播量