Android Lint - NewApi check still fails despite suppression with #TargetApi - android

Following an unsuccessful Lint run, I attempted to fix an error by adding the #TargetApi(Build.VERSION_CODES.HONEYCOMB) attribute, but the next time Lint is run, the following error still shows for the getScaleX() function:
Can anyone shed some light on this?

The call to getScaleX() requires API level 11 (Honeycomb), as mentioned in the message window. The message also indicates that the minimum API level is 9 (as per the minSdkVersion setting).
The Lint tool is warning you that you are using a method supported only in newer SDK versions (11+), but have set to allow the application to run on devices that don't support this method (SDK versions 9 and 10).
See a more detailed description of what the NewApi Lint check does here: (search for NewApi) http://tools.android.com/tips/lint-checks
Suppress such warnings with caution, I'd suggest protecting the code with something like this:
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
...getScaleX()...
}

Related

Android Studio minSdkVersion check for Java 1.8 (API level 24) specific features

My project uses Array#sort that requires API level 24 (Android 7.0)
_tmp.sort((left, right) -> { ... };
But I have also minSdkVersion 21 (Android 5.0)
When I run that code on Android 6.0 Emulator, the following exception is thrown:
... Caused by: java.lang.NoSuchMethodError: No interface method sort(Ljava/util/Comparator;)V in class Ljava/util/List; or its super classes (declaration of 'java.util.List' appears in /system/framework/core-libart.jar)
I have found that other users asked about this exception: java.lang.NoSuchMethodError: No interface method sort(Ljava/util/Comparator;) exception in sorting arraylist android
Any good way to Android Studio warns that .sort is not workable on OSes earlier than Android 7.0? like APIs having #RequiresApi?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { ... }
Android studios on my computers warns my about this out of the box, not to sure why yours doesn't. Maybe you made changes to your lint warning configuration? If not, you should still be able to enable that there.
Sort method is annotated as #since 1.8
You can change Android Studio errors and warnings levels in Settings->Editor->Inspections
Try change Java->Java language level migration aids->usages of API which isn't available at her configure (description of it: "This inspection finds all usages of methods that have #since tag in their documentation.")

API target and min confusion

I am confused about the target build and sdk usage
Lets say I have this code
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
//do xyz
}
Let say that I built against API 19 (kitkat) and my target api in manifest is 19 and my minimum supported api is 9
Now if a device with API 9 runs the above code, will it crash? I expect the answer is yes becasuse it will not understand what Build.VERSION_CODES.KITKAT means. However, what's the point of the check above then in first place?
Please help clarify this
Thank you
It won't crash. Simply the code within the if won't be executed. Build.VERSION_CODES.KITKAT is a constant field, and as you can read here, the constant fields are replaced with the numbers themselves by the compiler.
lesser versions of android will use the support library, if the check for kit-kat fails, it will revert to the closest possibkle form that version supports.... via the support library...
you cannot run you app on anything less than the minimum version, but it will find a way to run with less than the target version as long as its aboe the minimum
No, it won't crash, because its Build.VERSION.SDK_INT value is 9. It simply will not enter inside your if clause. Only devices that have API version 19 or above will run your code inside the if. Build.VERSION_CODES.KITKAT is equal to 19.
The code you posted won't crash because the class Build is created and compiled for every build of your app (as the R file) depending of the target API you set in the manifest
As you setup your target API to 19, the Build class will contain the field Build.VERSION_CODES.KITKAT because it exists starting from API level 19.

android lint still give "Call requires API ..." error after I put check there

I have the following code:
if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){
enter_pos.callOnClick();
}
But I still get error from Lint:
Call requires API level 15 (current min is 12): android.widget.Button#callOnClick
Why Lint is still giving error even after I put a check for the API version? I am using
Android Developer Tools
Build: v22.0.5-757759
Under Windows 8. Thanks in advance for any suggestions!
You should put #SuppressLint("NewApi") above the method you are using this. Lint cannot decide if you do your check right by looking at your code
In your eclipse Window -> preferences -> Android -> Lint error checking uncheck the two check boxes and apply changes and then clean the project.

what is the use of #SuppressLint("InlinedApi")

