2011-06-08 235 views
11

我正在開發一個應用程序,並在該應用程序中需要實現推送通知。任何人都可以建議我應該如何去實施推送通知?如果我可以提供一個很好的教程,那會很棒!Android C2DM推送通知

謝謝。

+0

這是最好的教程,看看[視頻教程](http://www.youtube.com/watch?feature=player_embedded&v=M7SxNNC429U) – 2012-05-06 08:09:46

回答

15

//調用時,你的應用程序啓動

public void StartRegistrationNotification() 
    { 

     Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER"); 
     registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0)); 
     registrationIntent.putExtra("sender", "[email protected]"); 
     this.startService(registrationIntent); 

} 

清單文件//改變

<receiver android:name="com.ReceiverC2DM" 
     android:permission="com.google.android.c2dm.permission.SEND"> 
     <!-- Receive the actual message --> 
     <intent-filter> 

      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <category android:name="yourpackagename" /> 
     </intent-filter> 
     <!-- Receive the registration id --> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
      <category android:name="yourpackagename" /> 
     </intent-filter> 
    </receiver> 
    <permission android:name="yourpackagename.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 
<uses-permission android:name="yourpackagename.permission.C2D_MESSAGE" /> 
<!-- This app has permission to register and receive message --> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 

// ReceiverC2DM.java .....

public class ReceiverC2DM extends BroadcastReceiver { 

    private static String KEY = "c2dmPref"; 
    private static String REGISTRATION_KEY = "registrationKey"; 
    private Context context; 

    // wakelock 
    private static final String WAKELOCK_KEY = "C2DM_FAX"; 
    private static PowerManager.WakeLock mWakeLock; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     this.context = context; 

     runIntentInService(context, intent); 

     if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) { 
      handleRegistration(context, intent); 
     } else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { 
      handleMessage(context, intent); 
     } 
    } 

    private void handleRegistration(Context context, Intent intent) { 
     String registration = intent.getStringExtra("registration_id"); 
     Log.e("registration :","registration :"+registration); 

     if (intent.getStringExtra("error") != null) { 
      // Registration failed, should try again later. 
      Log.d("c2dm", "registration failed"); 
      String error = intent.getStringExtra("error"); 
      if(error == "SERVICE_NOT_AVAILABLE"){ 
       Log.d("c2dm", "SERVICE_NOT_AVAILABLE"); 
      }else if(error == "ACCOUNT_MISSING"){ 
       Log.d("c2dm", "ACCOUNT_MISSING"); 
      }else if(error == "AUTHENTICATION_FAILED"){ 
       Log.d("c2dm", "AUTHENTICATION_FAILED"); 
      }else if(error == "TOO_MANY_REGISTRATIONS"){ 
       Log.d("c2dm", "TOO_MANY_REGISTRATIONS"); 
      }else if(error == "INVALID_SENDER"){ 
       Log.d("c2dm", "INVALID_SENDER"); 
      }else if(error == "PHONE_REGISTRATION_ERROR"){ 
       Log.d("c2dm", "PHONE_REGISTRATION_ERROR"); 
      } 
     } else if (intent.getStringExtra("unregistered") != null) { 
      // unregistration done, new messages from the authorized sender will be rejected 
      Log.d("c2dm", "unregistered"); 

     } else if (registration != null) { 
      Log.d("c2dm", registration); 
      Editor editor = 
       context.getSharedPreferences(KEY, Context.MODE_PRIVATE).edit(); 
      editor.putString(REGISTRATION_KEY, registration); 
      editor.commit(); 
      // Send the registration ID to the 3rd party site that is sending the messages. 
      // This should be done in a separate thread. 
      // When done, remember that all registration is done. 
     } 
    } 


    private void handleMessage(Context context, Intent intent) 
    { 

    String message = intent.getExtras().getString("payload"); 
    String key = intent.getExtras().getString("collapse_key"); 
    Log.e("","accountName : " +accountName); 
    Log.e("","message : " +message);  
      Intent startActivity = new Intent(); 
      startActivity.setClass(context, NotificationAlert.class); 
      startActivity.setAction(NotificationAlert.class.getName()); 
      startActivity.setFlags( 
        Intent.FLAG_ACTIVITY_NEW_TASK 
        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);  
      startActivity.putExtra("Title", "Hello"); 
      startActivity.putExtra("Message", message); 
      context.startActivity(startActivity); 

     //Do whatever you want with the message   
    } 

    static void runIntentInService(Context context, Intent intent) { 
     if (mWakeLock == null) { 
       // This is called from BroadcastReceiver, there is no init. 
       PowerManager pm = 
         (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
       mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 
           WAKELOCK_KEY); 
     } 
     mWakeLock.acquire(); 
    } 

