1

在我的常規版本中,gcm可以正常工作,但是當我使用flavor來更改com名稱時,就會停止工作。我的IntentService永遠不會被初始化。我應該如何設置我的清單文件以便發生這種情況?使用Gradle更改軟件包名稱時,未註冊GCM

  • 我已將它們添加到開發者控制檯。
  • 我使用gradle這個com.android.tools.build:gradle:0.11.+」

我得到的日誌

V/GCMBroadcastReceiver﹕ onReceive: com.google.android.c2dm.intent.REGISTRATION 
V/GCMBroadcastReceiver﹕ GCM IntentService class: com.sample.app.dev.GCMIntentService 
V/GCMBaseIntentService﹕ Acquiring wakelock 

,然後什麼都沒有。我的自定義IntentService類永遠不會被初始化,並且我的registrationId保持空白。我目前的實現類似於這裏的:https://stackoverflow.com/a/20334397/198034

我應該如何設置我的清單以獲得gradle 0.11。+ flavor以使用gcm?

下面是我的一個風格的清單,我在主清單中有更多的代碼(所有需要的權限等),但沒有其他處理gcm的代碼。

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.sample.app" 
    android:versionCode="45" 
    android:versionName="0.6.5" > 

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 


    <permission android:name="com.sample.app.permission.C2D_MESSAGE" 
     android:protectionLevel="signature" /> 
    <uses-permission android:name="com.sample.app.permission.C2D_MESSAGE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/app_icon" 
     android:label="@string/app_name" > 


     <service android:name=".GCMIntentService" /> 
     <receiver 
      android:name="com.google.android.gcm.GCMBroadcastReceiver" 
      android:permission="com.google.android.c2dm.permission.SEND" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 

       <category android:name="${packageName}" /> 
      </intent-filter> 
     </receiver> 
    </application> 

</manifest> 
+0

請發表您的清單 – Eran

+0

我沒有發佈它,因爲使用我已經嘗試了各種不同的配置,我的清單非常大。但我會加上重要的一點。 – QuinnBaetz

回答

10

這是我的解決方案:

<permission android:name="com.sample.app.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 
<uses-permission android:name="com.sample.app.permission.C2D_MESSAGE" /> 

...

<service android:name=".GCMIntentService" /> 
    <receiver 
     android:name=".MyBroadcastReceiver" 
     android:permission="com.google.android.c2dm.permission.SEND" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 

      <category android:name="com.sample.app" /> 
     </intent-filter> 
    </receiver> 
在我的清單

和mybroadcastReceiver

...

public class MyBroadcastReceiver extends GCMBroadcastReceiver 
    { 
    @Override 
    protected String getGCMIntentServiceClassName(Context context) 
    { 
     return GCMIntentService.class.getName(); 
    } 
    } 
+0

我沒有看到您在解決方案中使用產品口味的地方......謹慎解釋它?而且,這種清單屬於哪種味道? – wsgeorge

+1

這解決了這個問題。 @wsgeorge,默認的Android庫GCMBroadcastReceiver將其廣播發送到GCMIntentService的一個包裝位置,每個包裝位置都會改變它,但不能到達。當您對廣播接收器進行子類化並指定自定義類名稱時,廣播每次都會重定向到正確的類。 – nobre

+0

爲我節省了很多時間,非常感謝! – Nickmccomb

0

從你的清單,它看起來像你的應用程序的軟件包名稱是com.sample.app,這與你的permission.C2D_MESSAGE定義一致。您的接收器的意圖過濾器的類別說${packageName}。希望這也可以翻譯成com.sample.app,因爲它應該。

除此之外,上面顯示的日誌顯示您的意向服務預計爲com.sample.app.dev.GCMIntentService。這是一個不同的包。

你似乎使用舊的過時的GCM客戶端庫,其中com.google.android.gcm.GCMBroadcastReceiver預期目的服務被稱爲GCMIntentService和位於應用程序的主包:

/** 
* Gets the default class name of the intent service that will handle GCM 
* messages. 
*/ 
static final String getDefaultIntentServiceClassName(Context context) { 
    String className = context.getPackageName() + 
      DEFAULT_INTENT_SERVICE_CLASS_NAME; 
    return className; 
} 

您的清單聲明的意圖服務類是在你的應用程序的主包:

<service android:name=".GCMIntentService" />

所有這些東西加起來不。您應用的軟件包名稱是com.sample.app.devcom.sample.app。如果是前者,則發佈的清單不正確。如果是後者,廣播接收機沒有理由期望意圖服務等級爲com.sample.app.dev.GCMIntentService

+0

Gradle處理清單中的包名稱更改,我不確定它是如何執行此操作的,我不知道如何查看生成的清單。它可能會將包名稱的所有實例與flavor包名稱關聯起來。 – QuinnBaetz