Even though I have done some app on android, I am still confused. Is it possible to use functions in SDK 4.0, and run the app on android 2.1 or lower?
I tried methods you guys mentioned but got an error -
Field requires API level 11 (current min is 7): android.os.AsyncTask#THREAD_POOL_EXECUTOR, if I change min to 11, the app can't install on android 2.1, so even I can use higher API, but it still can't run on android lower version...how to fix that?
From Kzinch's advice, set TargetApi to 11, then it's working!
If you want a program that runs on both SDK4 and SDK 2.1 you have two possibilities. One is to provide alternative implementations on your code when they are needed i.e., if some function from SDK4 is not available in the SDK2.1 then you add a conditional block to your code that check the SDK version and provide code for each branch.
The other possibility is to use the Android Support Libaries in order to use the same code for both SDKs (no conditional blocks required). If you need a function provided by the SDK4 but not for the SDK2.1 you can check if that function is provided by a support library. If it is you can use it and your code will run fine on both SDK4 and SDK2.1 without requiring any version checking. For instance, if you need to use the LruCache class which is available since API level 12 (and so not available on SDK2.1) you can use the v4 support library which provide that function and works on SDK2.1 and SDK4. So in your code you would use
import android.support.v4.util.LruCache;
instead of
import android.util.LruCache;
Yes, you can use functions from the higher API in your code, but you must make sure they are never called on the lower API in runtime.
You should make checks for API level in runtime and provide alternative implementation that exists for that API level.
Let me provide some simple example:
SharedPreferences.Editor edit = PreferenceManager
.getDefaultSharedPreferences(getActivity()).edit();
edit.putInt(KEY, VALUE);
if (Build.VERSION.SDK_INT >= 9) {
edit.apply();
} else {
edit.commit();
}
apply() method is a faster (asynchronous) implementation of commit() method, but it not supported on the API level less than 9. With the help of API version check it all works perfect for all devices.
Update #TargetApi annotaion may be used to suppress Lint warnings/errors for API checks.
it doesn't matter what SDK level you compile your code against. Important is which methods/classes are you calling/instantiating.
If you use any newer classes or methods your code WILL crash running on older devices.
The suggested method to deal with it is Lazy Loading: http://android-developers.blogspot.co.uk/2010/07/how-to-have-your-cupcake-and-eat-it-too.html
and remember, I'm saying this about the SDK.
The compatibility pack is a library developed by google that you can add to any project and use the functions of the library without issues.
Furthermore, there're 3rd party libraries (such as the ActionBar Sherlock http://actionbarsherlock.com/ that aims to bring higher SDK level functionalities to lower SDK levels)
No. You cannot use methods from higher API, because the code to handle it is simply not present on lower version of API. You can, however target as high API version as possible, but you may take care to call these methods on right API. You can easily check that at runtime with. i.e.
f( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
// code to be run on Honeycomb and higher versions
}
If you are using the API which are specific to higher version, then the app wont work in older version.As those are not defined in the older version it will throw an error.That is the reason we restrict apps before uploading into market using minSDK in AndroidManifest.xml.
Related
I am developing an app which has to support at minimum level 10 sdk. Today, I was coding when I came across a method setLayerType() which I need to use. But this method is introduced in API level 11. So, I used a workaround and used Reflection to use this method.
So, my question is, won't my application still crash on device which runs on API level 10?
This question came to my mind because, even though I am using Reflection here, still, I am calling a method that was introduced in API level 11. Will this method run successfully when I run my app on Android devices that run on API level 10 or will it crash?
As stated in source, the method will run independent of OS level. But, why should it run successfully on API level 10 device which is still using Android.jar of API level 10 and that file doesn't even contain this method?
I tried to search it but couldn't find an explanation.
P.S. I wanted to test it on a device with API level 10, but as building full app will take some time, so it is not possible to test app on API level 10 device right now.
No, of course the app will crash if you call a method that is not present in its API level. This is true whether you call by reflection or not.
The point of reflection is that you choose whether or not to call it based on the API level. Compare http://developer.android.com/reference/android/os/Build.VERSION.html#SDK_INT to http://developer.android.com/reference/android/os/Build.VERSION_CODES.html in your code and only proceed with the reflective call if the SDK number is high enough.
The point is that you isolate code with bytecode references to any method or constant or class that's not present in all API levels into a separate class that is only loaded by reflection.
Here's an example of some utility code I created just to manage this kind of thing; it loads one or the other implementation of an interface based on API level:
https://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/common/PlatformSupportManager.java?spec=svn2361&r=2361
EDIT: #FD_'s answer works too which surprises me. Reflection is safer, but much more code. And it seems like the reflection approach is in fact unnecessary on recent, if not all, Android JVMs.
You don't even need Reflection for that. Just specify your target sdk as high as possible, and your min sdk as low as it is now. Then, before calling a method that was introduced after the min version, just check which api version your app is running on:
if (android.os.Build.VERSION.SDK_INT >= 11) {
//Your code here
}
Trying to use methods that were introduced in a later api version will lead to a crash otherwise, whether you call it using Reflection or not.
Well we started an application with support from API Level 8 i.e Froyo verison. Now we being on API level 18 Jelly Bean version, how do we stop using deprecated API's on my application.
One Example
Dialog(API 1) vs DialogFragment(API 13)
Following are in my mind
1)Use Android Support Library Good way to go?
2)Have a runtime API level check as below, is this a healthy habit?
if (Build.VERSION.SDK_INT==Build.VERSION_CODES) {//Some API Level
run a code
}else if(){
run a code
}
3) Use reflection?
4)Have separate code base to each API level,makes no sense.
5)Does Palystore allows us to uplaod multiple Apk's based on API level.Or the complete control is on uses-sdk manifest value.
<uses-sdk android:minSdkVersion="integer"
android:targetSdkVersion="integer"
android:maxSdkVersion="integer" />
What will be the best way use latest API's with only one code base and make one APK and inturn have backward comparability support.
Inputs will be much appreciated.
One Example Dialog(API 1) vs DialogFragment(API 13)
Dialog is not deprecated. Ways of using Dialog may be deprecated, such as the old-style managed dialogs.
Use Android Support Library Good way to go?
Generally, yes.
Have a runtime API level check as below, is this a healthy habit?
Yes, though usually you use >= or <=, not ==, to drive behaviors for a range of API levels.
Use reflection?
I wouldn't.
Have separate code base to each API level,makes no sense.
Does Palystore allows us to uplaod multiple Apk's based on API level
In some extreme cases this may be required. Most apps should not need this.
What will be the best way use latest API's with only one code base and make one APK and inturn have backward comparability support.
That is impossible to answer in the abstract.
Why not upload the existing application as a "legacy version" of the application, that supports older version of the app, and continue to develop the existing application for newer devices?
Is there any way to detect the current version of android and use one code path for one version, and another code path for a later version?
Something like ClipboardManager, there is a new version in API level 11, but the only way of accessing this new class is by telling mono for android that the minimum requirements is API level 11.
I "think" you can get around this using java reflection, but I imagine this wouldn't work when using Mono for Android. Has anyone got any advice on how you can use both ClipboardManager's, the early one on earlier versions, the later one on later versions, without setting the API level as 11 or higher.
This is a generic example, not limited to ClipboardManager. I am sure I will come across more classes that I could optionally use if it is available.
Sure there is. Just make sure to set your target API level in the manifest.
When wanting to use API 11 for instance you could do something like this:
if ((int)Build.VERSION.SdkInt >= 11)
{
//Execute API 11 and up code here
}
However if you are using methods and classes that are only present in API 11, VS might complain that it cannot find them, so you can surround them with a pre-processor symbol like:
#if __ANDROID_11__
// your API 11 and up code here
#endif
I am kind of new to Android world and have a simple question.
If I develop an app using libraries on API 13 (or API10) will this app still run on Android phones which have only API 7 installed?
When I try to run my current app with EClipse on my Android phone with API 7 I get an error message that my app requires at least API 10 - so I am afraid to develop on API 13.
Should I better just stick to API 7 and not use the new features?
Whats the best thing to do in this situation?
Many thanks
It will work if you are not using any function from API10 which is not present in the older APIs.
You can still use the new functions with reflection.
First check if the function is available, then execute it with reflection.
Example:
// try to override the transition animation
if (VERSION.SDK_INT > android.os.Build.VERSION_CODES.DONUT) {
try {
Method method = getClass().getMethod("overridePendingTransition",
new Class[]{int.class, int.class});
method.invoke(this, 0, 0);
} catch (Throwable e) {
// can not override transition animation, so do nothing
}
}
Also make sure you set android:minSdkVersion.
You generally want to develop using the minimum API version possible for the features your program requires. This will allow it to work on the most devices.
API 7 devices can run API 7 and lower.
The message you get is just a response to what is set in the manifest file. You can change the min API version for your application:
<manifest android:minSdkVersion="9"> </manifest>
As Heuristic said, you should use the minimal API version because of compatibility reasons, but if your application uses libraries from a newer version of the one installed on the phone, the app will not work.
If you have a true minimum API level you should develop for that level and with the appropriate minSDKVersion flag set so that your application won't even appear in the marketplace for devices that do not meet that standard. In general answer to your question, the minimum possible requirements will depend on what features of the API you take advantage of. If you want to provide backwards compatibility but still want to use some of the features in the newer API I think you're going to need to create two versions of your application and set the min/target/max SDK flags appropriately so customers get the version best suited to their device.
You can check out the Android API listing to see what the differences are between each level to determine if there's some functionality you'll really want to use.
http://developer.android.com/guide/appendix/api-levels.html
I'm working on an app that targets API 11 (3.0) but minSDKVersion is 7 (2.1).
I generate my PreferenceActivity programmatically instead of with XML. In Honeycomb, preference layouts have a built-in spot for an icon that can go next to each preference. You can set it with prefScreen.setIcon(R.drawable.my_icon);
So I don't want to do this on API 7-10. Is this sufficient protection from crashes?
if (android.os.Build.VERSION.SDK_INT>=11)
prefScreen.setIcon(R.drawable.myIcon);
The more elaborate solution that I know is safe is to use reflection to check if that method exists before trying to use it.
According to http://developer.android.com/training/basics/activity-lifecycle/starting.html, it's implied that it's safe to use the SDK_INT constant on Android 2.0 and above to wrap calls to newer APIs, without using reflection.
Caution: Using the SDK_INT to prevent older system's from executing
new APIs works in this way on Android 2.0 (API level 5) and higher
only. Older versions will encounter a runtime exception.
This worked for me:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){
//code
}
If the method is not available on a lower versions of the platform, it will crash when the file is loaded by the system (it won't even make it to execution of your if statement)
You should look at the article on Lazy Loading to do the reflection on the Android Dev Blog