Android 13下JNI中如何调用PackageManager.getPackageInfo(String, PackageInfoFlags)
在JNI中使用PackageInfoFlags获取PackageInfo的正确方式
你的代码出现NameNotFoundException,核心问题大概率是方法签名匹配错误、类对象获取不正确,或者没有正确构造PackageInfoFlags实例。下面是完整的解决步骤和示例代码:
关键问题分析
- 方法签名验证:你写的方法签名格式是对的,但要确保
PackageManager类对象是从实际的PackageManager实例获取的,而非其他类。 - PackageInfoFlags的构造:
PackageInfoFlags没有公共构造方法,必须通过静态方法of(long)创建实例,不能直接实例化。 - 版本兼容:该方法仅在Android 13(SDK 33)及以上可用,低版本设备需保留旧版
getPackageInfo(String, int)的调用逻辑。
完整示例代码
// 假设packageManagerObj是已获取的PackageManager实例 jobject // packageName是目标应用包名 jstring // 获取PackageManager类 jclass packageManagerClass = env->GetObjectClass(packageManagerObj); if (packageManagerClass == nullptr) { return nullptr; } // 获取PackageInfoFlags内部类 jclass packageInfoFlagsClass = env->FindClass("android/content/pm/PackageManager$PackageInfoFlags"); if (packageInfoFlagsClass == nullptr) { env->DeleteLocalRef(packageManagerClass); return nullptr; } // 获取PackageInfoFlags.of(long)静态方法ID jmethodID ofMethod = env->GetStaticMethodID(packageInfoFlagsClass, "of", "(J)Landroid/content/pm/PackageManager$PackageInfoFlags;"); if (ofMethod == nullptr) { env->DeleteLocalRef(packageManagerClass); env->DeleteLocalRef(packageInfoFlagsClass); return nullptr; } // 创建PackageInfoFlags实例(传入0表示无额外标志,可根据需求替换为对应long值) jobject flagsObj = env->CallStaticObjectMethod(packageInfoFlagsClass, ofMethod, 0L); if (flagsObj == nullptr) { env->DeleteLocalRef(packageManagerClass); env->DeleteLocalRef(packageInfoFlagsClass); return nullptr; } // 获取getPackageInfo方法ID jmethodID getPackageInfoMethod = env->GetMethodID(packageManagerClass, "getPackageInfo", "(Ljava/lang/String;Landroid/content/pm/PackageManager$PackageInfoFlags;)Landroid/content/pm/PackageInfo;"); if (getPackageInfoMethod == nullptr) { env->DeleteLocalRef(packageManagerClass); env->DeleteLocalRef(packageInfoFlagsClass); env->DeleteLocalRef(flagsObj); return nullptr; } // 调用方法获取PackageInfo jobject packageInfoObj = env->CallObjectMethod(packageManagerObj, getPackageInfoMethod, packageName, flagsObj); // 释放局部引用,避免内存泄漏 env->DeleteLocalRef(packageManagerClass); env->DeleteLocalRef(packageInfoFlagsClass); env->DeleteLocalRef(flagsObj); return packageInfoObj;
常见排查点
- 确认
packageManagerObj是有效的PackageManager实例,比如通过context.getPackageManager()获取的对象。 - 检查目标设备SDK版本是否≥33,低版本需兼容旧方法。
- 若开启混淆,需在混淆规则中保留
android.content.pm.PackageManager和android.content.pm.PackageManager$PackageInfoFlags类及方法。
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