//服務器端...新測試應用程序

ServerSimulator.java

private SharedPreferences prefManager; 
private final static String AUTH = "authentication"; 

private static final String UPDATE_CLIENT_AUTH = "Update-Client-Auth"; 

public static final String PARAM_REGISTRATION_ID = "registration_id"; 

public static final String PARAM_DELAY_WHILE_IDLE = "delay_while_idle"; 

public static final String PARAM_COLLAPSE_KEY = "collapse_key"; 

private static final String UTF8 = "UTF-8"; 

// Registration is currently hardcoded 
private final static String YOUR_REGISTRATION_STRING = "put registration key"; 

private SharedPreferences prefs; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    prefManager = PreferenceManager.getDefaultSharedPreferences(this); 
} 




public void getAuthentification(View view) { 
    SharedPreferences prefs = PreferenceManager 
      .getDefaultSharedPreferences(this); 

    HttpClient client = new DefaultHttpClient(); 
    HttpPost post = new HttpPost(
      "https://www.google.com/accounts/ClientLogin"); 

    try { 

     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); 
     nameValuePairs.add(new BasicNameValuePair("Email", "[email protected]")); 
     nameValuePairs.add(new BasicNameValuePair("Passwd",".....")); 
     nameValuePairs.add(new BasicNameValuePair("accountType", "GOOGLE")); 
     nameValuePairs.add(new BasicNameValuePair("source", 
       "Google-cURL-Example")); 
     nameValuePairs.add(new BasicNameValuePair("service", "ac2dm")); 

     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); 
      if (line.startsWith("Auth=")) { 
       Editor edit = prefManager.edit(); 
       edit.putString(AUTH, line.substring(5)); 
       edit.commit(); 
       String s = prefManager.getString(AUTH, "n/a"); 
       Toast.makeText(this, s, Toast.LENGTH_LONG).show(); 
      } 

     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

public void showAuthentification(View view) { 
    String s = prefManager.getString(AUTH, "n/a"); 
    Toast.makeText(this, s, Toast.LENGTH_LONG).show(); 
} 

