2014-04-17 79 views
3

首先請不要將此問題設置爲重複或其他任何內容,因爲所有其他問題都不會覆蓋我的問題。我的問題是push notification。我已在我的應用中使用gcm實施了push notification並製作了jar及其源代碼。現在我已將其與我的res文件夾一起分發以進行集成。它的工作正常,如果主機應用程序不執行它自己的push notification。如果主機應用程序自己實現push notification,那麼我的集成應用程序不會收到推送。 Register GCM from a library project使用jar推送通知不起作用

我用下面除了在應用程序中,我已經將我的罐子:

我通過這篇文章去

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.READ_CALENDAR" /> 
<uses-permission android:name="android.permission.WRITE_CALENDAR" />   
<!-- GCM requires a Google account. --> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<!-- Keeps the processor from sleeping when a message is received. --> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<!-- Creates a custom permission so only this app can receive its messages. --> 
<permission 
    android:name="HOST_APP_PACKAGE.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 
<uses-permission android:name="HOST_APP_PACKAGE.permission.C2D_MESSAGE" /> 
<!-- This app has permission to register and receive data message. --> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
<!-- Network State Permissions to detect Internet status --> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<!-- Permission to vibrate --> 
<uses-permission android:name="android.permission.VIBRATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

而下面是我的接收器:

<receiver 
     android:name="MY_JAR_APP_PACKAGE.PushLibraryBroadcastReceiver" 
     android:permission="com.google.android.c2dm.permission.SEND" > 
     <intent-filter> 
      <!-- Receives the actual messages. --> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <!-- Receives the registration id. --> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
      <category android:name="HOST_APP_PACKAGE" /> 
     </intent-filter> 
    </receiver> 

PushLibraryBroadcastReceiver類代碼jar:基於上述的澄清

public class PushLibraryBroadcastReceiver extends GCMBroadcastReceiver 
{ 
    /** 
    * Gets the class name of the intent service that will handle GCM messages. 
    */ 
    @Override 
    protected String getGCMIntentServiceClassName(Context context) { 
     return "MY_JAR_APP_PACKAGE.GCMIntentService"; 
    } 
} 
+0

當你說主機應用程序實現'push notificatin'屬於它自己的時候,你的意思是什麼? –

+0

意味着集成我的應用程序的應用程序 –

+0

它給出了任何錯誤? –

回答

2

,你需要每個廣播接收機(即你的庫和主機應用程序),以照顧其自己的消息並忽略用於其他廣播接收機的消息。

由於您使用不同的發件人ID在您的圖書館和主機應用程序中註冊GCM,因此您可以使用它來確定哪個廣播接收方應該處理哪個消息。

首先,我建議你停止擴展已棄用的GCMBroadcastReceiver類。我的解決方案依賴於不使用它(儘管您可以通過更改其代碼使其與舊接收器一起工作)。

然後下面的接收器是基於官方GCM Demo App的新版本。

public class PushLibraryBroadcastReceiver extends WakefulBroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getExtras().get("from").equals (SENDER_ID_OF_LIBRARY) { 
      // Explicitly specify that GcmIntentService will handle the intent. 
      ComponentName comp = new ComponentName(
      GcmIntentService.class.getPackage().getName(), 
      GcmIntentService.class.getName()); 
      // Start the service, keeping the device awake while it is launching. 
      startWakefulService(context, (intent.setComponent(comp))); 
      setResultCode(Activity.RESULT_CANCEL); 
     } else 
      setResultCode(Activity.RESULT_OK); 
     } 
    } 
} 

我從演示的實現兩個轉變:

  1. 獲得意圖服務的包名明確(因爲使用context.getPackageName()將返回主機應用程序的主包,這是不是你需要)。
  2. 將消息的「from」字段與庫的發件人ID進行比較,並僅在來自該發件人時處理該消息。處理完消息後,結果將設置爲Activity.RESULT_CANCEL,以防止廣播被主機應用程序的廣播接收器處理。

如果停止使用舊GCMBroadcastReceiver,你應該改變你的意圖的服務,這樣的事情(再次,這是從demo拍攝):

protected void onHandleIntent(Intent intent) { 
    Bundle extras = intent.getExtras(); 
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); 
    // The getMessageType() intent parameter must be the intent you received 
    // in your BroadcastReceiver. 
    String messageType = gcm.getMessageType(intent); 

    if (!extras.isEmpty()) { // has effect of unparcelling Bundle 
     /* 
     * Filter messages based on message type. Since it is likely that GCM will be 
     * extended in the future with new message types, just ignore any message types you're 
     * not interested in, or that you don't recognize. 
     */ 
     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()); 
     // If it's a regular GCM message, do some work. 
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { 
      // This loop represents the service doing some work. 
      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()); 
     } 
    } 
    // Release the wake lock provided by the WakefulBroadcastReceiver. 
    GcmBroadcastReceiver.completeWakefulIntent(intent); 
} 

我假設你GCMIntentService類擴展已棄用GCMBaseIntentService。您應該改爲IntentService,並將邏輯從onMessage移至onHandleIntent

您還應該切換到使用GoogleCloudMessaging.register註冊GCM的新方法,該方法不需要在意圖服務類中進行任何處理。所有處理都將在執行註冊的活動中完成,如演示here所示。最後,如果主機應用程序的廣播接收器的行爲與您的媒體庫的廣播接收器的行爲不相同(即僅處理它應該處理的消息),那麼如果主機應用程序的廣播接收器是在圖書館的廣播接收器之前觸發。您可以通過將android:priority屬性添加到兩個接收器的意圖過濾器來避免這種情況,併爲庫的接收器賦予更高的優先級。這將確保圖書館的廣播接收機始終首先被觸發。

我必須說,我從來沒有測試的應用程序有兩個廣播接收機,所以我不能保證使用優先級屬性的工作原理,但它應該工作基於我閱讀文檔上:

有序廣播(用Context.sendOrderedBroadcast發送)是一次傳送給一個接收器的 。由於每個接收器在 轉中執行,它可以將結果傳播到下一個接收器,或者它可以完全中止廣播,使其不會傳遞到其他接收器。接受訂單的接收者可以通過匹配意圖過濾器的android:priority屬性來控制;具有相同優先級的接收器 將以任意順序運行。

+0

如果我們在Play商店上傳我們的應用程序(我們已經集成了庫項目),那麼應該爲GCM關聯哪個app_id? –

+0

@Harish我從來沒有嘗試過,但我會說使用應用程序的包(不是圖書館項目)。 – Eran

+0

我的場景是我製作了一個庫項目並實現了有關GCM的所有內容,然後將這個庫集成到我的應用程序中,並在開發過程中通過lib獲取了通知到我的應用程序,但是當我將它上載到Play商店時,加工。我該怎麼做,我需要你的幫助,你是唯一能拯救我的人。 –