I encountered #SuppressLint("InlinedApi") in some code i was going through and could not find out any description of it online. I understand #SuppressLint("NewApi") is used to hide warnings when we write code that is higher than the minsdk mentioned in the manifest. But i am not able to figure out when "InlinedApi" should be used. Any ideas?
By executing lint --list (the lint tool is located in your sdk/tools directory) you can see a list of the valid issue id's. You can find the explanation of InlinedApi there :
"InlinedApi": Finds inlined fields that may or may not work on older
platforms
Here's an example from a Google codelab:
#SuppressLint("InlinedApi")
private void hideSystemUi() {
mPlayerView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
If you comment out the #SuppressLint("InlinedApi"), you get this lint warning:
Field requires API level 19 (current min is 16): android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY
So you're accessing a field that may not exist in the API of some of the devices that you've said you want to be able to run the device on. In that case, why is it just a lint warning instead of a fatal compile error?
The fuller description for the warning is nice and informative. You can see it in Android Studio if you press the "More" key combo (e.g. Cmd+F1) when the lint message popup is open. You can also get it via lint on the command line, similar to what #stan0 said but in more detail:
lint --show InlinedApi
Here's the detailed explanation:
InlinedApi
----------
Summary: Using inlined constants on older versions
Priority: 6 / 10
Severity: Warning
Category: Correctness
This check scans through all the Android API field references in the
application and flags certain constants, such as static final integers
and Strings, which were introduced in later versions. These will
actually be copied into the class files rather than being referenced,
which means that the value is available even when running on older
devices. In some cases that's fine, and in other cases it can result
in a runtime crash or incorrect behavior. It depends on the context,
so consider the code carefully and decide whether it's safe and can be
suppressed or whether the code needs to be guarded. [emphasis added]
If you really want to use this API and don't need to support older
devices just set the minSdkVersion in your build.gradle or
AndroidManifest.xml files. If your code is deliberately accessing
newer APIs, and you have ensured (e.g. with conditional execution)
that this code will only ever be called on a supported platform, then
you can annotate your class or method with the #TargetApi annotation
specifying the local minimum SDK to apply, such as #TargetApi(11),
such that this check considers 11 rather than your manifest file's
minimum SDK as the required API level.
(source)
Hopefully with that explanation, it's clear why this is not a fatal error (because the value of the constant gets copied into the class file instead of a reference), why it's still potentially dangerous, and when to suppress the warning. In the codelab example above, the author apparently decided that adding a flag that wouldn't be recognized on older devices was safe. Maybe he had information that unrecognized flags would be silently ignored, though I don't see that in the documentation.
I found this..
#SuppressLint("InlinedApi")
Indicates that Lint should ignore the specified warnings for the annotated element.
Exp:
SuppressLint
implements from Annotation Class.
android.annotation.SuppressLint like this..
Built-In Annotations
Java defines a set of annotations that are built into the language
Annotations applied to java code:
#Override - Checks that the method is an override. Causes a compile error if the method is not found in one of the parent classes or implemented interfaces.
#Deprecated - Marks the method as obsolete. Causes a compile warning if the method is used.
#SuppressWarnings - Instructs the compiler to suppress the compile time warnings specified in the annotation parameters
http://developer.android.com/reference/java/lang/annotation/Annotation.html
http://developer.android.com/reference/android/annotation/SuppressLint.html

ActionBarSherlock gives tons of "Call requires API level 11 (current min is 7)" errors

I downloaded ActionBarSherlock 4.0.3, unzipped it and created a new project from the library folder. The src folder was, according to Eclipse, full of errors, so I followed various instructions online, like adding android-support-v4.jar, setting target API to 15 and compiler compliance level to 1.6. Still, the project has 194 errors, all of which are "Call requires API level 11 (current min is 7)". So when I look at one of the errors, I see this:
#Override
public void invalidateOptionsMenu() {
getSherlock().dispatchInvalidateOptionsMenu();
}
public void supportInvalidateOptionsMenu() {
invalidateOptionsMenu();
//the previous line has this error in Eclipse:
//Call requires API level 11 (current min is 7): android.app.Activity#invalidateOptionsMenu
}
This looks strange to me, because invalidateOptionsMenu() is overridden with the previous function, but Eclipse still complains about the function requiring a newer API level. When I look at the other errors, I find that this is the case with many other errors too.
I have much more experience with Python than Java, so I don't understand anything of what causes this to happen. Help would be appreciated, and if you do help, could you also explain what causes this and what you did to solve it? I wouldn't want to ask someone every time I have a problem, I want to learn too.
Happened to me after running Lint checks. Try right click on sherlock action bar project -> Android tools -> Clear Lint Markers.
Use ActivityCompat, provided in the support jar.
Since you're using min API level 7, and invalidateOptionsMenu() did not exist until API level 11, you can't override it without errors since if the device runs API level 7, the function isn't even available in the base class and a non existing function cannot be overridden.
All this answers are wrong Except dbrown0708 Answer but I will declare it more
You Can use invalidateOptionMenu in lower API by using ActivityCompat As it provided in support library v4
Syntax is invalidateOptionsMenu(Activity activity);
code is
ActivityCompat.invalidateOptionsMenu(this);
In API Since level 11
invalidateOptionsMenu();
Try and use the import android.support.v4.app.Fragment; as your library

Categories

Resources