You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13下JNI中如何调用PackageManager.getPackageInfo(String, PackageInfoFlags)

在JNI中使用PackageInfoFlags获取PackageInfo的正确方式

你的代码出现NameNotFoundException,核心问题大概率是方法签名匹配错误、类对象获取不正确,或者没有正确构造PackageInfoFlags实例。下面是完整的解决步骤和示例代码:

关键问题分析

  1. 方法签名验证:你写的方法签名格式是对的,但要确保PackageManager类对象是从实际的PackageManager实例获取的,而非其他类。
  2. PackageInfoFlags的构造:PackageInfoFlags没有公共构造方法,必须通过静态方法of(long)创建实例,不能直接实例化。
  3. 版本兼容:该方法仅在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:50:17