Why are my supported android devices so low? I've tried to target the lowest possible apk (13), and yet only 12,000 devices can use my app.
Any help would be much appreciated!
Here is my build.gradle.
android {
signingConfigs {
}
compileSdkVersion 23
buildToolsVersion '25.0.0'
defaultConfig {
applicationId "thomas.surfaceviewtest"
minSdkVersion 13
targetSdkVersion 13
versionCode 5
versionName "1.0.5"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
}
}
dexOptions {
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.google.android.gms:play-services-ads:9.4.0'
compile 'com.google.firebase:firebase-ads:9.4.0'
}
apply plugin: 'com.google.gms.google-services'
That number is comparting your manifest configuration and a list of devices know by Google (see the list of devices).
It is not a number of real devices, but a number of model supported, so 12000 models on the market is a good number I believe.
Its because your target sdk level is low
targetSdkVersion 13
Update it to 25 so it will support more devices
targetSdkVersion 25
You can check for more android sdk version here
My app is compatible with 12611 devices. That is basically the same as you have. 12000 devices isn't little, especially given the fact that there are "only" 1465 unsupported devices as a result of my minSdk version being high.
Targeting 12k devices isn't little, it is a lot. If you were only targeting say 8k that would be something you should look into.
You should still change compile and minSdk versions to 25 or 26 (7.1 or 8.0) to make sure your app can run the newest API's.
I'd like to clarify the fact that targeting API 13 doesn't exclude API 14-26 from installing the app. It indicates what version it is designed for. You compile against 23 so you have the new API's included, but you only use API 13.
This should help:
android:targetSdkVersion
An integer designating the API Level that the application targets. If not set, the default value equals that given to minSdkVersion.
This attribute informs the system that you have tested against the target version and the system should not enable any compatibility behaviors to maintain your app's forward-compatibility with the target version. The application is still able to run on older versions (down to minSdkVersion).
As Android evolves with each new version, some behaviors and even appearances might change. However, if the API level of the platform is higher than the version declared by your app's targetSdkVersion, the system may enable compatibility behaviors to ensure that your app continues to work the way you expect. You can disable such compatibility behaviors by specifying targetSdkVersion to match the API level of the platform on which it's running. For example, setting this value to "11" or higher allows the system to apply a new default theme (Holo) to your app when running on Android 3.0 or higher and also disables screen compatibility mode when running on larger screens (because support for API level 11 implicitly supports larger screens).
Source: https://developer.android.com/guide/topics/manifest/uses-sdk-element.html
You should your increase target sdk level.
targetSdkVersion 25
Related
I have an About box in my App that displays information about the App, the phone and the data it uses. It's very useful when a user has a problem. I can get the phone's SDK version using "android.os.Build.VERSION.SDK_INT". However, I haven't found a way to get the value of "CompileSdkversion" which indicates the SDK version the App was compiled with. This is the value that is set in the build.gradle file.
While the Android OS version varies by user, the compileSdkVersion does not. For version X.Y.Z of your app, the compileSdkVersion is whatever you said it was when you compiled that app version. So long as your about box contains the app version, you know what compileSdkVersion that you used, if you keep track of that (e.g., check what it was in your version control system).
But, if you really want to have it be available to you at runtime, you have two options.
If your minSdkVersion is 31 or higher, you can use compileSdkVersion on ApplicationInfo. However, most likely, if you are reading this before the year 2026, your minSdkVersion is lower than that.
For older devices than Android 12, you could add a BuildConfig field for it, at least with newer versions of the Android Gradle Plugin:
android {
compileSdk 31
defaultConfig {
applicationId "com.commonsware.android.myapplication"
minSdk 23
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "int", "COMPILE_SDK_VERSION", "$compileSdk"
}
// other stuff goes here
}
This takes your defined value for compileSdk and hoists it into BuildConfig.COMPILE_SDK_VERSION, so you can reference it at runtime. This was tested using a scrap Arctic Fox project, using Gradle 7.0.2 and 7.0.3 of the Android Gradle Plugin.
Here is the relationship between the three values:
minSdkVersion (lowest possible) <=
targetSdkVersion == compileSdkVersion (latest SDK)
CompileSdkVersion has nothing to do with what devices can and cannot run your app. Usually, you set this to be the latest version of the Android SDK.
And the targetSdkVersion should be fully tested and less or equal to compileSdkVersion.(It depends on your app)
If you are using the features of API level of 26 then you need to use compileSdkVersion 26, the lower version will give you an error.
Android supports backward compatibility
(i.e. an app compiled on 26 can also run on a phone having API level 26 or lower).
Considering your use-case, wouldn't a better approach be just to show the current app version? If you know the version, you could look up how/when it was created (via git tags, for example) and then find out the SDK version it was compiled with.
everyone!
I'm new to android programming, so simple things sometimes become a problem.
I have my application. It should work on devices with Android 5 and higher.
The question is what is proper strategy of sdkVersion defining?
What I mean.
For example, I need to acheive permision to use bluetooth.
If my target sdkVersion is 7 and minimum sdkVersion is 5 I should ask permission in manifest file and then acheive it in runtime. Like this
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
...
}
But if my target sdkVersion is 5 even Build.VERSION_CODES.M cannot be resolved.
So the question is : what is proper approach to choose sdkVersion? Where can I read about it?
I read here https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target
but I didn't get what is best practice. So please share your experience.
Read this article from Ian Lake: Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion
compileSdkVersion:
compileSdkVersion is your way to tell Gradle what version of the
Android SDK to compile your app with. Using the new Android SDK is a
requirement to use any of the new APIs added in that level.
minSdkVersion:
If compileSdkVersion sets the newest APIs available to you,
minSdkVersion is the lower bound for your app. The minSdkVersion is
one of the signals the Google Play Store uses to determine which of a
user’s devices an app can be installed on.
targetSdkVersion:
The most interesting of the three, however, is targetSdkVersion.
targetSdkVersion is the main way Android provides forward
compatibility by not applying behavior changes unless the
targetSdkVersion is updated. This allows you to use new APIs (as you
did update your compileSdkVersion right?) prior to working through the
behavior changes.
Ideally, the relationship would look more like this in the steady state:
minSdkVersion (lowest possible) <=
targetSdkVersion == compileSdkVersion (latest SDK)
I suppose you are using Android Studio and build.gradle. If not, I recommend you to get it. All of the following is relevant for Android Studio and gradle build system.
Your main mistake is that SDK version in build.gradle of app module is not the same as Android Version. Here is the list of Platform Codenames, Versions, API Levels. What you need for SDK version is number in API level column of first table.
This is how android section of build.gradle for app targeting Android 5.0 and newer should look like.
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "net.eraga.myobjectives"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Read more about targetSdkVersion, minSdkVersion and compileSdkVersion here.
In this case, your minSdkVersion should be 21 (android 5.0) and targetSdkVersion along with compileSdkVersionshould be 25 (android 7.1).
I am getting the following error:
"
The SDK platform tools version (25.0.6) is too old to check APIs
compiled with API 26; please update This check scans through all
ANDroid API calls in the application and warns about any calls that
are not available on all versions targeted by the application
(according to its minimum SDK attribute in the manifest). If you
really want to use this API and don’t need to support older devices
just set the minSdkVersion in the build.gradle or AndroidManifest.xml
files If your code is deliberately accessing newer APIs and you have
ensured (e.g. with conditional execution) that this code will only
ever be called on a supported platform, then you can annotate you
class or method with the #TargetApi annotation specifying the local
minimum SDK to Apply, such as #TargetApi(11), such that this check
considers 11 rather than you manifest file’s minimum SDK as the
required API level. If you are deliberately setting android:
attributes in style definitions, make sure you place this in
values-xxx folder in order to avoid running into runtime conflicts on
certain devices where manufacturers have added custom attributes whose
ids conflict with new ones or later platforms. Similarly, you can use
tooltargetApi=”11” in an XML file to indicate that the elements will
only be inflated in an adequate context."
I also get the package name up top as an error, but I just created the new App and even though it indicates an error. The source code compiles and runs on the emulator on the targeted device.
Go to your App Level Gradle file and enter the following:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.0'
defaultConfig {
applicationId ">>>YOURPACKAGENAME<<<"
minSdkVersion 16
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
If I build my android project using the jack & jill toolchain I can set the minimum SDK version fairly low. When I have jack enabled via:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
jackOptions {
enabled true
}
}
}
I am able to set minimum sdk to:
minSdkVersion 9
Anything lower and I get the error message:
uses-sdk:minSdkVersion 7 cannot be smaller than version 9 declared in library [com.google.android.gms:play-services-location:7.8.0] {project_folder}/build/intermediates/exploded-aar/com.google.android.gms/play-services-location/7.8.0/AndroidManifest.xml
Suggestion: use tools:overrideLibrary="com.google.android.gms.location" to force usage
I don't want to go that low. I am just curious if there are any pitfalls in the range of sdks from 14 to 23 that could come from using the jack compiler. Say with a target of 25, and min of 14.
Is there any odd behaviour or issues that would pop up on older versions of android?
Jack only compiles the code. It does not care what your minSdk is, that is more relevant for using android API's etc.
The reason you're getting an error when you set minSdk below 9 is because google play services requires it to be 9 or higher. If you remove the play services dependency it should work. Also see here
android studio is currently supporting vector assets. according to the literature I can
Create separate APKs for different API levels. When you don’t include
the corresponding raster images in the APK for Android 5.0 (API level
21) and higher, the APK can be much smaller in size. For more
information, see Multiple APK Support.
so I tried creating 2 APIs: -
the pre-lollipop version contains the generated pngs without the vector assets,
while the lollipop version contains only the vectors assets
In http://developer.android.com/google/play/publishing/multiple-apks.html
If an APK you've uploaded for API levels 4 and above (Android 1.6+) has a version code of 0400, then an APK for API levels 8 and above (Android 2.2+) must be 0401 or greater. In this case, the API level is the only supported filter used, so the version codes must increase in correlation with the API level support for each APK, so that users get an update when they receive a system update.
The following is my gradle build file.
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "twitch.angelandroidapps.matchit"
}
productFlavors {
lollipopConfig {
minSdkVersion 21
targetSdkVersion 23
versionCode 3
versionName "21.1.0"
}
preLollipopConfig {
minSdkVersion 10
maxSdkVersion 20
targetSdkVersion 17
versionCode 2
versionName "10.1.0"
}
}
:
//snipped the rest of the build config...
:
however, when I deploy the pre-lollipop version first, followed by the lollipop version, then the pre-lollipop version got archived (and vice-versa).
Any advice on how I can get both versions to be deployed in the play store?
I had it figured out.
When i first deploy the lollipops and pre-lollipops, they get auto-archived.
For some strange reason, I have to manually shift the pre-lollipop version back into production by clicking "Move to Prod" for it to work.
After that, the playstore will show a new "API LEVELS" column.
Also the literature about having a larger versionCode seems to be wrong. Pre-lollipop version needs to always be a lower VersionCode (probably because my API levels do not overlap?). Anyway, I can now deploy new pre-lollipop versions without getting the previous version archived.
In the end, I used the naming convention of
21xxxx for lollipop versions and
10xxxx for pre-lollipop versions
Hope it helps.