2

我一直在嘗試推出推送通知的擴展,其中我沒有應用程序的包名稱(因爲擴展將用於任何數量的應用程序而無需修改) 。清單中包含以下信息 -使用清單註冊廣播接收器

<receiver 
      android:name=".GcmBroadcastReceiver" 
      android:permission="com.google.android.c2dm.permission.SEND" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <category android:name="App.package" /> 
      </intent-filter> 
      <!-- Receive the registration id --> 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
       <category android:name="App.package" /> 
      </intent-filter> 
     </receiver> 
     <service android:name=".GcmIntentService" /> 

清單可以用於每個應用程序,不需要包含在擴展中。這裏的IntentService和廣播接收器的代碼 -

public class GcmIntentService extends IntentService { 

    public static final int NOTIFICATION_ID = 1; 
    private NotificationManager mNotificationManager; 
    NotificationCompat.Builder builder; 
    private static final String TAG = "INTENT_TAG"; 

    public GcmIntentService() { 
     super("GcmIntentService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     Bundle extras = intent.getExtras(); 
     GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); 
     String messageType = gcm.getMessageType(intent); 

     if (!extras.isEmpty()) { 
      if (GoogleCloudMessaging. 
        MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { 
       sendNotification("Send error: " + extras.toString()); 
      } else if (GoogleCloudMessaging. 
        MESSAGE_TYPE_DELETED.equals(messageType)) { 
       sendNotification("Deleted messages on server: " + 
         extras.toString()); 
      } else if (GoogleCloudMessaging. 
        MESSAGE_TYPE_MESSAGE.equals(messageType)) { 

       for (int i=0; i<5; i++) { 
        Log.i(TAG, "Working... " + (i+1) 
          + "/5 @ " + SystemClock.elapsedRealtime()); 
        try { 
         Thread.sleep(5000); 
        } catch (InterruptedException e) { 
        } 
       } 
       Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime()); 
       // Post notification of received message. 
       sendNotification("Received: " + extras.toString()); 
       Log.i(TAG, "Received: " + extras.toString()); 
      } 
     } 
     GcmBroadcastReceiver.completeWakefulIntent(intent); 
    } 
    private void sendNotification(String msg) { 
     mNotificationManager = (NotificationManager) 
       this.getSystemService(Context.NOTIFICATION_SERVICE); 

     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, LoaderActivity.class), 0); 

     NotificationCompat.Builder mBuilder = 
       new NotificationCompat.Builder(this) 
     //.setSmallIcon(R.drawable.ic_launcher) 
     .setContentTitle("GCM Notification") 
     .setStyle(new NotificationCompat.BigTextStyle() 
     .bigText(msg)) 
     .setContentText(msg); 

     mBuilder.setContentIntent(contentIntent); 
     mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); 
    } 
} 

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     // Explicitly specify that GcmIntentService will handle the intent. 
     ComponentName comp = new ComponentName(context.getPackageName(), 
       GcmIntentService.class.getName()); 
     // Start the service, keeping the device awake while it is launching. 
     startWakefulService(context, (intent.setComponent(comp))); 
     setResultCode(Activity.RESULT_OK); 
    } 
} 

當我嘗試從服務器發送郵件,通知不會被調用,就好像接收從來沒有得到實例化或註冊。是否因爲我的IntentService和BroacastReceiver都是默認包?

+0

我已經創建了另一個問題,因爲問題不是我最初的想法 - http://stackoverflow.com/q/19350641/1079901 – noob

回答

5

GCMBroadcastReceiver會在應用程序的主包GcmIntentService,所以如果它在另一個包就不會被發現。

您可以使用此代碼啓動意圖服務:

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Intent gcmIntent = new Intent (context, GcmIntentService.class); 
     gcmIntent.putExtras (intent.getExtras()); 
     startWakefulService(context, gcmIntent); 
     setResultCode(Activity.RESULT_OK); 
    } 
} 

此外,使用你的代碼的每個應用(我不知道你的代碼是否應該被用作庫項目或一些其他方式)必須在其清單中聲明廣播接收機,並在意圖過濾器的類別中使用正確的包名稱。而且您必須爲GCM定義一個包含該軟件包名稱的權限。

+0

所以類別名稱應該是我在GCMIntentService/GCMBroadcastReceiver?這可能與應用程序的實際包名稱不同,以便我可以爲擴展名定義通用包名稱?在權限中,需要哪個軟件包名稱,擴展名或應用程序(允許其中兩個不同的是允許的)? 這就像一個庫項目,稱它爲插件將是一個更好的術語,但:-) – noob

+0

不,類別名稱必須是使用您的GCM代碼的特定應用程序的包(並且必須在權限中使用相同的包)。每個使用您的代碼的應用程序將具有不同的包名稱,因此具有不同的類別名稱和GCM權限。服務類的包名稱是一個不同的問題。您應該更改您的廣播接收器代碼以停止在應用程序的主包中查找服務類,而是在擴展的包中查找它。 – Eran

+0

感謝您的幫助。我希望這應該很容易解決。 – noob

相關問題