Last active
December 25, 2015 13:59
-
-
Save cmelchior/6988275 to your computer and use it in GitHub Desktop.
Adding support for ".res-auto" in ContentProvider authorities in AndroidManifest.xml. This replaces ".res-auto" with the current package name, making it possible to install multiple build variants on the same devices without getting [INSTALL_FAILED_CONFLICTING_PROVIDER]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.trifork.example" | |
android:installLocation="auto" | |
android:versionName="@string/client_info" > | |
<!-- ... --> | |
<application | |
android:hardwareAccelerated="true" | |
android:icon="@drawable/icon" | |
android:label="@string/app_name" | |
android:theme="@style/Theme.Standard" > | |
<!-- ... --> | |
<provider | |
android:name="path.to.provider.ProviderImpl" | |
android:authorities=".res-auto.path.to.provider.ProviderImpl" | |
android:exported="false" > | |
</provider> | |
<provider | |
android:name="path.to.provider.ProviderImpl" | |
android:authorities="@string/provider_auth" | |
android:exported="false" > | |
</provider> | |
</application> | |
</manifest> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
buildscript { | |
repositories { | |
mavenCentral() | |
} | |
dependencies { | |
classpath 'com.android.tools.build:gradle:0.6.+' | |
} | |
} | |
apply plugin: 'android' | |
apply from: './build_extras.gradle' | |
repositories { | |
mavenCentral() | |
} | |
android { | |
compileSdkVersion 18 | |
buildToolsVersion "18.0.1" | |
defaultConfig { | |
minSdkVersion 10 | |
targetSdkVersion 18 | |
} | |
} | |
dependencies { | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Version 1.1. | |
* | |
* Add support for installing multiple variants of the same app which have a | |
* content provider. Do this by overriding occurrences of ".res-auto" in | |
* android:authorities with the current package name (which should be unique) | |
* | |
* V1.0 : Initial version | |
* V1.1 : Support for ".res-auto" in strings added, | |
* eg. use "<string name="auth">.res-auto.path.to.provider</string>" | |
* | |
*/ | |
def overrideProviderAuthority(buildVariant) { | |
def flavor = buildVariant.productFlavors.get(0).name | |
def buildType = buildVariant.buildType.name | |
def pathToManifest = "${buildDir}/manifests/${flavor}/${buildType}/AndroidManifest.xml" | |
def ns = new groovy.xml.Namespace("http://schemas.android.com/apk/res/android", "android") | |
def xml = new XmlParser().parse(pathToManifest) | |
def variantPackageName = xml.@package | |
// Update all content providers | |
xml.application.provider.each { provider -> | |
def newAuthorities = provider.attribute(ns.authorities).replaceAll('.res-auto', variantPackageName) | |
provider.attributes().put(ns.authorities, newAuthorities) | |
} | |
// Save modified AndroidManifest back into build dir | |
saveXML(pathToManifest, xml) | |
// Also make sure that all strings with ".res-auto" are expanded automagically | |
def pathToValues = "${buildDir}/res/all/${flavor}/${buildType}/values/values.xml" | |
xml = new XmlParser().parse(pathToValues) | |
xml.findAll{it.name() == 'string'}.each{item -> | |
if (!item.value().isEmpty() && item.value()[0].startsWith(".res-auto")) { | |
item.value()[0] = item.value()[0].replace(".res-auto", variantPackageName) | |
} | |
} | |
saveXML(pathToValues, xml) | |
} | |
def saveXML(pathToFile, xml) { | |
def writer = new FileWriter(pathToFile) | |
def printer = new XmlNodePrinter(new PrintWriter(writer)) | |
printer.preserveWhitespace = true | |
printer.print(xml) | |
} | |
// Post processing of AndroidManifest.xml for supporting provider authorities | |
// across build variants. | |
android.applicationVariants.all { variant -> | |
variant.processManifest.doLast { | |
overrideProviderAuthority(variant) | |
} | |
} |
@influenced, in searchable.xml
you can use something like
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:searchSuggestAuthority="@string/search_provider"
android:searchSuggestSelection=" ?"
>
</searchable>
and add to your strings.xml
<string name="search_provider">.res-auto.util.LocationSuggestionProvider</string>
But I do have the same issue with the values being overwritten when I use IntelliJ.
That's what I'd like to do - and what I originally did - but by the time it gets onto the device, it'll have been reset to .res-auto again, so the OS won't be able to find that provider.
I spent way too much time on this, but I finally have a version that works. Please check out https://gist.github.com/paour/9189462
@influenced: do you manage to get .res-auto replaced when you hit run/debug?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK, I still haven't got the modified value.xml to make it into a deployed build with the latest Android Studio plugin/Gradle, but I have got the process working other than that.
The alternative I'm using is simply to define something like:
in my provider class, and using the direct form of .res-auto in the manifest:
which works fine. Since the provider I'm specifically using is a SearchSuggestionProvider, I also tried adding a new section to overrideProviderAuthority that processes searchable configuration xml files, but this suffers from the same issue as values.xml - the modified version is getting replaced with the original prior to deployment.
I do not, as yet, have a workaround for that...