No virtual method getLongVersionCode()J when getting version code - android

According google suggestion i am using getLongVersionCode to get version code like this:
private long getCurrentCode() {
try {
return context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).getLongVersionCode();
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
but when i run my app, my app force closed and i got this error:
Process: com.xxxxx.debug, PID: 25754
java.lang.NoSuchMethodError: No virtual method getLongVersionCode()J in class Landroid/content/pm/PackageInfo; or its super classes (declaration of 'android.content.pm.PackageInfo' appears in /system/framework/framework.jar)
at com.xxxxx.common.ApplicationUpdateTask.getCurrentCode(ApplicationUpdateTask.java:329)
at com.xxxxx.common.ApplicationUpdateTask.<init>(ApplicationUpdateTask.java:84)
So i decided to use:
String versionName = BuildConfig.VERSION_NAME;
but now this commend return -1 !!!!!
This is my gradle config:
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 15
targetSdkVersion 28
versionCode 66
versionName '2.0.66'
applicationId 'com.xxxxxx.yyyyy'
multiDexEnabled true
}

I recommend you to use PackageInfoCompat:
PackageInfoCompat.getLongVersionCode();
It automatically checks the sdk version greater than 28 and returns appropriately versionCode or LongVersionCode. It is included in androidx.

The method long getLongVersionCode() was added to Android in version 28; see javadoc
It is clearly present in the APIs you are compiling against, otherwise you would get a compilation error.
But the exception says that it is not present at runtime, so you must have been running on an older platform.
I don't know what you mean when you say that you used this:
String versionName = BuildConfig.VERSION_NAME;
The version name and code are different things. Maybe you used BuildConfig.VERSION_CODE?
And I don't know what you mean by this:
but now this commend return -1 !!!!!
My guess is that there is something wrong with way you are using the version name or code attributes. But that's just a guess. You haven't shown us the code.
The other thing to note is that prior to API version 28, you could use the PackageInfo.versionCode attribute (javadoc). This was deprecated in API version 28. So it should be possible to use reflection to call the getLongVersionCode() method if available, and fall back to using reflection to access the versionCode attribute. (Or test the value of Build.VERSION.SDK_INT at runtime to find out what API version the platform supports.)
Or you could just set the minimum supported Android version for your app to 28.

Just a note for those looking here. Although this says that it was added in 28, I can say for sure it does not work in Android 8.1. Same runtime error. Changing my code to check for Android.os.Build.VERSION_SDK_INT >= Build.VERSION_CODES.P before trying to use getLongVersionCode() avoided the error.

Related

"Unsupported value: Tiramisu" while I try to set up the Android 13 SDK

I followed this page: https://developer.android.com/about/versions/13/setup-sdk
to set up Android 13 SDK.
In my build.gradle:
android {
compileSdkVersion("Tiramisu")
defaultConfig {
targetSdkVersion("Tiramisu")
}
}
Then I got the error:
> Unsupported value: Tiramisu. Format must be one of:
- android-31
- android-31-ext2
- android-T
- vendorName:addonName:31
I tried to use "33" instead of "Tiramisu", but it's not working.
I'm using the latest Android Studio Preview as the instruction.
Is there anyone trying to use Android 13 SDK?
This answer is no longer valid because you can use API version 33 now for Tiramisu as it's officially released
Credit to #NickolaySavchenko - Posting this answer since I've been waiting for him for a day.
Finally, after taking advice from #NickolaySavchenko - I have a final working code like this.
compileSdkVersion "android-Tiramisu"
targetSdkVersion "Tiramisu"
Yes, you see it correctly, the targetSdkVersion is Tiramisu, not android-Tiramisu so that it can run in an emulator API Tiramisu device.
I tested and can confirm that minSdkVersion doesn't need to change to android-Tiramisu or Tiramisu. I'm still keeping it as 19 and it's working great.
As #NickolaySavchenko said
compileSdkPreview "android-Tiramisu"
targetSdkPreview "android-Tiramisu"
working fine
and to run it on android 13 you also need to change your minSdk to "android-Tiramisu"

Android Studio: false Lint warning forcing usage of "Compat" classes when high min SDK (25)

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.

Android Q emulator - Build.VERSION.SDK_INT returns 28

Build.VERSION.SDK_INT
returns 28 instead of 29 when running on Android Q emulator. Is there anything I am missing? I am trying to add logic specifically for Android Q but I do not know how to determine this version correctly.
app.gradle file contains
targetSdkVersion = 'Q'
compileSdkVersion = 'android-Q'
Before the API is finalized and officially becomes API 29 (where you'd use compileSdkVersion 29, etc), you must use BuildCompat.isAtLeastQ():
Checks if the device is running on a pre-release version of Android Q or newer.
Note: This method will return false on devices running release versions of Android. When Android Q is finalized for release, this method will be deprecated and all calls should be replaced with Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q.
Note that Ian's solution requires AndroidX and is only available from Java/Kotlin code.
If your project is not ready for AndroidX just yet, or you need the value in a resource or the manifest, you can use bool resources:
Create res/values/bools.xml and put <bool name="isQ">false</bool> in there
Create res/values-v29/bools.xml and put <bool name="isQ">true</bool> in there
At this point, if you refer to the isQ resource, you will get true on Android Q and higher devices, false otherwise.

Can i get minSdkVersion from ApplicationInfo object below API level 24(of all installed apps)? if not, is there any alternative way?

I know that I can get the minSdkVersion of an app from ApplicationInfo object on API 24+. But is it possible on earlier APIs(as described in documentation). If there is no way, can someone tell me any alternative?
Getting minSdkVersion of app before 24 is not possible as their is no api is been exposed for the same.
But you can use this to get the same.
You just need to declare it in your gradle like this
defaultConfig {
minSdkVersion 16
buildConfigField "int", "MIN_SDK_VERSION", "$minSdkVersion.apiLevel"
}
Then whenever you want to use the same, you can access it as follow
BuildConfig.MIN_SDK_VERSION

Is there a max value for versioncode?

We always have to increment versionCode by some arbitary number to publish it to google play.
Is there limit to that value and what will happen if it is reached?
defaultConfig {
applicationId "my.app"
minSdkVersion 15
targetSdkVersion 22
versionCode 65
versionName "1.05"
setProperty("archivesBaseName", "myapp-$versionCode")
}
Update 08/11/2016 (UTC):
The docs has been updated. Not the old MAX_INT value nor the 2000000000.
Warning: The greatest value Google Play allows for versionCode is 2100000000.
Cross-post for visibility here.
It seems there was a recent change in Google, making the maximum versionCode up to 2000000000 only.
Reference post: Google Play Developer Console error: The version code of your APK is high and you risk not being able to update your APK
PS: For those who are planning to provide reference to the official documentation where the mentioned max value is 2147483647, please read the answer first in the post I referenced. It mentions that as of current date (08/10/2016), its still not updated.
According to android documentation and the gradle DSL documentation:
android:versionCode — An integer value that represents the version of the application code, relative to other versions.
Checking the java doc, by default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of (2^31)-1.
Then the maximum value is 2^31-1.
Starting at Android Pie (9), the version code will be a long (source). The max value of a long is 9,223,372,036,854,775,807 so you shouldn't run into any issues regarding length here.
Do note that it's still an int in older android versions, so long is only relevant to you when your minSdkVersion is 28 or higher.
The other responses are technically true but you should note that Google Play Store only accepts version codes up to 2100000000.

Categories

Resources