55

Starting from API level 33 the getPackageInfo(String, int) method of PackageManager class is deprecated. Documentation suggests to use getPackageInfo(String, PackageInfoFlags) instead. But that function is only available from API level 33.

My current code:

val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)

Is this how it should be now?

val pInfo = context.getPackageInfo()

@Suppress("DEPRECATION")
fun Context.getPackageInfo(): PackageInfo {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
    } else {
        packageManager.getPackageInfo(packageName, 0)
    }
}
Marat
  • 6,142
  • 6
  • 39
  • 67
  • You may need to catch NameNotFoundException exception - if packageName turns into a param. – Akn Dec 29 '22 at 22:29

2 Answers2

49

If you are using Kotlin, you can add extension function to your project:

fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): PackageInfo =
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags.toLong()))
    } else {
        @Suppress("DEPRECATION") getPackageInfo(packageName, flags)
    }

and after just call packageManager.getPackageInfoCompat(packageName) or add another flag, if you need.

mtrakal
  • 6,121
  • 2
  • 25
  • 35
  • 2
    Do I have to check Android version here? Wouldn't it just work for older Android versions if I use the new API? – Ali Kazi Jan 04 '23 at 23:50
  • @Ali Kazi no, since older Android versions don't have the new API, it was introduced in API-level 33 (aka Android 13 Tiramisu), usage of the new API will crash on older Android versions with a NoSuchMethodError. Also, the Android linter should mark that with an error or at least a warning in your code immediately. – arne.jans Jun 19 '23 at 08:52
  • You could use the old API for now, but it is risky, since we do not know when Google will delete the old API in favor of the new API, since a deprecation is a marker that tells us Google wants to delete this code at some time in a future android version. – arne.jans Jun 19 '23 at 08:56
  • Depending on what you set your targetSdkVersion to in your build.gradle, it is possible that Android selects certain backward-compatibility mechanisms that prevent a crash, but Google Playstore policy will get updated in the future so that you can't release or update an app with a legacy targetSdkVersion (at the moment, the minimum value for targetSdkVersion is 31, if you want to release for Play Store). – arne.jans Jun 19 '23 at 09:00
21

Is this how it should be now?

Yes, though I've gotten out of the practice of using TIRAMISU in favor of the actual underlying Int.

Ideally, Google would add stuff to PackageManagerCompat for these changes, and perhaps they will now that Android 13 is starting to ship to users.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 14
    I filed a feature request for a new `PackageManagerCompat` function in `androidx.core` (https://issuetracker.google.com/issues/246845196). – stkent Sep 15 '22 at 13:23
  • Isn't it safe to use the `TIRAMISU`-constant in older android-versions that don't know about it, ie doesn't the compiler inline the constant with its Int-value? – arne.jans Jun 19 '23 at 09:04
  • @arne.jans: Yes -- the OP's concern was about needing to call both flavors of `getPackageInfo()`. – CommonsWare Jun 19 '23 at 10:31