Progressive Enhancement for Android? - java

Is it possible to use progressive enhancement when building Android apk's.
I'd like to build an app which can be used on SDK 8 + (gingerbread is the dominant android version) and when possible add features from newer version.
I know I can get the SDK version with SDK_INT to do something conditional, however when I use features introduced in later versions, eclipse won't let me build saying I need to increase the min SDK level.
Maybe my web development background is what's causing my thinking this to be possible, it may just be fundamentally impossible, do popular apps have different versions for different SDKS (like min8-max10,min11-max15)? Is progressive enhancement in Android Java code possible?

check if the build fails because of Lint errors, if so, and you're certain that a specific method won't be called on non-supported devices, add an annotation to that method with the min api level it can be called on as such:
#TargetApi(14)
public void useSomeNewApis() {
...
}
Or, if you're using eclipse, you can hover on the error line, and choose add #TargetApi(14) to useSomeNewApis

Something like:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/>
should be enough. But when program hit code from newer API than is on device then it will crash.

You need to make sure you are using the correct version of android. If you want to use a feature available in API 15 you have to build it in that API.
So if the feature you want to use requires API 15 make sure that in your project properties you have Project Build Target set to that API.
Right click on the your project and go to Properties. Select the Android section and make sure the correct API is checked.

Related

Recommended Android API levels

I am learning the Android SDK and I am getting to the point of getting a bit more comfortable to start doing actual app development. I have done some reading here and there online, and based on my limited understanding, I as a developer, should include the Android API levels that I intend to make the app available to. My question is related to this...
Based on some charts online, it seems to make the most sense to support devices from 2.3 (Gingerbread) all the way to the current KitKat API. So that would mean API level 10 - current.
Question 1 Do I have to download all the API levels in between (i.e. 3.0, 4.0, 4.1, etc...)or is the lowest and highest be enough?
Question 2 If I do not end up downloading those API levels in between? What would a user running, say 4.0), experience? Would they be totally unable to run the app? Or would it simply mean that I, as a developer, would not be able to use any of the APIs states in those levels?
I understand that there might be some compatibility issues, from changes in the API which I would need to work out myself.
Thanks you for your clarification.
Answer to Question 1
You can develop your application using any API version. In Android Manifest.XML file, you specify the Minimum SDK version that your application supports. Based on that value, your application works in all API ranging from the min value to the current Value.
Please note that you can specify the MAX SDK value supported but this is not recommended.
Answer to Question 2
Once you develop an application, it is good if you test it on various API versions. If you download different platform versions, then you will be able to create different emulators and test your application. But your application will work successfully even if you install only latest version.
Also, as a developer, from the application code, you can make your application utilize certain libraries supported in higher version and do not use those SDK if the application is running in low API devices. You can do this through code.
Similarly, compatibility issues can also be addressed in code.
You just have to download the latest API. You can define in your app what the minimum Android version can run it (you should start low but as you add more and more features you're going to learn that you might have to increase it) and anything between the version you define and what the current highest version is (19, at the moment) can run it. They all might have slightly different experiences, but it'll all be similar in general (like, I have an ActionBar in my app and it looks pretty different between JellyBean and Gingerbread, but it's there nonetheless).
The main thing is that for backwards compatibility there are support libraries that you'll have to download and include in your app which aren't there by default (android-support-v4.jar for example).
A big tool you can use if you want to include certain features on higher API devices is check to see the current API of the device) and then implement accordingly. The most important thing is testing on different level APIs to make sure your app works on all of them.
You can configured minimum and Maximum API level in Manifest file.So that you can covered maximum device.Please put following code in your manifest file,
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />
Thus your application can run on device having API level between 15 to 17.

Which versions of Android SDK support coding in which versions of Java?

I was writing an Android app for Android SDK 2.3.3 but then I was asked to test it on a device running Android 2.2.1. So I set my target to 8 instead of 10. But then java.util.concurrent.TimeUnit only had the Java 1.5 feature set instead of the Java 1.6/1.7 feature set of java.util.concurrent.TimeUnit. So I put the openjdk 6 implementation of TimeUnit into my package for my Android app and everything works fine.
Does anyone know where I can get some documentation that gives me a chart that tells me, for example, that when using the official SDK, Android 2.2 has to be coded using Java 1.5 keywords/syntax/APIs, Android 2.3.3 can be coded using Java 1.6 keywords/syntax/APIs, etc...?
You are trying to look at Android as a subset of Java which it is not. They are completely separated. Even though Android comes from Java, it as departed from it quite a bit and there is no correlation 'version-wise' anymore between the two.
What you can look at is the Android documentation. For every instruction/command/method/properties, at the top right you'll find the api level at which you are able to access said property.
Clicking on the api level will take you to a page which contains a table that translates api level to Android versions.
The easy way to find out if you are allowed to use a property is using eclipse and doing what you just did : Change the target api level. Then any call to methods or properties that are not available to you will produce fatal errors.

Use preprocessor in Android project in Eclipse

I am trying to use preprocessor like #ifdef in my Android project in Eclipse. I did some research on this topic and found this link: Java Preprocessing Using Eclipse, which could potentially let me use preprocessor in Android project.
However, after I tried to build the project, it claimed something like package android.* does not exist. So, none of the android APIs could be found.
So, how should I add those libraries in the build path? Actually, android.jar file is under the Java Build Path already. Why does Eclipse still claims that?
Is there any other way to let me use the preprocessor in Android Project built in Eclipse?
You are programming in Java, not C/C++. Android development does not require the use of a preprocessor.
Edit:
My problem is we developed an Android app with USB functionality which is supported only by Android 3.1+. So, some of the USB libraries are imported, what I want is those imported libraries could be commented out using #ifdef, if we could, when we build the project for Android 2.2 or 2.3, etc. Is there any other workaround for this?
To make use of the classes/methods you mentioned, you'll have to build your application against the Android SDK version 3.1 or higher. However, you must also ensure that devices running version 3.0 or lower don't make use of these classes/methods during runtime, since doing so will result in a ClassNotFound exception.
The key take-away here is that you need to perform these checks at run-time. Since your application is compiled only once for all devices, a preprocessor could do nothing to prevent such an event from occurring. Instead, you need to explicitly protect against this in your code. This is usually done with a basic if-else statement. For example,
if (Build.VERSION_CODES.HONEYCOMB_MR1 >= Build.VERSION.SDK_INT) {
// then you are on a device running android 3.1+ and it is
// safe to make use of the new classes/methods
} else {
// otherwise, you are running on a device running android 3.0
// or lower. you should not make use of the new classes/methods.
}
Edit #2:
In response to bill's comment, which read:
Thank you, Alex. I built my project agaist 3.1, deployed it on 2.2 and run it. One last thing I am not quite sure I understand is I could debug the part of the code referred by the Android 3.1 on the Android 2.2 OS. Here is my explanation: after being built against 3.1, Java code is converted to machine code and HONEYCOMB_MR1 is just an integer although HONEYCOMB_MR1 is not present in 2.2, when I debugged it, the debugger goes to the line of HONEYCOMB_MR1, fetches that integer and compares with SDK_INT. In this way, the code could still be debugged although HONEYCOMB_MR1 is only in 3.1 SDK. Is that correct? Thanks.
I think you are understanding correctly. The more exact reasoning is that HONEYCOMB_MR1 is marked static final. Since the variable is an immutable constant (i.e. its value will never change), the integer is hard-coded into the bytecode when you compile the .apk. In So when your 2.2 device reaches the if statement, it checks to see if 12 > 8, thus avoiding a (failed) runtime search for HONEYCOMB_MR1.
This sort of thing actually happens quite frequently when you develop your Android application. For instance, this behavior also explains why you can use MATCH_PARENT (introduced in 2.2) on devices that should "technically" only support FILL_PARENT. Both constants have value -1; thus, when you run an app that uses MATCH_PARENT on a pre-Froyo device, all works as expected.

Can I change the platform version of an android app after creating it?

I am just learning about android app development and have created my first app which is a relatively simple app with a link to a gallery of images and some text pages. I created this using the 1.5 platform as it seemed sensible to make it backwards compatible. I've been testing it on 3.0 and it comes up tiny on the screen and I have since learnt I need to use supports-screens and other related commands to allow variable screen support which from what i read is only available in 1.6 and above. As a result I need to change the app platform to 1.6 or above and my questions are as follows:
1) Am I able to just go to project properties and change the platform version tickbox to a newer one (in this case 1.6)? As I tried this with the project but the supports-screens tag still gives an error (which it doesn't when I create a brand new project)?
2) What version should I be creating it in these days for ideal backwards compatibility but able to use most desirable features? I understand 1.6 includes a lot of the newer functionality but according to http://developer.android.com/resources/dashboard/platform-versions.html only about 4% of people are using less than 2.1 so is it better to just code using 2.1 (assuming I want to target mobiles and tablets)?
Thanks so much for your help as ever,
Dave
Take a look at this. It explains how you can go about changing your AndroidManifest.xml to specify which version of the SDK to use. You may also need to update default.properties to point the target to the proper api value.
This really depends on what you want to do. If you require something from 2.1 or 3.0, then I think you need to go with that. But if you can get by using just 1.6 and still have all the functionality that you need/want, then I would definitely recommend using 1.6.

