2012-04-25 23 views
5

我可以在我的清單中使用<receiver>成功地在C2DM上註冊我的android應用程序。但是,如果我從清單中刪除<receiver>並使用上下文的registerReceiver方法註冊接收方,則會收到SERVICE_NOT_AVAILABLE錯誤響應。我在仿真器和實際設備中複製了這種行爲。使用registerReceiver的C2DM接收器的動態寄存器

是否正在動態註冊C2DM接收器?

這是我刪除了清單的片段:

<receiver android:name=".service.C2DM.C2DMReceiver" android:permission="com.google.android.c2dm.permission.SEND"> 
    <intent-filter> 
     <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
     <category android:name="mytestapp" /> 
    </intent-filter> 
    <intent-filter> 
     <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
     <category android:name="mytestapp" /> 
    </intent-filter> 
</receiver> 

這裏是代碼:

public class C2DMReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     String registration = intent.getStringExtra("registration_id"); 
     if (intent.getStringExtra("error") != null) { 
      //TODO: Registration failed, should try again later. 
      Log.e("MyTestAppC2DM", "C2DM Error = " + intent.getStringExtra("error")); 
     } else if (intent.getStringExtra("unregistered") != null) { 
      Log.d("MyTestAppC2DM", "C2DM Unregistered"); 
     } else if (registration != null) { 
      Log.d("MyTestAppC2DM","C2DM registration_id = " + registration); 
     } else { 
      Log.w("MyTestAppC2DM", "C2DM No registration_id"); 
     } 
    } 

    public static void register(Context context){ 
     /* BEGIN OF DYNAMIC REGISTER */ 
     C2DMReceiver c2dmReceiver = new C2DMReceiver(); 

     IntentFilter receiveIntentFilter = new IntentFilter(); 
     receiveIntentFilter.addAction("com.google.android.c2dm.intent.RECEIVE"); 
     receiveIntentFilter.addCategory("mytestapp"); 
     context.registerReceiver(c2dmReceiver, receiveIntentFilter, "com.google.android.c2dm.permission.SEND", null); 

     IntentFilter registrationIntentFilter = new IntentFilter(); 
     registrationIntentFilter.addAction("com.google.android.c2dm.intent.REGISTRATION"); 
     registrationIntentFilter.addCategory("mytestapp"); 
     context.registerReceiver(c2dmReceiver, registrationIntentFilter, "com.google.android.c2dm.permission.SEND", null); 

     /*END OF DYNAMIC REGISTER*/ 

     Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER"); 
     registrationIntent.putExtra("app", PendingIntent.getBroadcast(context, 0, new Intent(), 0)); 
     registrationIntent.putExtra("sender", "[email protected]"); 
     ComponentName service = context.startService(registrationIntent); 
     if(service!=null){ 
      Log.d("MyTestAppC2DM","C2DM Registration sent"); 
     }else{ 
      Log.d("MyTestAppC2DM","C2DM Service not found"); 
     } 
    } 
} 

回答

2

當系統發送廣播時,如果在清單中聲明瞭匹配的意圖過濾器,它將啓動應用程序來處理意圖。由於C2DM的性質,動態安裝廣播接收器是沒有用的,因爲當收到C2DM消息時,您的應用程序可能沒有運行。如果它沒有運行,它將不會爲動態安裝的接收器啓動。

3

可以在清單文件中的接收器C2DMReceiver註冊,並調度意圖真實BroadcastReceiver來處理它。

+0

謝謝。這就是我所做的,但我接受了另一個答案,因爲我問的是更多的推理而不是解決方法。 – hectorct 2012-06-23 12:33:20

+0

@hectorct我有一個真正simmilar [問題](http://stackoverflow.com/questions/25233039/google-gcm-client-not-sending-messages-after-unregistering-registering-the-broad)。如果我註冊廣播接收器,我的應用程序不再發送消息。當我切換回specterst模式時,它正在工作。也許你已經及時發現了。 – 2014-08-11 05:54:36

0

在一個Activity的動態註冊的BroadcastReceiver中收到一個意圖,但是像原始作者一樣,我發現這是行不通的(除了JB上的GCM)。是否有一個原因 ?我無法在任何地方的文檔中找到此限制。