I am writing an Android library. The vast majority of the interface in the lbirary supports Android API level 10 or above. Some functionality, though, requires a higher API level. For instance, part of the library requires API 18 for Bluetooth Low Energy.
For the sake of concreteness, let's say that the library produces three classes ClassA
, ClassB
and ClassC
. ClassA
uses functionality available in API 10, ClassB
uses functionality available in API 14 and ClassC
uses functionality available in API 18.
I want to be able to trigger a lint issue (warning/error) whenever someone uses a class from my library without having the required API level in their project (unless they suppress the warning with the appropriate annotation), similar to the already built-in NewApi issue used by lint.
After searching, I have found the following possible solutions:
1) This solution isn't along the lines of lint: Split the library into three .jar files, say lib_10.jar
that includes all classes using functionality available in API 10 (ClassA in the example), lib_14.jar
that includes all the classes using functionality available in API 14 (ClassB in the example) and lib_18.jar
that includes all classes using functionality available in API 18 (ClassC in the example). This solution allows portability but would complicate the later maintainability of the codebase and would potentially require some code duplication as well.
2) Create my own annotation (say, @RequireAndroidApi(API_LEVEL)
indicating the minimum API level required by the annotated class/method/etc...) and use the lint-api.jar
(http://tools.android.com/tips/lint-custom-rules
) to create a custom lint rules that check the usage of any annotated classes/methods/etc... with a lower API than required. Something that would later look like this:
@RequireAndroidApi(10)
Class ClassA {
}
@RequireAndroidApi(14)
Class ClassB {
}
@RequireAndroidApi(18)
Class ClassC {
}
The problem is that I couldn't find good documentation for the lint API and it seems that this is reinventing the wheel for a functionality that lint already supports (lint already checks for the "NewApi" issue).
3) Finally, I succeeded to edit <SDK>/platform-tools/api/api-versions.xml
in order to indicate the API level required by each class as follows:
<api version="1">
...
<class name="package/path/ClassA" since="10">
<extends name="java/lang/Object" />
<method name="<init>()V" />
</class>
<class name="package/path/ClassB" since="14">
<extends name="java/lang/Object" />
<method name="<init>()V" />
</class>
<class name="package/path/ClassC" since="18">
<extends name="java/lang/Object" />
<method name="<init>()V" />
</class>
</api>
Which caused lint to trigger the NewApi issue in the same manner as it would with the Android APIs. I like this type of solution because it doesn't reinvent the wheel and further any errors thrown this way would utilize the suggested solutions programmed in Eclipse or Android Studio to deal with the problem (i.e. "quick fixes" in Eclipse). The problem with this solution is that it requires editing api-versions.xml
that ships with the Android SDK, which makes this solution not very portable for releasing the library for several reasons including: a) the api-versions.xml
file is not local to a project and changes the behavior of lint for all android projects, including the ones that do not use the library; and b) api-versions.xml
will be overwritten every time the SDK is updated from the Android SDK manager which would overwrite any changes made.
I was wondering if there is a simpler solution to achieve this "minimum API errors/warnings" or if there is a way to write a separate file similar to api-versions.xml
that can be placed in the project directory which can be read by lint whenever lint is ran on the project in question (something similar to lint.xml
).
Thanks for bearing with me during this long description of the problem and I appreciate any help in advance.
Starting November 1, 2022 if your app doesn't target API level 30 or above, new users with newer Android OS versions won't be able to discover or install your app on Google Play. You can request an extension if you need more time to update your app.
android:minSdkVersion — Specifies the minimum API Level on which the application is able to run. The default value is "1". android:targetSdkVersion — Specifies the API Level on which the application is designed to run.
There is no need to create your own annotation, the android support library's @RequiresApi
annotation is what you are looking for. For example:
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public void someMethod() {}
This annotation tells lint to warn if someMethod()
is used in a context that may have a lower API level.
Note that @TargetApi
is different: It's used to assure the linter that the annotated method will only be called with the targeted API, in a situation where it would otherwise warn you not to use that method. So @TargetApi
can be used to silence the lint warning triggered by @RequiresApi
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With