Having issues with appcompat-v7 and compileSdkVersion, the app build target is API 10 so I set compileSdkVersion 10 to compile the code safely, as expected it works well with support-v4: the app compiles and runs on API 10 devices.
Then I want to add appcompat-v7 to dependencies (or replace v4 with it) and perform clean re-build of the app without any changes at the code or resources, build fails at the R generation stage unless the compileSdkVersion is set to a higher value.
I understand it as the v7 library is using some values unavailable at API 10. It raises the question of how someone can continue to write safe code and use v7 without need to manually check API level of each variable and method. Is there a way to keep using v7 (that is claimed to be "designed to be used with Android 2.1 (API level 7)") and compileSdkVersion 10 ?
Apparently at the newest Intellij version Lint produces errors if the methods form the API above minSdkVersion is used (can be enabled/disabled at Preferences-Inspections, expand Android Lint at the list, look for Calling new methods on older versions or use "NewApi" annotation to suppress the error if needed).
That'll have to do until some kind of dynamic resources compilation is introduced. I'm going to leave the question here for a future reference.
Related
I am trying to understand how Android Studio determines if a code is available in a certain API. When using MediaStore.setRequireOriginal, Android Studio warns me that "this call requires API level 29". Does Android Studio check that this code is available in previous Android version sources?
photoContentUri = MediaStore.setRequireOriginal(photoContentUri)
I am trying to understand how it knows this.
The linter just knows all the APIs in all the versions. You don't need to download all the previous Android version sources (I was wondering how Android Studio's Linter knew about older versions when I only had API level 29 and 30 sources downloaded on my machine).
As you can see, lint now has a database of the full Android API such that it knows precisely which version each API call was introduced in.
Lint API Check page
The Short Answer:
It's set by the developer, And Android Studio just compares your minSdkVersion set in build.gradle file with the required api level.
The Longer Answer:
When you get this warning on a method, just CTRL+click on it to go to the source class, and there you will find it annotated #RequiresApi or/and #TargetApi, for example :
class MediaStore{
#RequiresApi(api = 29)
#TargetApi(29)
void setRequiredOriginal(...){}
}
Your build.gradle file:
defaultConfig {
minSdkVersion 23
...
}
Android Studio compares minSdkVersion to #RequiresApi or/and #TargetApi at the time you call the method MediaStore.setRequiredOriginal(...); and warn you if minSdkVersion is less that the recommended api.
Please note that there are differences between #RequiresApi and #TargetApi, sometimes you find them used along with each other but sometimes just one of them.
For more about difference between the two see: https://stackoverflow.com/a/50578783/10005752
There is something in build.gradle of application module like:
defaultConfig {
minSdkVersion 23
targetSdkVersion 30
}
So you can change the "minSdkVersion" to 29, and the warning message disappear ...
And if not:
With android OS version >= 29: your code works normally
With android OS version <29: might be an exception occurs
We're dropping support for Android 2.3 (API level 9) devices because most of our users have a newer Android version on their phones. I've updated the minimum SDK version to api level 14.
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
}
}
However I'm still able to install the app on Android 2.3 devices manually (not by store). Is this expected behavior or am I doing something wrong? I couldn't find the answer somewhere else.
Another strange issue is that Lint doesn't detect the correct api level.
listView.setFastScrollAlwaysVisible(true);
This results in the warning: Call requires api level 11 (current min is 9).
However my current minimum is now 14. So this indicates to me that i did something wrong. I tried cleaning and rebuilding the project, restarting Android Studio. It all didn't work.
Can anyone help me out?
Edit
Based on Sufians comment I started fiddling around with my gradle files and I came to the following solution. However some questions still remain.
My project structure looks like this:
android.gradle (top-level build file which contains SDK versions)
main module (contains base code for other modules)
build.gradle (apply from: '../android.gradle')
sub module A (module specific changes)
build.gradle (has dependency on main module)
sub module B (module specific changes)
build.gradle (has dependency on main module)
I have a top-level build file android.gradle which contains the SDK versions. My modules then include the build file by apply from: '../android.gradle'. If I put the minSdkVersion directly in de main module the warnings disappear. Is that the way it should be? or do I need to set an minSdkVersion for every submodule? Or is there another way so that the SDK versions can stay within the android.gradle file?
Ok... I finally realized that there is nothing wrong in my project structure. The only thing I needed to do was press the little 'Sync Project with Gradle Files' button. After that all errors disappear.
Also I concluded that it's possible to install unsupported apps manually.
However the Google Play Store should prevent users from installing or updating the app.
i have personally never developed anything for android but when installing apps the device has never complained when installing an .apk that wasn't supported by the OS version.
even when the store said it wasn't supported i'm always able to install it as a .apk so i think it can't really be blocked.
Yes, you can install the app manually on your device as long the minimum API level specified in your manifest is less than your device's API level.
When you upload your app to the store, the store will not show your app to users with devices having Android version less than the min API level specified (API level 9 in your case).
As for the Lint warnings, make sure that the minimum/maximum SDK versions in your manifest file match those specified in the build.gradle file.
and you can also make sure that new APIs are not executed on older API levels by checking the OS version in the code.
http://developer.android.com/reference/android/os/Build.VERSION.html
If I put the minSdkVersion directly in de main module the warnings
disappear. Is that the way it should be?
Your main module's minimum and target SDKs (i.e inside the build.gradle of the module) will be that of your application.
The project's build.gradle should not contain any of this information.
or do I need to set an
minSdkVersion for every submodule? Or is there another way so that the
SDK versions can stay within the android.gradle file?
Each module defines its own minimum SDK. If you're using a third party module/library, you better not change it, unless you know what you're doing.
I'm targeting Android 19 (because that's what my phone is running). I want to add a notification with buttons; it seems the right approach is to use appcompat-v7.app.NotificationCompat.
However, when I add appcompat-v7 from the Android Support repository revision 22.2 (via a build.gradle dependency), it includes a file app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.0/res/values-v21/values-v21.xml that doesn't compile because it assumes the target is 21+.
I tried deleting that file, but it gets regenerated.
There doesn't seem to be a way to exclude a file from the build.
So, I need to get an older version of the support library or repository, that doesn't include 21 stuff.
I guess I could import all the sources directly (and leave out the v21 stuff), rather than thru the dependency? I'm not clear where to start with that.
I can use the SDK manager to get older versions of the SDK, but it only offers the latest version of the support library.
to directly answer your question it's all that one line on gradle:
compile 'com.android.support:appcompat-v7:22.2.0'
That last part is the version you're getting. 22.2.0 on the example above.
and on this link you can check the revisions numbers:
https://developer.android.com/tools/support-library/index.html#revisions
But you have a fundamentally wrong approach to your issue. You don't have to target the API for the device you have with you. You can easily and safely target the latest API, use the latest AppCompat features and bug fixes.
Lint will give you a warning every time you try to use a feature that is not from your minimumApi, regardless of the targetAPI
In your gradle build file change the dependency to be the 19 version (the version of the library should match the sdk you are compiling with):
dependencies {
compile 'com.android.support:appcompat-v7:19.1.+'
...
}
Edit: If v19 of the support lib doesn't have NotificationCompat, then you can't use that unless you compile against a later SDK. You can't include a support library with a higher version than your compiled SDK - that's the issue you are running into.
In this case change:
android {
compileSdkVersion 22
...
}
and leave the dependency set to the 22 version of the appcompat support lib
I have set the min sdk version in build.gradle as minSdkVersion 8 (I set it low so it was easy to find an API that wasn't added yet). but when I run Analyze->Inspect Code... it doesn't show the call to the above-8 API in the errors. How do I get this to work?
I needed to sync the gradle changes. Then Lint sees the issues.
I am trying to use RecyclerView & CardView in existing Android version. They said it is in support library. So, I should be able to use those with put "compileSdkVersion" to "Android-L". Right ?
I am trying to use those widgets without Android L Preview device or emulator.I have checked other questions on this matter. But, seems they all are trying Android-L with Android-L version.
Here is my dependencies.
compile 'com.android.support:support-v4:13.0.+'
compile 'com.android.support:recyclerview-v7:+'
Here is my target config
minSdkVersion 15
targetSdkVersion 20
Thanks in advance for any idea.
I just found the solution.
The reason why I can't build the App with RecyclerView & CardView while the targetSdkVersion and minSdkVersion is not "Android-L" is because internally Google designed to treat the preview version of OS differently comparing with original releases.
When I compile the App which contains the components from Android-L, the build tools locked minSdkVersion and targetSdkVersion to same level. The new supports libraries (RecyclerView, CardView, Palette, etc) are also locked into the L API level.
This behaviour is only happening on this Android-L preview release.
The fix for it is to put the following in AndroidManifest.xml.I didn't need to change anything on my gradle script.
<uses-sdk
tools:node="replace" />
Since version 0.11 of Android Gradle Plugin, it turned on a new Manifest Merger by default. It allows us to do some niffy stuffs. This specific configuration tells the manifest processor to replace any attributes from uses-sdk nodes in lower-priority manifest (such as library manifest in this case) with this attributes.
Since Gradle also inserts minSdkVersion and targetSdkVersion from your build.gradle into this uses-sdk node, that's all we really need to add.
Check here for more information related to this issue.
Check here for the info related to Manifest Merger.
The best solution is RecyclerViewLib. The support library has been pulled into a repo and published on maven central. It'll be safe even after L is released as all L dependent code has been removed. The author explains it here in his blog post.
To use it in your project just add the following line in your build.gradle dependencies:
compile 'com.twotoasters.RecyclerViewLib:library:1.0.+#aar'
Good luck!
No you must set targetSdkVersion above 7. You can use android support library v7 with project that support android above 7 api level.
And one more. Android L has api level 'android-L', not 20. Under the hood it has api level 21 (20 is 4.4W, KitKat for wearables).