在Android上使用C2DM的人

10

我需要在我的应用中实现c2dm。是否有其他人也在这方面做过?请帮忙...一些教程将非常有帮助。或者,如果您已经完成了c2dm的实现,则更加感激您的教程。

请帮帮忙。


我已经实现了C2DM,它对我来说运行良好。你可以查看这个链接http://github.com/commonsguy/cw-advandroid/tree/9b93f41fd825dedb10365776fde2e22200737072/Push/C2DM,希望这能帮到你。 - Sunit Kumar Gupta
你如何实现第三方服务器部分?你使用了哪种语言——php/pyhtong?你能帮我实现服务器端吗? - mudit
服务器端的实现是通过使用PHP完成的。它简单地接收来自设备的registration_id和device_id并将其存储在表中。服务器通过使用curl URL(在示例中给出)从c2dm服务器获取身份验证令牌,然后返回一个auth token,接着使用下一个URL向设备发送通知。 - Sunit Kumar Gupta
嗨,Mudit,你能帮我吗? - Sunit Kumar Gupta
我尝试了您提供的链接,但是我收到了以下错误信息:E/AndroidRuntime(1508): java.lang.RuntimeException: Unable to instantiate 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]。请问您可以帮我解决这个问题吗?另外,能否告诉我服务器如何发送消息? - user881928
2个回答

26

我下载了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的消息。然后您可以使用该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返回“...<H1>未经授权</H1><H2>错误401</H2>...”。有任何想法是出了什么问题吗? - Thomas Ahle
你确定你正在正确使用令牌吗?你必须从响应中取一个子字符串。 - blindstuff
一切似乎都很好,请尝试使用虚假的电子邮件和/或密码进行注册,以便您知道这是错误的凭据,检查是否返回了Auth Token,如果返回了,则可能存在注册问题,如果没有,则我们可以排除该问题。 我刚刚重新运行了我在这里描述过的测试服务器,它仍然正常工作,我的猜测是您可能没有被列入白名单,或者您正在使用错误的电子邮件或类似的东西。 - blindstuff
使用另一个电子邮件地址会出现“Error=BadAuthentication”。很奇怪。 - Thomas Ahle
这是我在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"); - blindstuff
@blindstuff 谢谢,我把账户从托管的换成了 Gmail,并记得使用 "auth=" 而不是 "Auth="。这样修复了它。 - Thomas Ahle

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接