2012-05-03 90 views
0

我跟着大多數人試圖理解C2DM的教程一樣,這是一個很棒的教程來獲取代碼,但它並沒有真正幫助我理解如何使用它。我建立了我的Android類和我的服務器(移植到php),但現在我不知道如何繼續。我的代碼如下所示:難以理解的Android C2DM

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", "[email protected]"); 
    startService(intent); 
} 

我在我的應用程序啓動期間調用register(),並在LogCat中顯示「Message Receiver called」,而不是「Registration Receiver called」。我當然已將[email protected]更改爲我自己的等等,但我現在不知道如何使用代碼。任何人都可以幫助我?

在此先感謝!

+0

對於Android C2DM,清單代碼與源代碼一樣重要,有太多的聲明可以省略並導致其無法正常工作。 – Warpzit

回答

2

上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的教程中找到。

+0

非常感謝!我會在幾分鐘之內檢查它並回復它的過程! – simtaxman

+0

我似乎現在已經掌握了它,我只是要用我的代碼來實現它,等等,但感謝您的幫助! – simtaxman

+0

不客氣。 –

0
在我的情況

我使用單接收器兩個:

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> 
+0

Okey,我忘了,但我的清單也有正確的權限。但我該如何從註冊 - >發送消息 - >在我的應用程序中接收它?這是我的問題,對如何使用它的全部理解。 – simtaxman

0

我只會解釋我所理解的。

  1. 首先,在Android的C2DM網站與Android應用程序包名註冊說,你擁有一個Gmail ID下com.example.app 。

  2. 開發一個android應用程序應該能夠發送設備註冊標識到服務器作爲請求。服務器應該將這些ID存儲在db中。

  3. 一旦你準備推一些消息,從服務器上的所有設備,你只需要爲你在你已經存儲在數據庫C2DM和 設備ID註冊了Gmail的ID新鮮的auth_token。

Vogella教程有獲取設備和auth_token的regid的示例代碼。我已經嘗試過,並用它來修改我的應用程序。