Google Play recently issued a heads up to Android developers to update their apps with three new changes : https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html
I have a question regarding updating the targeted SDK to version 26. When I made this change for one of my apps, the Developer console showed me a warning saying that this new APK would not support an x number of devices, since it does not fall into some SDK version criteria. Since the app did not have too many active installs, I went ahead with it.
Now I need to do this for another app of mine which has quite a good number of active users. Would making this change of targeted SDK version have any impact on user having low end Android OS or older device models?
Could somebody please explain what might be the problems one might face while making such a change, from perspective of existing and new users?
Would love some clarification from anyone who has some info, but particularly from android app developers who have already made these changes.
From a user perspective: no problems, because changing the target SDK does not mean changing the minSDK.
For you as a developer: depending on the gap between current and future target SDK, there may be quite a lot of work to do because the runtime will handle things differently under the hood depending on the target SDK (e.g. permission handling, use of certain libraries, rendering of UI components).
Quoting from documentation for <uses-sdk>
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.
Related
I've got a quote from a developer to build a couple of Android apps. For both the contract states: "App will be compatible with Android OS 4.0.x and 4.1".
Can anyone please tell whether this poses any problems for people wanting to run the apps on newer versions of Android's OS? Not sure if I should be worried or not.
Many thanks
Drew
Mostly, newer Android API fully support older API. That means anything that works on 4.1 should work on 4.3, 4.4, etc
Still, not everything that can run on 4.1 can run on 2.2, for example. Backwards compactibility is a huge problem sometimes
Targeting a minimum of 4.0 won't stop the apps from working on the current versions of android. The only major difference that I can think of is the default color accents being changed in 4.4 (The current highest release). This can be addressed by your developer if your desired styling overrides the defaults anyways, otherwise know that in 4.0 youll see lots of blues, but in 4.4+ youll see a more subtle grey accent.
That isn't to say that this will always be the case though. At any point the OS can take a right turn like they did with the HOLO changes that were introduced between 2.3 and 3.0, which would make your "legacy" app not function as it use to. At this point, you would either have to have the app redone, or accept the flaws in this completely hypothetical future state.
Unless the API is depecrated, they will always work on newer versions. The problem usually is older versions unable to support newer API, not the other way round.
When I created my application, I chose 1.0 for the minimum SDK and 4.3 for the target SDK, so my application works on all phones.
But why would we choose (for example) a minimum SDK of 2.2?
Is it about performance, or something like that?
First of all i'd like to clear,
android:minSdkVersion="integer"
Despite its name, this element is used to specify the API Level, not the version number of the SDK (software development kit) or Android platform. The API Level is always a single integer. You cannot derive the API Level from its associated Android version number (for example, it is not the same as the major version or the sum of the major and minor versions).
find more detail
we choose minimum and maximum version for our app because , some of the feature which are not supported in lower/higher versions of android are used in app . The Android system will prevent the user from installing the application if the system's API Level is lower/higher than the value specified in this attribute.Hence preventing unwanted force close.
Most of the features of higher versions of android will not work in api level 1 .thwn why will you put level 1 as minimum sdk.
Android is a system that is everytime changing, and that implements new features in each new version.
When you develop an app, you will have to deal with :
Compliance for the user
Nice features for your application
For example, animations of clickable elements are not well implemented in Android 2.3. So when you will have to develop an application, you will have to choose :
Compliance with a maximum users including 2.3 compliance
Develop a lot of nice animations, including on clickable elements
It's why sometimes you decide to develop an applications, you may decide to not include some versions of the SDK.
And for having a clear view on how much users you would loose, you may want to go to :
Dashboards
99,9% of phones use SDK 2.2 and later and all cool features that you can use are avaliable on later SDK versions than 1.1. That is the main reason, but you can use earlier version of SDK for minimum but in has no efect because you are covering all devices with 2.2 SDK.
Currently, I tend to target all my app development to API 8, so that I can hit the largest number of devices 'out there', basically from Android 2.2 upwards.
Do any experienced Android developers reading this have a perspective on what features, as a developer am I 'missing out' on, and more importantly, what are my users missing out on? In this day and age, what API is the 'best' one for my apps to target? Or is there no such thing, and each app should be targeted for a given API on its merits?
I'm not looking for pointers such as read the android developer docs (I have, or at least what I consider the salient parts), I'm more interested in the views of experienced developers as to how they decide which API to target.
Thanks.
if you set your target and minSdkVersion to 7 and use support (compatibility) library v4, then your app will support nearly 95% of all android phones, and still you are able to use modern features of newer APIs (by using support library).
I usually target the minimum API required by the apps functionality. If there is a minor feature needing a higher API, I make it optional instead of increasing the minimum for the whole app. In addition to using ActionBarSherlock and the compatibility libraries, I occasionally back port a few things from later APIs to keep the current basis.
While I decide the minimum on a per app basis, most of my apps target 2.1, as they were written almost one and a half years ago. Now days, I have new apps target 2.2, though I plan to change it to 2.3 very soon.
I guess my point is that there is no defined minimum API target. You should choose the one which offers maximum user reach, along with as much major functionality as possible. UI elements like the action bar and ViewPager can be used via libraries, and the ones not available in libraries can sometimes be back ported. However, it is usually not worth it to sacrifice users running a lower API version just for a better UI.
My app is set to run on minSdk = 5, but the vast majority of users are using SDK 8 (FroYo) and higher. I want to be able to use the android:configChanges="uiMode" for my main activity, but I can't do it because that mode wasn't introduced until SDK level 8. So, I was hoping that I could do it at runtime -- check which SDK level is running on the device, and then use reflection to add that parameter.
Is that possible?
EDIT:
The problem is that whenever a user's phone is connected to the dock, my app gets terminated, and then re-created. I'm trying to avoid that by including the android:configChanges="uiMode".
After much poring through the Android Reference, there is very little you can change from the manifest at runtime. This is due to security because through the PackageManager, one can gain very specific information about any application on the device. While it is easy to enable/disable a given Component, in most other circumstances, you can only read manifest information... not write it.
Alternatives
You could potentially make a separate APK with API Level 8 support.
You could manually check for configuration state and run your code when it changes. The object reference for configuration is here.
Edit: (new info)
While you cannot change the configChanges, I found this question that is closely related to yours. It turns out that you might not have to. It implies that you can use Android's backward compatibility mode when supporting new configChanges. In case the link above is broken, here is the URL: https://stackoverflow.com/a/7893148/501932
To put this to use for you, it suggests setting a new targetSdk while maintaining your original minimumSdk. It also requires that you have the updated SDK, itself. Apparently, this was a huge deal for users that utilized that AdMob API.
App Configuration for forward compatibility
The answer I provided is a simple what to do, but not much or the why, this should update the answer as well as act as apology to the SO community for sparring with the poster, which was pointless and added nothing to the conversation.
I think it’s an important point to expand upon this issue since these kind of questions come up a lot and developers in a hurry (aren’t we all) and we have a tendency to cut/copy/paste and worry about the why of it later which mostly works out but occasionally just adds to the problems.
If you understand how the android runtime actually works you can often solve these types of problems by applying a simple pattern of best practices by using the block in your manifest, and making good use of the Build Target when compiling your app, followed by some simple testing at the compile and run time levels.
Manifest
minSdkVersion =
Pretty straight forward it’s the lowest build target you will support on a specific device. If you don’t set this it defaults to 1.
The only caveat here is that if your Build Target is higher than your minSdkVersion than you can potentially call API’s that don’t exist on the device, more on that under Build Target.
This will filter you app from on the various market/play repositories for devices that have lower OS support.
How you make this determination is up to you, if you must have your app run on every device ok, but take a look at Platform Distribution to make an informed decision.
If you are willing to bypass 0.9% of the market then target 2.1 which seems reasonable but that’s a decision for a developer/company to make, if you can bypass 25% of the market then go with 2.3 which has significant advantages but is a bit hard to swallow for most general purpose app’s.
The linked chart is updated from time to time.
targetSdk =
If you don’t apply this value then it defaults to whatever minSdkVersion you set. This means that when you run on a device with higher OS support certain new looks and or behaviors that are implemented will be bypassed in favor of the older way of doing things.
For instance if you apply 10 to the minSdkVersion and then your app runs on a device with gingerbread (11) it will not attempt to use the holo theme, or disable screen compatibility mode. In general this might give your app a “Dated” look and feel.
If on the other hand you set this to something higher, like 11, then the system will use the native look and feel of the OS up to that value you set. Best practices is to set this as high as possible and then to test on the higher level device in the emulator to make sure this is acceptable.
Some of the changes that effect compatibility behavior between OS jumps are documented here Differences between OS's
This will not stop you from running on earlier devices, or effect those earlier devices look or feel (see ActionBarSherlock and the Android Support Library if that’s your goal)
maxSdkVersion =
In general this does just what it says it does, it restricts availability and deployment of your application on devices that have a higher OS level from Google market/play.
On android 2.0- it will also refuse to install the apk, and will even remove your app if a device is updated to a level higher than this setting, 2.0.1+ removed the second part of this behavior but the markets will still filter based on it.
In general there is no reason to usually set this value, so leave it blank.
Build Target
When you set a build target in eclipse (or otherwise) you are telling the complier which API’s, constants, etc. should be VISIBLE to your application.
In general it adds a jar file that has all of these definitions/declarations but of course not the actual classes/methods so that you can compile your application for any target OS you desire.
When your app runs on a device it links to the actual android OS/support jar file(s) (or blows chunks if they are not there)
If you select a build target higher than you are willing to support then bad things can of course happen when you try and call method that does not exist, or even a class that does not exist on the Older OS.
If on the other hand you are willing to carefully manage and test this then you can obtain forward compatibility in the sense that you can use the new API’s on newer devices so long as you don’t attempt to do so on earlier devices.
Best Practices – Short Version
This is what the poster is trying to accomplish and if best practices are followed it works out well, these are in general
minSdkVersion = lowest general API you will support
targetSdkVersion = highest behavioral model you are willing to allow
maxSdkVersion = leave it blank
Build Target = generally as high as is currently supported
The real caveat is that you have to avoid API mismatches between older and newer versions, and make sure your app looks and acts ok on the higher version.
In general methods/classes that are higher than your minimum targeted OS should be used sparingly and tested at both the compile and runtime level since it requires some effort to use them safely.
Here is how I go about it
minSdkVersion = 7 ( I can live with a 0.9% clip again your choice )
targetSdkVersion =15 ( highest as of this writing )
maxSdkVersion = ( blank )
Build Target = 15
When developing I never use an API not available on 7 unless I have a real need to do that, in the posters question he could have used a broadcast received to get similar functionality back to 6/7 (2.0/2.1) but he states he needs API 3 support so he has to support forward compatibility.
One tool you can use, and most don’t just to keep things straight is to set the API level on the developer.android.com website to your minimum SDK level, this gives you a heads up when developing that you will have to support forward compatibility.
It will still show the other API calls but it will gray them out telling you that extra effort will be needed to support them
If you do need to use a newer API you will need to do an if then else so that they are only called on the newer device, this will allow you to support the new functionality without getting a force close on older devices.
So in general if you support higher API levels those calls should be wrapped with something like this (note the .SDK_INT is a since API 4 test)
If ( Build.VERSION.SDK_INT >= API11_SUPPORT ) {
switch(newConfig.uiMode) {
case ...
}
Testing – manual method (CI integration methods are left up to the reader ;-)
Compile with the build target set to the minSdkVersion – this will give you compile errors on any newer API’s that you are using, check them out and if you handled them great, if not now is the time.
For every issue I see at step 1 I add two items to the code (manifests/xml )
// TODO Compatibility xxx
if (DEBUG) Log.i(“MyApp”,” Compatibility xxx”);
I can then use the eclipse TODO pane to check off compatibility issues before ship and test them against the lowest/highest and any significant in between OS versions
Test on minSDKVersion device/emulator, this is a bit tricky if you are not doing comprehensive testing, in general use step 1 above to make sure I exercise those blocks of code
Test on Build Target device/emulator to make sure look and feel work as expected
If you think it’s a bit of work it is, but when you need it you should do it right and make sure your app does not break.
Hopefully this is useful to someone trying to figure out similar situations, below was my second response to the poster, Cheers.
UPDATE:
I still have no idea what the author is asking, but if he is asking if there is a way to detect the configuration changes in regard to uiMode (docking stuff) on 7 and below using the onConfigurationChanged handler then no since that was only introduced in API 8.
There is a broadcast event sent in API 2.0+ systems, but apparently that has some issues and does not seem to be completely reliable
If he is asking if there is a way to support it on devices that are API 8 and above via the onConfigurationChanged handler by setting the flag in manifest for the activity then of course there is
Of course he may be asking about something totally different, it's hard to tell exactly what he is looking to do given his post none the less in the spirit of cooperation:
Select an API from project properties that is >= 8, best practices is to use the highest API available when you create your app for just this reason BUT care must be taken not to call any API's that are not available on the device.
Then in the manifest use (duh)
<activity
android:name=".myActivity"
android:configChanges="uiMode|orientation|keyboardHidden"
This compiles fine (and that is really the only issue and why you need to set a higher api in the eclipse project properties) this will run fine on 7 and below it just wont trigger any events because of course API 7 and below devices won't recognize the uiMode flag (duh)
API 8 and above of course will recognize it and send the proper event so on api 7 the log will be written, on api 8+ it will (if docked etc) of course the calls that are made if it does happen will most likely be 8+ related so you would need a OS check block before calling them.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i("myActivity","uiMode="+newConfig.uiMode);
}
If you compile and run on a 7 API emulator and fire a dock broadcast nothing happens, change to a 8 API emulator and it does
adb shell am broadcast -a android.intent.action.DOCK_EVENT --ei android.intent.extra.DOCK_STATE 2
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