3

We have two different flavor dimensions like in this example and we want to dynamically generate applicationId like

com.company.apple

instead this script will generate an applicationId of

null.company.apple

I believe this is because the function at the bottom iterates over the full productFlavor list and not the combined list.

flavorDimensions "product", "license"

productFlavors.all {
    ext.scheme = null
    ext.scheme_tail = ""
    ext.kind = null
    ext.license = null
}

productFlavors {
    apple {
        dimension "product"
        kind = "apple"
        scheme = "companyapple"
    }

    orange {
        dimension "product"
        scheme = "companyorange"
        kind = "orange"
    }

    kiwi {
        dimension "product"
        scheme = "companykiwi"
        kind = "kiwi"
    }

    com {
        dimension "license"
        license = "com"
        scheme_tail = ''
    }

    eu {
        dimension "license"
        license = "eu"
        scheme_tail = "eu"
    }

    uk {
        dimension "license"
        license = "uk"
        scheme_tail = "uk"
    }

}

productFlavors.all {
    applicationId license + ".company." + kind
    ext.fileProvider = applicationId + ".fileprovider"
    manifestPlaceholders = [scheme: "$scheme$scheme_tail", fileProvider: "$fileProvider"]
    buildConfigField("String", "FILE_PROVIDER", "\"$fileProvider\"")
    buildConfigField("String", "SCHEME", "\"$scheme$scheme_tail\"")
    buildConfigField("String", "KIND", "\"$kind\"")
    buildConfigField("String", "LICENSE", "\"$license\"")
}

How can I iterate over the combined list to build my buildConfig fields and applicationIds?

The manifestPlaceholders are consumed like this:

    <activity android:name=".FruitViewerActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <data android:scheme="${scheme}" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
        </intent-filter>
    </activity>

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${fileProvider}"
        android:grantUriPermissions="true">

        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />

    </provider>

Thanks, Rory

Ankhwatcher
  • 420
  • 6
  • 19

2 Answers2

3

I found a solution that accomplishes my goals, and then improved upon it with information from this post by David Medenjak.

Firstly use applicationId and applicationIdSuffix to build the applicationId. Build the file provider separately for BuildConfig and for AndroidManifest. Publish the scheme_prefix and scheme_suffix separately for the AndroidManifest and concatenate them later. Build the scheme from it's components in the ApplicationVariant.

flavorDimensions "product", "license"

productFlavors.all {
    ext.scheme_prefix = null
    ext.scheme_suffix = ""
    ext.license = null
}

productFlavors {
    apple {
        applicationId = "apple.company"
        dimension "product"
        scheme_prefix = "companyapple"
        manifestPlaceholders = [scheme_prefix: "$scheme_prefix"]

        buildConfigField("String", "KIND", "\"apple\"")
    }

    orange {
        applicationId = 'orange.company'
        dimension "product"
        scheme_prefix = "companyorange"
        manifestPlaceholders = [scheme_prefix: "$scheme_prefix"]

        buildConfigField("String", "KIND", "\"orange\"")
    }

    kiwi {
        applicationId = "kiwi.company"
        dimension "product"
        scheme_prefix = "companykiwi"
        manifestPlaceholders = [scheme_prefix: "$scheme_prefix"]

        buildConfigField("String", "KIND", "\"kiwi\"")
    }

    com {
        dimension "license"
        license = "com"
        applicationIdSuffix = "$license"

        scheme_suffix = ''
        manifestPlaceholders = [scheme_suffix: "$scheme_suffix"]
    }

    eu {
        dimension "license"
        license = "eu"
        applicationIdSuffix = "$license"

        scheme_suffix = "eu"
        manifestPlaceholders = [scheme_suffix: "$scheme_suffix"]
    }

    uk {
        dimension "license"
        license = "uk"
        applicationIdSuffix = "$license"

        scheme_suffix = "uk"
        manifestPlaceholders = [scheme_suffix: "$scheme_suffix"]
    }

}

android.applicationVariants.all {
    variant ->
        ext.fileProvider = variant.applicationId + ".fileprovider"
        buildConfigField("String", "FILE_PROVIDER", "\"$fileProvider\"")

        def product = variant.productFlavors[0]
        def license = variant.productFlavors[1]
        variant.buildConfigField("String", "LICENSE", "\"${license.license}\"")
        variant.buildConfigField "String", "SCHEME", "\"${product.scheme_prefix}${license.scheme_suffix}\""
}

Here are the corresponding Manifest changes:

    <activity android:name=".FruitViewerActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <data android:scheme="${scheme_prefix}${scheme_suffix}" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
        </intent-filter>
    </activity>

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:grantUriPermissions="true">

        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />

    </provider>
Ankhwatcher
  • 420
  • 6
  • 19
0
apple {
    dimension "product"
    kind = "apple"
    licence = "apple"
    scheme = "companyapple"
}

Your missing licence in you flavour so it defaults to null

Emortal
  • 25
  • 5