问题
Shortly after the Google I/O keynote and the consecutive talks about Android M features, I started playing around with the new SDK functions, e.g., runtime permissions. For that it is necessary to set the compileSdkVersion as well as the targetSdkVersion to android-mnc.
When running the project on a Nexus 5 with the Android M Developer Preview installed, Android Studio installs the application and it works fine on the device.
If I set the minSdkVersion to, e.g., 10 to test it on a 2.3.6 device or to 21 to test it on a 5.0 device, it still works on the M-Nexus5 but not on the aforementioned devices with lower-than-M API versions.
apply plugin: 'com.android.application'
android {
buildToolsVersion "22.0.1"
compileSdkVersion 'android-MNC'
defaultConfig {
applicationId "de.FOOBAR.permtestproject"
minSdkVersion 10
targetSdkVersion 21
versionCode 23
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
}
As you can see in the following screenshot, my level-21 device is shown as incompatible even though I set the minSdkVersion to 10 and not to the claimed level of 22.
Lowering the targetSdkVersion to 21 doesn’t make a difference. Changing the compileSdkVersion is not an option as the permission request calls have not been available in pre-M(NC) SDKs.
Trying to run the application on a pre-M device always fails with the error INSTALL_FAILED_OLDER_SDK.
回答1:
Quoting myself:
In the case of the M Developer Preview, the
compileSdkVersionvalue ofandroid-MNCcauses the build process to put MNC in as theminSdkVersionandtargetSdkVersionin the generated manifest.Fortunately, manifests are text files.
So, here is an android closure that can build an app module that compiles against MNC but will run on API Level 15+ devices:
android {
compileSdkVersion 'android-MNC'
buildToolsVersion "23.0.0 rc1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 15
}
// based on http://stackoverflow.com/a/27372806/115145
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.processManifest.doLast {
def manifestOutFile = output.processManifest.manifestOutputFile
def newFileContents = manifestOutFile.getText('UTF-8').replace("MNC", "15")
manifestOutFile.write(newFileContents, 'UTF-8')
}
}
}
}
This takes a very “caveman” approach to the problem, reading in the generated manifest, replacing all occurrences of
MNCwith15, and writing the adjusted manifest back out. This will fail on projects that haveMNCsomewhere else, like an activity’s class name. It also sets bothminSdkVersionandtargetSdkVersionto the same value. A more sophisticated script would replace those individual attributes — the proof of this is left as an exercise for the reader. Similarly, a more powerful script would read the desired values out ofdefaultConfigand apply them. And, a safety-conscious edition of this would only apply this for debuggable variants, thereby helping to reduce the impact of a drooling idiot trying to ship a release build that performs this override. This is merely a proof of concept, not implementing all possible bells and whistles.Again, doing this and releasing the results to the Play Store or elsewhere is monumentally idiotic. Use this for testing only.
来源:https://stackoverflow.com/questions/30734545/android-mnc-project-won-t-run-on-devices-prior-to-api-level-android-mnc