2

buildTypes デバッグ/リリースと 2 つの productFlavor のパッケージ名が異なるアプリがあります。

私の build.gradle の興味深い部分は次のようになります。

android {
    buildTypes {
        debug {
            packageNameSuffix ".debug"
        }

        release {
            signingConfig signingConfigs.release
        }
    }

    productFlavors {
        flavor1 {
            packageName "com.example.app.flavor1"
        }

        flavor2 {
            packageName "com.example.app.flavor2"
        }
}

したがって、パッケージ名には次のものがあります。

com.example.app.flavor1 com.example.app.flavor1.debug com.example.app.flavor2 com.example.app.flavor2.debug

コードはすべて問題ありません。しかし、マニフェストのマージ中に変更されたパッケージ名が台無しになるため、有効なパッケージごとに GCM パーミッションやコンテンツ プロバイダーの権限などを手動で設定する必要があります。

しかし、それはどのように行うのですか?AndroidManifest.xmlを に入れても に入れてsrc/falvor{1,2}src/{debug,release}、最終的には 2 つの構成しかありません。flavor1Debug運が悪いなどのことを試しました。

4

1 に答える 1

5

「flavorBuildType」(flavor1Debug など) の組み合わせのリソース ファイルを設定する公式の方法はないため、ここで少しハックする必要があります。

まず、AndroidManifest.xml の新しいパスを定義します。

project.ext.flavor1 = [
    debugManifest: 'src/flavor1Debug/AndroidManifest.xml',
    releaseManifest: 'src/flavor1Release/AndroidManifest.xml'
]

project.ext.flavor2 = [
    debugManifest: 'src/flavor2Debug/AndroidManifest.xml',
    releaseManifest: 'src/flavor2Release/AndroidManifest.xml'
]

次に、processManifest タスクで新しい AndroidManifest.xml を使用するように gradle に指示します。問題は、sourceSet.manifest.srcFile が読み取り専用であり、その場で置き換えることができないことです。フレーバーごとに個別のリソース (デバッグとリリース) を使用しているため、新しい AndroidManifest.xml を元のフレーバー フォルダーにコピーでき、gradle は適切な設定で APK ファイルをビルドします。

android.applicationVariants.all { variant ->
    variant.processManifest.doFirst {
        if (project.ext.has(variant.productFlavors.name)) {
            if (project.ext[variant.productFlavors.name].debugManifest != null &&
                project.ext[variant.productFlavors.name].releaseManifest != null) {
                def manifestDirectory = android.sourceSets[variant.productFlavors.name].manifest.srcFile.parentFile
                if (variant.buildType.name.equals("debug")) {
                    copy {
                        from project.ext[variant.productFlavors.name].debugManifest
                        into manifestDirectory
                    }
                } else if (variant.buildType.name.equals("release")) {
                    copy {
                        from project.ext[variant.productFlavors.name].releaseManifest
                        into manifestDirectory
                    }
                }
            }
        }
    }

    variant.processManifest.doLast {
        if (project.ext.has(variant.productFlavors.name)) {
            project.delete android.sourceSets[variant.productFlavors.name].manifest.srcFile
        }
    }
}

AndroidManifest.xml については、GCM 関連の設定をそのままにしておきます。

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

    <permission
        android:name="com.android.example.free.debug.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.android.example.free.debug.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

</manifest>

ここでサンプル コードを取得できます: https://github.com/shakalaca/learning_gradle_android/tree/master/07_tricks

Google Maps API v2 と GCM の両方のケースに対応していますが、マイナー コード変更後はコンテンツ プロバイダーにも対応しやすいと思います。

于 2013-09-04T17:24:34.360 に答える