[英]Hard to understand Android C2DM
我已經按照Vogella C2DM教程的教程,就像大多數人試圖理解C2DM一樣,這是一個很好的教程來獲取代碼,但它並沒有真正幫助我理解如何使用它。 我已經設置了我的Android類和我的服務器(移植到php),但現在我不知道如何繼續。 我的代碼如下所示:
c2dm.php(服務器端)
function googleAuthenticate($username, $password, $source="Company-AppName-Version", $service="ac2dm") {
session_start();
if( isset($_SESSION['google_auth_id']) && $_SESSION['google_auth_id'] != null)
return $_SESSION['google_auth_id'];
// get an authorization token
$ch = curl_init();
if(!ch){
return false;
}
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
$post_fields = "accountType=" . urlencode('HOSTED_OR_GOOGLE')
. "&Email=" . urlencode($username)
. "&Passwd=" . urlencode($password)
. "&source=" . urlencode($source)
. "&service=" . urlencode($service);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// for debugging the request
//curl_setopt($ch, CURLINFO_HEADER_OUT, true); // for debugging the request
$response = curl_exec($ch);
//var_dump(curl_getinfo($ch)); //for debugging the request
//var_dump($response);
curl_close($ch);
if (strpos($response, '200 OK') === false) {
return false;
}
// find the auth code
preg_match("/(Auth=)([\w|-]+)/", $response, $matches);
if (!$matches[2]) {
return false;
}
$_SESSION['google_auth_id'] = $matches[2];
}
function sendMessageToPhone($authCode, $deviceRegistrationId, $msgType, $messageText) {
$headers = array('Authorization: GoogleLogin auth=' . $authCode);
$data = array(
'registration_id' => $deviceRegistrationId,
'collapse_key' => $msgType,
'data.message' => $messageText //TODO Add more params with just simple data instead
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");
if ($headers)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
C2DMRegistrationReceiver.java
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.w("C2DM", "Registration Receiver called");
if ("com.google.android.c2dm.intent.REGISTRATION".equals(action)) {
Log.w("C2DM", "Received registration ID");
final String registrationId = intent
.getStringExtra("registration_id");
String error = intent.getStringExtra("error");
Log.d("C2DM", "dmControl: registrationId = " + registrationId
+ ", error = " + error);
// TODO Send this to my application server
}
}
public void sendRegistrationIdToServer(String deviceId, String registrationId) {
Log.d("C2DM", "Sending registration ID to my application server");
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("myserverpage");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
// Get the deviceID
nameValuePairs.add(new BasicNameValuePair("deviceid", deviceId));
nameValuePairs.add(new BasicNameValuePair("registrationid", registrationId));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd =
new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
Log.e("HttpResponse", line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
C2DMMessageReceiver.java
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.w("C2DM", "Message Receiver called");
if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) {
Log.w("C2DM", "Received message");
final String payload = intent.getStringExtra("payload");
Log.d("C2DM", "dmControl: payload = " + payload);
// Send this to my application server
}
}
在我的MainActivity中,我有
public void register() {
Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
intent.putExtra("app",PendingIntent.getBroadcast(this, 0, new Intent(), 0));
intent.putExtra("sender", "app-name@gmail.com");
startService(intent);
}
我在應用程序啟動期間調用register(),在LogCat中調用“Message Receiver called”,而不是“Register Receiver called”。 我當然將app-name@gmail.com更改為我自己的等等,但我現在不知道如何使用代碼。 誰可以幫助我?
提前致謝!
關於Vogella的教程非常簡單明了。 如果您一步一步地遵循它,您將不會有這么難的理解。
您的記錄器顯示消息接收器被調用,因為這是您使用C2DMMessageReceiver記錄的內容。 如果您有另一個用於注冊的接收器,請確保在清單中聲明它並在此處發布代碼。
我建議使用相同的接收器類。 例如,這是一個簡單的onReceive
方法:
if (action != null){
// This is for registration
if (action.equals("com.google.android.c2dm.intent.REGISTRATION")){
Log.d(LOG_TAG, "Received registration ID");
final String registrationId = intent.getStringExtra("registration_id");
String error = intent.getStringExtra("error");
Log.d(LOG_TAG, "dmControl: registrationId = " + registrationId + ", error = " + error);
// Create a notification with the received registration id
// Also save it in the preference to be able to show it later
// Get the device id in order to send it to the server
String deviceId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
// .. send it to the server
}
// This is for receiving messages
else if (action.equals("com.google.android.c2dm.intent.RECEIVE")){
String payload = intent.getStringExtra("payload");
Log.d(LOG_TAG, "Message received: " + payload);
// .. create a notification with the new message
}
我添加了注釋,您可以在其中添加更多操作(例如創建通知,將注冊ID發送到第三方服務器等)。 在Lars Vogel的教程中也可以找到如何執行上述操作的示例。
在我的情況下,我使用單接收器:
if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
String registrationId = intent.getStringExtra("registration_id");
//do somting
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
Bundle extras = intent.getExtras();
String message = extras.getString("message");
}// end if
}
在清單中
<receiver
android:name=".receiverName"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="packageName" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="packageName" />
</intent-filter>
我將解釋我所理解的內容。
首先,在android c2dm網站注冊,你的Android應用程序包名稱在你擁有的gmail id下說com.example.app。
開發一個Android應用程序應該能夠將設備注冊ID作為請求發送到服務器。 服務器應該將這些ID存儲在db中。
一旦准備好從服務器向所有設備發送一些消息,您只需要為在c2dm中注冊的gmail id和已存儲在db中的設備ID提供新的auth_token。
Vogella教程提供了用於獲取設備和auth_token的regid的示例代碼。 我已經嘗試過並將其用於我的應用程序的修改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.