Android app using 2.x APIs that will also run on 1.x

I'm working on an Android app in which I would like to use multi-touch. However, I do not want to completely leave out those still running a 1.x OS phone. How do you program the app so that you can use the 2.x multi-touch APIs (or any other higher level API for that matter) and still allow it to gracefully degrade on 1.x systems. If you create a project in Eclipse for 1.x can you even still access the 2.x APIs?
Basically I want it to show up in the marketplace and work on all 1.6 and higher phones and just allow access to the higher level functionality if available.
Also, if anyone can point me to any data on the number of 1.x devices vs. 2.x devices in use, it would be greatly appreciated.
Here is how I use the AccountManager on 2.* but have a fallback on 1.* where it isn't available.
I build with the 2.1 SDK, but my Manifest states
<uses-sdk android:minSdkVersion="3" />
This does allow the app to run on 1.5 devices upwards.
I restrict my use of android.accounts.AccountManager to a wrapper class, I called it UserEmailFetcher.
It will be possible to use this class on 2.* devices. However on earlier devices a java.lang.VerifyError will fire the first time this class is encountered in the code. This I catch, and perform some fallback action.
String name;
try {
name = UserEmailFetcher.getEmail(this);
} catch (VerifyError e) {
// Happens if the AccountManager is not available (e.g. 1.x)
}
Hope that helps.
There's a good Android article on this topic called "Backward Compatibility for Applications." Essentially there are two things you can do:
Set the minSdkVersion so that the app identifies itself as being compatible with a version of Android lower than what it was compiled on.
Use reflection to access newer APIs.
You can also create a wrapper class for speed/ease of use, but that's just a flavor of #2.
As for platform usage, Google released this data a few months ago.
Using reflection seems to be the way to go :)
Hello p2p Android Wifi in API level 14
http://developer.android.com/resources/articles/backward-compatibility.html

Categories