Xamarin中Android 13(SDK33)下PackageManager.GetPackageInfo替代方案咨询
Xamarin Android 9-13 适配PackageManager.GetPackageInfo兼容方案
问题背景
Android 13(SDK 33)中PackageManager.GetPackageInfo(String, int)已被废弃,直接调用会遇到两个问题:
- 目标SDK设为33时,调用
packageinfo = PackageManager.GetPackageInfo(PackageName, 0);编译失败 - 调用
packageinfo = PackageManager.GetPackageInfo(PackageName, PackageManager.PackageInfoFlags.Of(0));会在Android 13以下版本崩溃
需要适配Android 9到13全版本,以下提供两种可行的兼容方案:
方案1:运行时版本判断的扩展方法(推荐)
和你提供的Kotlin兼容逻辑一致,在C#中可以通过扩展方法实现运行时版本分支判断,自动适配新旧API:
using Android.Content; using Android.OS; using Android.Content.PM; public static class PackageManagerExtensions { public static PackageInfo GetPackageInfoCompat(this PackageManager pm, string packageName, int flags = 0) { if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu) { return pm.GetPackageInfo(packageName, PackageInfoFlags.Of((long)flags)); } else { #pragma warning disable CS0618 // 抑制废弃API警告 return pm.GetPackageInfo(packageName, flags); #pragma warning restore CS0618 } } }
使用方式:
var packageInfo = PackageManager.GetPackageInfoCompat(PackageName, 0);
方案2:条件编译实现分支
如果需要在编译阶段就区分API版本,可以利用Xamarin的条件编译符号:
PackageInfo packageInfo; #if __ANDROID_33__ packageInfo = PackageManager.GetPackageInfo(PackageName, PackageInfoFlags.Of(0)); #else #pragma warning disable CS0618 packageInfo = PackageManager.GetPackageInfo(PackageName, 0); #pragma warning restore CS0618 #endif
注意:条件编译是基于编译时的目标SDK版本,若需同时支持安装在低版本设备上,优先推荐方案1的运行时判断,避免编译成单一版本后在其他系统版本上出问题。
其他注意事项
- 调用
GetPackageInfo需要对应权限,比如查询其他应用信息时,Android 11+需QUERY_ALL_PACKAGES权限,或针对特定应用的PACKAGE_USAGE_STATS权限,需根据需求配置 - 可根据实际需求调整
flags参数,新旧API的标志位对应关系可参考Android官方文档
内容的提问来源于stack exchange,提问作者J M
相关产品推荐
相关产品推荐

