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