Android Gradle 带有解析推送通知的产品风味

Android Gradle product Flavors with Parse Push Notifications

我正在尝试通过 Parse 发送推送通知并集成产品风格。当我实现产品风格时,我无法接收 Parse 推送通知。有没有人对纠正这个问题有任何建议

Gradle 应用程序文件:

apply plugin: 'com.android.application'

android {
compileSdkVersion 19
buildToolsVersion "21.1.2"

defaultConfig {
    applicationId "com.example.project"
        minSdkVersion 16
        targetSdkVersion 21

}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
    }
}
productFlavors{
    freeApp{
        applicationId "com.example.project.free"

    }
    premiumApp{
        applicationId "com.example.project.paid"
    }
}
}

dependencies {
compile files('libs/android-async-http-1.4.2-66-g4b6eb97.jar')
compile files('libs/android-support-v13.jar')
compile files('libs/bolts-android-1.2.0.jar')
compile files('libs/Parse-1.9.2.jar')
compile files('libs/ParseCrashReporting-1.9.2.jar')
}

Android 清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.project"
android:versionCode="1"
android:versionName="1.1" >

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

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

<application
    android:name="com.example.project.Application"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">



    <activity
        android:name="com.example.project.MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>



    <meta-data android:name="com.parse.push.notification_icon" android:resource="@drawable/ic_launcher"/>

    <service android:name="com.parse.PushService" />
    <receiver android:name="com.parse.ParseBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.USER_PRESENT" />
        </intent-filter>
    </receiver>
    <receiver android:name="com.parse.ParsePushBroadcastReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="com.parse.push.intent.RECEIVE" />
            <action android:name="com.parse.push.intent.DELETE" />
            <action android:name="com.parse.push.intent.OPEN" />
        </intent-filter>
    </receiver>
    <receiver android:name="com.parse.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" />

            <!--
              IMPORTANT: Change "com.parse.starter" to match your app's package name.
            -->
            <category android:name="com.example.project" />
        </intent-filter>
    </receiver>
</application>

注意: 正如观察到的那样,我的解决方案比下面 Morten Holmgaard 的解决方案要复杂一些。不用说,如果我知道我会提出那个更简单的解决方案。然而,我的回答确实包含了一些相关的解释,而且它也是唯一的 - 也是唯一 正确的 - 五周的回答,所以我将保留它。

============================================= ==============================

有什么问题吗?

我认为您没有收到任何推送的原因是您在 AndroidManifest.xml 中为 Parse 声明了以下内容:

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

<receiver android:name="com.parse.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" />

        <!--
          IMPORTANT: Change "com.parse.starter" to match your app's package name.
        -->
        <category android:name="com.example.project" />
    </intent-filter>
</receiver>

但是,包名称定义为

applicationId "com.example.project.free"

applicationId "com.example.project.paid"

因此包名称与您 AndroidManifest.xml 中的声明不匹配,因此 Parse 无法接收推送。实际上,如果您查看 logcat 输出,您应该会看到一条来自 Parse 的消息,它告诉您 AndroidManifest.xml.

中到底缺少什么

那么,如何解决呢?

这种情况有点棘手,但可以做到:

1.) 从您的 main 源集 (src/main/AndroidManifest.xml) 中的 AndroidManifest.xml 中删除我上面引用的两个部分 (src/main/AndroidManifest.xml)。

2a.) 在您的 free 源集 (src/free/AndroidManifest.xml) 中创建一个 AndroidManifest.xml 并输入以下内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <permission
        android:name="com.example.project.free.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.project.free.permission.C2D_MESSAGE" />

    <application>
        <receiver
            android:name="com.parse.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="com.example.project.free" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

2b.) 对 paid 源集执行相同的操作。请务必在 AndroidManifest.xml.

中正确替换包名

为什么这样做?

因为 gradle 不会用 src/free/AndroidManifest.xml 替换 src/main/AndroidManifest.xml 而是 将它们合并 为一个。因此,如果您只是将声明留在 main 源集中,并将它们放入 freepaid 中,您将为每种口味正确合并 AndroidManifest.xml。

我刚刚使用 Manifest Merger:

非常轻松地解决了完全相同的问题
 ${applicationId}

示例:

    <permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />

    <application>
        <receiver
            android:name="com.parse.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="${applicationId}" />
            </intent-filter>
        </receiver>
    </application>