When building android apps for different behavior on different targets we can do:
if (Build.VERSION.SDK_INT < 10) {
Toast.makeText(this.context, "Not Supported", Toast.LENGTH_LONG ).show();
} else {
this.doComplicatedOperation();
}
But in the method doComplicatedOperation() it would be logical to use higher api classes than the current build target (eg. api 5), but lint keeps complaining that ClassIntroducedInApiLevel11 can not be resolved as a type
How could I change the code of doComplicatedOperation() that my project compiles?
#TargetApi(11)
private void doComplicatedOperation() {
ClassIntroducedInApiLevel11 = new ClassIntroducedInApiLevel11();
}
The purpose of minSdkVersion is to exclude platforms where you do not provide backward compatibility support.
In order to provide the proper libraries for your build you need to set a higher targetSdkVersion so the IDE or whatever knows what libraries to include when creating your APK.
It sounds like you don't want to target a higher SDK because some methods or objects may be deprecated or even unsupported. That's when you use support libraries, if necessary, for backward compatibility.
You need to change your SDK target to at least the SDK that the method is in so in. You should always be targeting the highest API there is available (currently 19) so your manifest should look like this
<uses-sdk
android:minSdkVersion="5"
android:targetSdkVersion="19" />
if you are still targeting SDK 5 you are in the dark ages
Related
I am working on a project with minSdkVersion set to 25 (aka Android 7.1).
Since this version is quite high, there are a lot of methods I can use without worrying about backward compatibility.
For example, retrieving a drawable, from a Fragment, should be as simple as:
context?.getDrawable(R.drawable.my_drawable)
In the source code, what it does is:
return getResources().getDrawable(id, getTheme());
As far as I am concerned, such a method was introduced in API 21 (Android 5.0).
However, I get the following warning:
Looking at the source code of ContextCompat.getDrawable(...):
if (Build.VERSION.SDK_INT >= 21) {
return context.getDrawable(id);
} else if (Build.VERSION.SDK_INT >= 16) {
return context.getResources().getDrawable(id);
} else { ... }
Since the min SDK is set to 25, the first if will always be called, which then the same code I have written. So why the warning?
I could suppress it with the #SuppressLint("UseCompatLoadingForDrawables") but it kinds of defeat the purpose... or I could follow it...
Is this normal? Should I really use ContextCompat and its affiliates or is there a setting somewhere to remove such a false warning?
PS: the project is also using Android X.
Ran into the same issue. I would say it is a false positive when you have a minSdk >= 21. Since as you say you will always enter the if branch which calls getDrawable.
So suppressing/ignoring it is the way to go until someone can make the lint rule smart enough to detect that you are on minSdkVersion higher than 21. You can ignore it globally by doing this in your build.gradle:
android {
...
lintOptions {
ignore("UseCompatLoadingForDrawables")
}
}
Interestingly context.getColor(R.color.something) does not give a similar warning even though it has similar code in ContextCompat.getColor.
I'm curious about what is the sense in setting both target and minimal supported API version when starting a new Android Studio project. I mean, if I set that minimal API is, say, 8, then I won't be able to use features from 22 (which could be my target), because it would break compatibility with API 8.
if I set that minimal API is, say, 8, then I won't be able to use
features from 22
You can use API level >= 8 features in application, but you have to check OS version of the device first, see following code, that's how you can maintain compatibility
if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.HONEYCOMB){
//use features of API 3.0
} else if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.HONEYCOMB_MR1){
//use features of API 3.1
} else if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.HONEYCOMB_MR2){
//use features of API 3.2
}else{
// and so on....
}
Other then code, use can use resource folders on the basis of API level, like:
values-v11
values-v12
values-14
....
and
drawable-v11
drawable-v12
drawable-14
....
This is not correct. By setting target API to 8 you can't use any features added after, but specifying minimum API is just a guarantee that you application will work on such devices. You don't guarantee that it provide all features on such devices, nor minimum API level restricts what features it could use when running on later versions of OS.
Look at PE history - all win32 executable files are compatible with MSDOS, but all they say after executing is just "This is not a MSDOS program.". Similar to this, it is your decision what features you provide on which OS you support.
I am working with a large project, which has a minimum API level:16. however, I came across API usages that are above API level 16.
Is there any tool in Android studio or elsewhere, other than testing with a device, to check if the code doesn't violate the minimum required API level or better point it out like an error etc.?
Thank you.
The IDE will use the minimum android SDK, thus you will not get compile errors. If you there are classes in SDK 14 which are moved in sdk 16, yet you are using the imports from SDK 14, it will give a standard compile error.
So no, not that I am aware of.
You can use something like this:
public static boolean supports(final int version) {
return Build.VERSION.SDK_INT >= version;
}
Like this,
if (supports(Build.VERSION_CODES.HONEYCOMB)) {
// do something HONEYCOMB+ compatible here
}
More codes here,
http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
I found that from API 19+ their is a small change in code and it doesn't appear in API 19-.
How can I support both android versions in the same app?
EDIT: The are feature that exists only in android 4.1.2 and in versions below 4.1.2 they doesn't exists.
How can I make an app that support both versions with the exception that in lower version the "new" features won't exist? (its hard for me to explain)
You can wrap the API 19-specific code inside a conditional that queries the device version with the enumerated values present in Build.VERSION_CODES.
for instance :
if ( android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT )
{
// Kitkat (API level 19) code in here...
}
else {
// code for all versions lower than Kitkat in here...
}
BACKGROUND
I am developing an android application that needs to work on API levels from 7 to 16.
THE PROBLEM
Whenever I go to build my project this is the process I have to go through.
Clean project
Run Project
"Errors in project" > Click OK > Run Project Again
Runs fine on any API
I think the problem is due to the fact I am including code (such as the ActionBar) that API < 3.0 can't use but I am checking for it and running something else if thats the case.
THE QUESTION
Does anyone know a way round this because it is very time consuming considering I have to do this every time I want to run it.
I suppose you are using Eclipse for your development. You can annotate the offending methods as follows:
private final int VERSION = android.os.Build.VERSION.SDK_INT;
private File myDir;
// some stuff here
#SuppressLint("NewApi")
private void doSomething() {
if (VERSION < 8) {
// Uses a method available since API 1
myDir = Environment.getExternalStorageDirectory();
else {
// Uses a method available since API 8
myDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
}
// Do more stuff
}
You can add in your manifest:
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="16" />
Then any API between and including 7 and 16 versions will compile because your target is 16.
Then if your device is 7 any API > 7 will fail on your device but you have said you are taking measures against that in your code.