问题
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
compileSdkVersion
value ofandroid-MNC
causes the build process to put MNC in as theminSdkVersion
andtargetSdkVersion
in 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
MNC
with15
, and writing the adjusted manifest back out. This will fail on projects that haveMNC
somewhere else, like an activity’s class name. It also sets bothminSdkVersion
andtargetSdkVersion
to 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 ofdefaultConfig
and 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