Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android N - Cannot run on lower API though minSDK set to 14

I am trying to run the APK on API 22 device after updating compileSdkVersion to N but unable to do so.

compileSdkVersion 'android-N'
buildToolsVersion "24.0.0 rc1"

defaultConfig {
       minSdkVersion 14
       targetSdkVersion 'N'
}

enter image description here

like image 673
mihirjoshi Avatar asked Mar 10 '16 23:03

mihirjoshi


People also ask

How do I change the minimum sdk version?

check it: Android Studio->file->project structure->app->flavors->min sdk version and if you want to run your application on your mobile you have to set min sdk version less than your device sdk(API) you can install any API levels. Show activity on this post. Set the min SDK version in your project's AndroidManifest.

What is minimum sdk version Android?

minSdkVersion is the minimum version of the Android operating system required to run your application. The Android app must have a minimum SDK version 19 or higher. If you want to support devices below API level 19, you must override minSDK version.

What is the difference between compileSdkVersion and targetSdkVersion?

Conclusion. With the above discussion, we have noted that compileSdkVersion tells the Gradle which version it should build the application on while targetSdkVersion defines the specific device which the application is built for while minSdkVersion defines the least version of API level that your application supports.


2 Answers

I found a solution that work but before that a little bit of history. What I did was trying to have different variants of my app and each variant would have its own compileSdkVersion

Those are snippets from my build.gradle

First attempt (compileSdkVersion is variant specific): Let you install the app on API level >= ANDROID-N only

    //compileSdkVersion 'android-N'
    buildToolsVersion '24.0.0 rc1'

    productFlavors {
        dev {
            compileSdkVersion 23
            targetSdkVersion 23
        }
        experimental {
            compileSdkVersion 'android-N'
            minSdkVersion 'N'
            targetSdkVersion 'N'
        }
    }

Second attempt (compileSdkVersion still variant specific but I removed experimental variant): Let you install the app on API Level < ANDROID-N only

    //compileSdkVersion 'android-N'
    buildToolsVersion '24.0.0 rc1'

    productFlavors {
        dev {
            compileSdkVersion 23
            targetSdkVersion 23
        }
        /*
        experimental {
            compileSdkVersion 'android-N'
            minSdkVersion 'N'
            targetSdkVersion 'N'
        }
        */
    }

Third attempt (compileSdkVersion still variant specific but experimental is defined before dev)

//compileSdkVersion 'android-N'
buildToolsVersion '24.0.0 rc1'

productFlavors {
    experimental {
        compileSdkVersion 'android-N'
        minSdkVersion 'N'
        targetSdkVersion 'N'
    }
    dev {
        compileSdkVersion 23
        targetSdkVersion 23
    }
}

At my big surprise this one worked ! I don't know why but it does. All you have to do is define your Android-N only variant before any other variant, click Build Variants in Android Studio and select the one you want to compile.

I am going to file an issue in the Android-N bug tracker and update this answer when I get more info.

like image 21
Charles-Eugene Loubao Avatar answered Oct 11 '22 17:10

Charles-Eugene Loubao


Out of the box, the build tools are set up to block you from running N Developer Preview apps on older devices. Presumably, this is a sloppy way for Google to try to prevent people from shipping stuff built off of the preview. This approach was also used in the past two developer previews. So, Google does not want you testing your N Developer Preview app on your Android 5.0 (API Level 22) device to see if you are handling backwards compatibility correctly.

¯\_(ツ)_/¯

Fortunately, you can hack in a solution:

android {
    compileSdkVersion 'android-N'
    buildToolsVersion "24.0.0 rc1"

    defaultConfig {
      minSdkVersion 15
      targetSdkVersion 'N'
    }

    // based on http://stackoverflow.com/a/27372806/115145

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.processManifest.doLast {
                def manifestOutFile = output.processManifest.manifestOutputFile
                def xml = new XmlParser().parse(manifestOutFile)
                def usesSdk = xml.'uses-sdk'

                usesSdk.replaceNode{
                    'uses-sdk'('android:minSdkVersion': '15',
                               'android:targetSdkVersion': '15')
                }

                def fw=new FileWriter(manifestOutFile.toString())

                new XmlNodePrinter(new PrintWriter(fw)).print(xml)
            }
        }
    }
}

What the tools demand is targetSdkVersion 'N', and that's what breaks your ability to run the app on older devices. So, this hunk of Groovy code allows the build tools to start with targetSdkVersion 'N', then swaps in another targetSdkVersion value into the generated manifest, before packaging. In this case, I am setting the minSdkVersion and targetSdkVersion to 15, but you can substitute in your own values. Also, you will need to rebuild or clean your project for the change to take effect.

On the plus side, the resulting app can be installed and run on an older Android device (though possibly only through a command-line build; I think Android Studio didn't like this technique).

On the minus side, your targetSdkVersion will not actually be N, which may impact some behaviors on N Developer Preview devices. You might want to set up a particular build type that you use for the backwards-compatibility testing and only do my hack-the-manifest trick on that build type. Then, you can test both using an official N Developer Preview setup and perform some measure of backwards compatibility testing in one build.

like image 170
CommonsWare Avatar answered Oct 11 '22 18:10

CommonsWare