public void sendMessage(View view) { 
    try { 
     Log.e("Tag", "Started"); 
     String auth_key = prefManager.getString(AUTH, "n/a"); 
     // Send a sync message to this Android device. 
     StringBuilder postDataBuilder = new StringBuilder(); 
     postDataBuilder.append(PARAM_REGISTRATION_ID).append("=") 
       .append(YOUR_REGISTRATION_STRING); 

     // if (delayWhileIdle) { 
     // postDataBuilder.append("&").append(PARAM_DELAY_WHILE_IDLE) 
     // .append("=1"); 
     // } 
     postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=") 
       .append("0"); 

     postDataBuilder.append("&").append("data.payload").append("=") 
       .append(URLEncoder.encode("Fax Sent ... Test Push Notification ....", UTF8)); 

     Log.e("postDataBuilder ","postDataBuilder :" + postDataBuilder.toString()); 

     byte[] postData = postDataBuilder.toString().getBytes(UTF8); 

     // Hit the dm URL. 

     URL url = new URL("https://android.clients.google.com/c2dm/send"); 

     HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
     conn.setDoOutput(true); 
     conn.setUseCaches(false); 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty("Content-Type", 
       "application/x-www-form-urlencoded;charset=UTF-8"); 
     conn.setRequestProperty("Content-Length", 
       Integer.toString(postData.length)); 
     conn.setRequestProperty("Authorization", "GoogleLogin auth=" 
       + auth_key); 

     OutputStream out = conn.getOutputStream(); 
     out.write(postData); 
     out.close(); 

     int responseCode = conn.getResponseCode(); 

     Log.e("Tag", String.valueOf(responseCode)); 
     // Validate the response code 

     if (responseCode == 401 || responseCode == 403) { 
      // The token is too old - return false to retry later, will 
      // fetch the token 
      // from DB. This happens if the password is changed or token 
      // expires. Either admin 
      // is updating the token, or Update-Client-Auth was received by 
      // another server, 
      // and next retry will get the good one from database. 
      Log.e("C2DM", "Unauthorized - need token"); 
     } 

     // Check for updated token header 
     String updatedAuthToken = conn.getHeaderField(UPDATE_CLIENT_AUTH); 
     if (updatedAuthToken != null && !auth_key.equals(updatedAuthToken)) { 
      Log.i("C2DM", 
        "Got updated auth token from datamessaging servers: " 
          + updatedAuthToken); 
      Editor edit = prefManager.edit(); 
      edit.putString(AUTH, updatedAuthToken); 
     } 

     String responseLine = new BufferedReader(new InputStreamReader(
       conn.getInputStream())).readLine(); 

     // NOTE: You *MUST* use exponential backoff if you receive a 503 
     // response code. 
     // Since App Engine's task queue mechanism automatically does this 
     // for tasks that 
     // return non-success error codes, this is not explicitly 
     // implemented here. 
     // If we weren't using App Engine, we'd need to manually implement 
     // this. 
     if (responseLine == null || responseLine.equals("")) { 
      Log.i("C2DM", "Got " + responseCode 
        + " response from Google AC2DM endpoint."); 
      throw new IOException(
        "Got empty response from Google AC2DM endpoint."); 
     } 

     String[] responseParts = responseLine.split("=", 2); 
     if (responseParts.length != 2) { 
      Log.e("C2DM", "Invalid message from google: " + responseCode 
        + " " + responseLine); 
      throw new IOException("Invalid response from Google " 
        + responseCode + " " + responseLine); 
     } 

     if (responseParts[0].equals("id")) { 
      Log.i("Tag", "Successfully sent data message to device: " 
        + responseLine); 
     } 

     if (responseParts[0].equals("Error")) { 
      String err = responseParts[1]; 
      Log.w("C2DM", 
        "Got error response from Google datamessaging endpoint: " 
          + err); 
      // No retry. 
      throw new IOException(err); 
     } 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 
+0

嘿samit謝謝你的幫助。但我沒有得到NotificationAlert類。在廣播接收器中,我收到了NotificationAlert calss錯誤。 – 2011-06-08 09:36:14

+0

嗨通知類你自己的自定義代碼。您需要的手段自定義警報或通知.... – SBJ 2011-06-08 09:38:25

+0

嗨samit我得到了以下錯誤。 org.pushnotification.com是我的軟件包名稱。 – 2011-06-08 10:20:48

11

C2DM已過時,由Google Cloud Messaging for Android (GCM)已被替換。 谷歌的聲明:

重要:C2DM已正式棄用2012年6月26日, 。這意味着C2DM已停止接受新用戶和配額 請求。沒有新的功能將被添加到C2DM。但是,使用 C2DM的應用程序將繼續工作。鼓勵現有的C2DM開發者 遷移到新版本的C2DM,稱爲Google Cloud Messaging for Android(GCM)。有關更多 信息,請參閱C2DM-to-GCM遷移文檔。開發人員必須使用GCM進行新的開發。

有一個demo app tutorial for GCM和也來自C2DM的migration