I have an app to release which works on all android screen-sizes (except smaller) and densities above SDK version 2.0.
It will also run on extra large screens.
Currently I have added this:
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="false"
android:anyDensity="true"
/>
But I also need to add android:xlargeScreens="true" , to allow it visible in android market on extra large screen devices, since by default it is false.
But to add android:xlargeScreens I need to change my eclipse targetsettings to 2.3 as this attribute was added from API level 9.
So what should I do with my target compilation settings for this scenario ? Should it be 2.3 while compiling ? If yes, then will the app not give any problems while running on devices with 2.0 version ?
Yes you need to change the uses sdk to 2.3 but make sure that you are not using any newer apis which are not in 2.0 or whatever your minimum supported sdk version is. Or in case you want to use them you have to use reflection.
But more about how to use the sdk versions is here and more about uses-sdk is here.
I do the same in my application and make sure you test your application in both[all] the versions before you release.
Best,
Achie.
I'm moving this from the comments to make it more clear for others looking at this question in the future.
When supporting both old and new versions of Android it can be confusing how applications manage to run despite many things change with in the frameworks during each new release, I'm going to try and clarify this here.
An application written for the 1.5 sdk can only call functions that exist for that API level, so for instance the multi touch api's didn't exist in 1.5 and never will. Now you say "Ok but I don't need to call any newer APIs, I just want my app to work in 2.3 and have a2sd support" And I say "Ok, just change your targetApi in the manifest, set the minSDK and compile against 2.3 and you're good to go."
Now why does that work? What if the onMeasure() method for ListView was changed in 2.2 and now calls betterCalculateFunction() within onMeasure()? Why does my app still work?
This is the advantage of late binding in Java. You see, Java is never compiled until it reaches a device and is running, what you are doing in Eclipse is converting it to byte code which contains a bunch of byte code instructions that are later interpreted by the device. The byte code will NEVER contain a reference to betterCalculateFunction() though (unless you directly call it. Calling onMeasure() is indirect). This can happen because when your code is running on the device it gets linked against the Android framework on the device and your code calls onMeasure() directly because it is a public outward facing API. The path of execution will then enter the framework and call whatever it needs to, then once its done return to your code.
So on 1.5 you might see
doStuff (your code) -> onMeasure
(public API) -> done
and 2.2
doStuff (your code) -> onMeasure
(public API) ->
betterCalculateFunction (private
function) ->done
Now if you need to call functions that may or may not exist depending on API level then I suggest you look at a related answer of mine here stackoverflow: gracefully downgrade your app
Hope that clears some things up.
I haven't tried 2.3, but that's what I do with 2.2.
I compile for 2.2 and test on 1.6 to make sure everything works how I'm expecting. I haven't run in to any issues with it.
To double check, set your target for 2.3 and then setup an emulator for a lower rev version to make sure it all works.
The default value for android:xlargeScreens is true, so you don't have to change anything - it's on by default, as long as your minSdkVersion or targetSdkVersion is higher than 4.
http://developer.android.com/guide/topics/manifest/supports-screens-element.html
Here is an official Android developer blog explanation of how this works:
http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html
In summary: you can use the newest XML whilst still supporting the older OS versions in a back compatible way.
While reading this blog post I guess I have an answer on my old question. An extract below (which is for another manifest attribute "requiresSmallestWidthDp" introduced from 3.2):
"The catch is that you must compile your application against Android 3.2 or higher in order to use the requiresSmallestWidthDp attribute. Older versions don’t understand this attribute and will raise a compile-time error. The safest thing to do is develop your app against the platform that matches the API level you’ve set for minSdkVersion. When you’re making final preparations to build your release candidate, change the build target to Android 3.2 and add the requiresSmallestWidthDp attribute. Android versions older than 3.2 simply ignore that XML attribute, so there’s no risk of a runtime failure."
For different screens you have to create multiple apk then it reduces size of your application.In each application's manifest you have to define according to following link.
http://developer.android.com/guide/practices/screens-distribution.html
Related
I'm just wondering, if the latest Android SDK installed on a device contains code of all the previous versions as well?
So if I target API level 10 in my app and install it on a device with Lollipop, will it just take and use Gingerbread SDK exactly as it was 3 years ago?
Or is there just one codebase for all versions with a lot of checks and switches which is then run by some kind of compatibility mode picking the correct code and enabling methods of the version of SDK I target?
I read the article about android:targetSdkVersion specified in Manifest but still would like to know how this works internally.
Ok, I just surfed a bit around on the source code (which you can find here: https://github.com/android/platform_frameworks_base). I'm not an engineer of the Android framework, I was just curious about your question and here is what I found.
It does not contain all the different versions of source code. You can imagine that this would result in a nightmare if more and more versions become available. Foremost, you would have different (buggy) versions of the same method without fixing them just to keep them the same.
In the source code, you can find places like these: (see https://github.com/android/platform_frameworks_base/blob/59701b9ba5c453e327bc0e6873a9f6ff87a10391/core/java/com/android/internal/view/ActionBarPolicy.java#L55)
public boolean hasEmbeddedTabs() {
final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
return mContext.getResources().getBoolean(R.bool.action_bar_embed_tabs);
}
// ...
return mContext.getResources().getBoolean(R.bool.action_bar_embed_tabs_pre_jb);
}
So the Android developers do the version check in the code where necessary. But these checks are not as necessary as you think (I guess). What's the reason for changing a method?
method is buggy: All they need to do is fix the bug. Tests will make sure that the general behavior of the method keeps the same
method is deprecated: The guys can not remove the method, all they can do is mark it as deprecated and hope for the best. Compilers will do the rest.
method behavior has to change: Well, I guess that is something they can not do easily. They can work around with version codes (which is pretty ugly and becomes a maintenance nightmare), or they just introduce a new API. That's the reason why you'll find a lot of APIs just doing the same
If you have write down a code with latest android sdk and install it in your device. It means actually you are using latest android.jar(you can see android.jar in your project) file while compiling/Executing code.
Now If you install your application in ginger bread device then android.jar(latest) has a backward compatibility(if required) to run code in Gingerbread device.and if you define target sdk version 10 and running app on Higher API level ,then it will run smooth except your compatibility behavior disable in respective device other than targeted devices.
I am making application with target SDK set to 17 and min to 8.
So for some features I have to use Support library v4
Question is how can I test it works on older devices?
I am testing on my phone - which has 4.2.2; and I don't have others with older ones
Will creating emulator with 2.3.3 be true test?
tnx
Update
Just for example: I use Fragment in my code (from android.app, not from support library) - even if my minSDK is 4 - I don't see any warnings...should I?
Yes. It is an emulator (not a simulator) so it is very similar to running your code on the corresponding phone.
Another good practice is to run the Lint tests from times to times, they can detect many common mistakes in your code (including compatibility).
Your ide (both Eclipse & Android Studio plugins do this) will also display warning for obvious calls to functions that don't exist at your chosen min API level.
Most of the time emulator behave same if we consider layout view and
other stuff like look and feel performance , but that can be
difference in case of speed performance and sound quality
.
I found one online tool which are providing that service please go through that link , https://appthwack.com
apache lint (from tools) is the answer - shows all problems
Can you explain to me how I should determine the correct value for targetSdkLevel?
Let's say I want to build an app that works on all the versions from android 2.3.7 to 4.0.3, how should I set minSdkLevel and targetSdkLevel?
The former should match the API level of android 2.3.7 and the latter should match the API level of 4.0.3?
Then, when I develop my app, should I use only Methods/classes available in the oldest supported sdk level?
When I compile the app does it compile for 2.3.7 or 4.0.3?
I can not understand the purpose of targetSdkLevel, since the apk can not be compiled for the newer version specified in this tag, otherwise it could not work on versions down to the one specified by minSdkLevel... Why should I not set targetSdkLevel to the latest available level?
I've read also the official info about uses-sdk Manifest tag, but I still do not understand.. Can you help me clarifying this topic?
EDIT: thanks to all of you and excuse me for the duplicate question. I've read this Blog post and it really helped me. Great answers from all of you.
You should only use methods/classes available in the SDK specified by minSdkLevel, or otherwise wrap them with a proper check for the runtime API version.
Your application will be compiled with the SDK specified in the project itself, not by the one specified by either minSdkLevel nor targetSdkLevel.
You should set targetSdkLevel to the highest level API that you have tested the application with. This is because compatilibity behavior will be enabled/disabled for your application based on this value.
It clearly is explained here: http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
minSdkVersion:
An integer designating the minimum API Level required for the
application to run. The Android system will prevent the user from
installing the application if the system's API Level is lower than the
value specified in this attribute. You should always declare this
attribute.
And for 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).
What is that you don't understand here?
This is how you would set it:
<uses-sdk android:minSdkVersion="10"
android:targetSdkVersion="15"/>
You can read about the changes here, for API Level 14: http://developer.android.com/sdk/api_diff/14/changes.html
and here for API Level 4: http://developer.android.com/sdk/api_diff/4/changes.html
Build using the target, and then you can check and gracefully downgrade if the user is below the target. For example, if you are creating a location aware app, you might want to use PASSIVE_PROVIDER which is available starting with version 8. You could set the min version lower than 8 and check the android version. From there you could decide to use or not use PASSIVE_PROVIDER based on the version.
google suggests that you always use the latest version of the targetSdk , and also gives the lint tool to check for you that your classes and methods aren't too new for the minSdkVersion .
in case of a warning , you will need to think of how to handle it.
do note that as people has mentioned here , setting the targetSdk also means that it will change some aspects of the app .
one aspect is how the app treats the menu button : if you set the targetSdk to 11 or above , it means that you can't assume that there is a menu button , so you will have to deal with the action bar and put the options there in some way (or any other way, depending on your app design) .
if you set it to 10 or below , android will add this button (shown as 3 dots) on the screen for devices that don't have the menu button , like the htc one x or the galaxy nexus . do note that for some devices it looks ugly (takes a whole row for the htc one x , for example) .
so , in short , i would suggest setting the minSdk to the minimum that you can , in order to support as many people as possible , and the targetSdk to the maximum that you can , in order to enjoy all of the benefits that it can give you .
my app has minSdkVersion = 8, targetSdkVersion = 15 and SDK build version = 8. In general it works well, including on ICS but I would like to provide few more features to ICS users, for example resizeable widgets. This requires increasing also the SDK build version to 15.
I am concerned about the API static safety. For example if I will use unintentionally an API features that is not available on old phones.
What are good practices to handle SDK build version > minSdkVersion? How can I verify before shipping a new version that it does not break on old phones? What are good practices to address it?
I don't know if this is considered "good practise", but I just open the file project.properties and change the property target=android-11 to whatever API level I want to check. Once the file is saved, Eclipse will starting flagging errors where the API calls above the set version are. I just scan through them, check that they're encompassed by API-level checks, and then change the property back.
I tried Glitch's answer (thanks!), it kind of works but not as I expected. My widget info files have API 15 attributes such as
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:resizeMode="horizontal|vertical"
When I change the SDK build version from 15 to 8, these lines are flagged at error (which is fine) which fail the generation of the R class. This in turn flags every reference to R as an error (hundrads). Now, if I have something like
someApi15SpecificMethod(R.xyz)
Since the argument is undefined, it cannot tell safely if someApi15SpecificMethod(...) exists in API 8.
Since Glitch's answer is the best so far I am flagging it at the answer but please keep posting ideas here.
I have been developing an android app. I had chosen 2.2 as the version. I have not used any advanced features that are specific to 2.2 or above. I want my app to work with 1.6 and above. What should I do?
Thanks.
You should read this http://developer.android.com/guide/publishing/versioning.html
Complement preview answers.
android make upward compatible your code automatically as much as possible (not always).
But lowering the api level of an app. Can be a task from simple to nightmare to execute, all depends if your code use a lot of specific 2.2 ...
That's means changing API level or android.jar in your project may be far to be enough.
good luck
Open the AndroidManifest.xml file and change to :
<uses-sdk android:minSdkVersion="4"/>
At first you should set android:minSdkVersion="4" in the Android Manifest file.
Next step is to do some testing on an android vm with version 1.6.
Even better would be to test on a real device, but the compiler should give you enough hints what to change in your program.