I have an application that behaves differently when compiled for API 18 and 19 (behaviour of repeating alarm).
I compiled my application for API 19 (Google API). I ran it on device, and saw that the Build.VERSION.SDK_INT returned 16.
I understand that this says that 16 is the maximal API number that my device can run currently.
I just wanted to verify: In such a case, will my app run the same on such a device, regardless of whether I compiled it for API 18 or 19?
I have an application that behaves differently when compiled for API 18 and 19 (behaviour of repeating alarm).
The core behavior of AlarmManager is not dependent upon how you compile the app. It is dependent upon the OS level of the device and, more importantly, your android:targetSdkVersion.
The only difference in AlarmManager based upon how you compile the app (i.e., your build target, Project > Properties > Android in Eclipse), is whether you have direct access to additional methods (e.g., setExact()) on newer devices.
In such a case, will my app run the same on such a device, regardless of whether I compiled it for API 18 or 19?
This is impossible to answer in the abstract, even if we convert "compiled it" to "set the android:targetSdkVersion". Some behavior changes will occur on newer devices regardless of android:targetSdkVersion; some behavior changes will occur on newer devices only if your android:targetSdkVersion is set to that API level or higher.
In the particular case of AlarmManager, some of this is covered in the JavaDocs for the particular Build.VERSION_CODES value of interest, such as KITKAT:
AlarmManager.set becomes interpreted as an inexact value, to give the system more flexibility in scheduling alarms.
It is also echoed in the documentation for AlarmManager itself, such as:
Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
Target API != your device api
For example, if you set target API to be 16, you can access all API with version <= 16
When you run on a device with newer API, it would still works as all public API should be backward compatible
But in some cases, the target API does change the app behaviour.
For example, kitkat webview has changed a lot, some old code actually have conflict with the kitkat api. But to keep backward compatibility, it would not crash with target api < kitkat. But if you set target api to be kitkat, it means you know the new api changes in kitkat, it does crash if you run those old problematic code. To keep device with old sdk working, you would need to check the sdk version of device, and run different code in different sdk.
So for your case, if you need the alarm fire exactly the time you set, here is the code:
if (Utils.isKitKatOrLater()) {
am.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
} else {
am.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
}
You should use emulators...
Set as many as you can, running devices with different OS versions.
I know they are slow, but they are an invaluable help.
Your device runs on API Level 16 because there's Jelly Bean installed (version 4.1 or version 4.1.1).
So it's backward compatible up to minSdkVersion (as defined in your Manifest).
Your targetSdkVersion should always be the latest.
Related
This question already has answers here:
What is the difference between compileSdkVersion and targetSdkVersion?
(11 answers)
Closed 5 years ago.
I know that targetSdkVersion is the "highest SDK version, your app is known to work with", but what is the point? I set my targetSdkVersion 22, and my app runs fine on an api 25 device. Is it not meant to prevent installation on further api versions? If no, then what is it meant for?
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).
There are many compatibility behaviors that the system may enable
based on the value you set for this attribute. Several of these
behaviors are described by the corresponding platform versions in the
Build.VERSION_CODES reference.
To maintain your application along with each Android release, you
should increase the value of this attribute to match the latest API
level, then thoroughly test your application on the corresponding
platform version.
Introduced in: API Level 4
Sorry for just posting straight from Android.com but it gives a clear signal of what it does.
It is the one you are developing for. App can work on higher API as well. But it is the one used for rendering layout etc.
I'm developing a android SMS App.
Currently i am using 2.2 API and it needs to stay that way.
With the new KitKat framework to send/receive sms messages i got a problem to know if to use the KitKat SMS or the lower API SMS Framework but i want to be able to use the lower sdk all the time except for times when the device is KitKat and he would use the KitKat api instead.
I saw the solution to use android.os package to check what kind of os u got but if i write in a class KitKat sms functions , wouldn't it make my app 4.4 api?
Thanks headds up
While creating your project you should target the lowest API level possible. Because if you are not using any KitKat features you should not target KitKat. Because all those people using Gingerbread (2.3–2.3.7), Honeycomb (3.0–3.2.6), Ice Cream Sandwich (4.0–4.0.4), Jelly Bean (4.1–4.3.1) will not be able to get your application even though it runs fine on their devices.
You can specify your target api in AndroidManifest.xml :
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10"
android:maxSdkVersion="19" /> //example only
Take a look at the documentation in android website : uses-sdk
You can encounter some method that is deprecated in lower version when using lower version API that is not currently used in Upper Version
Use this structure:
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KIT_KAT)
// for kit kat devices
else
// all other devices
minSdkVersion determines the minimum Android version the app will run on. So you can set the targetSdkVersion in manifest to the API 19 to get access to Kit Kat functions and still have you app work on lower versions.
You have to target with the lowest API level. If your API level 10 will work for API level 11, 12, etc but it can't support API level 9, 8 (Lower API comparing with your current API). It support all higher versions.
I have defined in my manifest android:targetSdkVersion="15" and I would like to test with a device with API level equal to 17.
The minSdkVersion is set to 15.
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
I know it will work since minSdkVersion is set to a lower version than the device's one but my question is should I change the targetVersion whenever I change the device ? Isn't the targetSdkVersion supposed to be always equal to the one of the device I am testing with as it is said in the reference
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html ?
You shouldn't change the target version with every device, but with every new API level that is released.
As the webpage that you've already posted states:
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.
and a few lines further:
To maintain your application along with each Android release, you
should increase the value of this attribute to match the latest API
level, then thoroughly test your application on the corresponding
platform version.
Every new API contains new features, but will also deprecate old ones; some may even get removed completely! So devices running with a higher API level might not support the same features anymore that you used in your app, which forces them to enable compatibility mode to once again be able to run the app properly.
In short, no, your targetSdkVersion should just be as high as the highest API goes. The minSdkVersion should of course be as low as possible, and you should try to avoid using maxSdkVersion, as that one will decrease the mobility of your app over time.
Even if your minSdkVersion is 1 and the targetSdkVersion is 19, new devices won't have to enable compatibility mode to run the app.
I'm new in the android developing.
I need to write some simple application - and i need to decide what will be the target version.
I don't know how to decide this - because i want to support the most newer version with all the new abilities - but i also want to support the maximum devices ( there are few devices that have old versions )
So, How to decide what will be the target version ?
In the Android Manifest.
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
Set your android:targetSdkVersion to whatever is the last Android SDK version.
Quote from Bruno Oliveira at Google IO:
targetSdkVersion does not affect the minimum SDK level required to run your application. It should always be the latest version that you are aware of.
The only reason you could have to use a lower version would be to detect incompatibilities, but that is not a good reason because Lint does this better.
BUT set your android:minSdkVersion to as low as your app will run on. That's the important one.
For instance, my app uses very new features, but I set android:minSdkVersion to 3 (which means Android 1.5). My code detects Android 1.5 devices, and uses less-shiny controls on them, but still runs correctly.
Detection code sample:
if (android.os.Build.VERSION.SDK_INT > 4) {
ActivityTransitionAnimation.slide(this, ActivityTransitionAnimation.UP);
}
So, here is my suggestion:
Set android:minSdkVersion to 3
Everytime you discover an API is not present at that level, ponder whether the loss of potential users associated with increasing this number is worse than spending the time to implement a workaround.
I would say just start off with the lowest possible target and then as you encounter stuff that you can only do with a higher target you will have to change the target to the higher one. Using APIs that only work on for example 2.3 will show errors if your target is lower (because the APIs won't exist there).
Also you should consider the current state of the "fragmentation" to se what targets are actually being used out there. Looking at this chart (from October 5) maybe it could be worth just starting with 2.1 and se if it is high enough for all the things you want to do:
http://cdn.devilsworkshop.org/files/2011/09/android-OS-fragmentation-report.jpg
When developing an Android app, let's say I want it to be compatible with 1.6 (API Level 4) devices, but still enabling 2.2 (API Level 8) features such as adding android:installLocation to enable moving app to SD card. Therefore I set Eclipse to compile against 2.2 SDK instead of 1.6 SDK.
Adding unknown attribute like android:installLocation doesn't crash the app when running in 1.6 device, but in case when coding I call some API that is unavailable in 1.6, such as android.util.Pair or Base64, the app will crash when running in 1.6.
Is it possible (e.g. via an Eclipse plugin) in build-time (not in run-time!) to check whether the project is still compatible with 1.6, in other words, check whether there is any API calls to any of the methods/classes requiring more than 1.6 (API Level 4)?
The best way to check if your app uses a non-existing API on older handsets is to change the target to the old version (starting from the minimal one you support) and seeing if you have any compilation errors... This will point you to non-compatible API calls.
At least that's the way I do it.
This is a tough problem to handle gracefully in code. I asked a very similar question here.
It seems to me that you may be asking the wrong question. Checking for calls to new API features is reasonable, but if you want to make your app work well over multiple versions, you will have to have code that makes calls to old and new API levels as appropriate. There are many ways to do this and it's considered a best practice.
In that case, you may want to downgrade your target version and check that all the errors that come up in Eclipse are handled well in your code (and of course try it in the right emulator versions).
I know this question is ancient, but there is a "holy grail" solution to this issue (at least from your users' point of view):
You can publish two versions of your app, one requiring API level 8 and another requiring API level 4. Then, use versionCode 100, 101, 102, 103, ... for your level 4 version and versionCode 200, 201, 202, 203, ... for your level 8 version.
That way, if a user has API level 8 available, they get offered only the level 8 version of your app as it has the higher versionCode. And users that only have API level 4 through 7 available, get offered only the other version as the other one is incompatible.
It's a little bit more of a pain to maintain, but it has the (potentially huge) advantage that you can customize the reduced-features version to still provide a complete experience (no grayed-out buttons, etc.), and you can even keep the APK size smaller for that version as you don't even need to ship the code or related resources for the unavailable features.
You can find more details in Android's Multiple APK Support documentation.