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

如何通过JNI调用WallpaperManager的getDrawable/peekDrawable方法及解决报错

Android JNI调用WallpaperManager获取壁纸问题解决

错误根源

  • 调用WallpaperManager.getInstance(nullptr)传入了空Context:getInstance必须接收有效Context(如Activity实例)才能访问系统服务,空Context会触发NullPointerException。
  • peekDrawable()方法签名错误:该方法返回Drawable类型,正确签名为()Landroid/graphics/drawable/Drawable;,而非你写的()Landroid/app/WallpaperManager;。

修正后的JNI代码

// 1. 获取有效的GameActivity实例(Context不能为空)
jobject gameActivity = FAndroidApplication::GetGameActivityThis();
if (!gameActivity) {
    // 处理Activity为空的场景,比如打日志
    return nullptr;
}

// 2. 查找WallpaperManager类
jclass wallpaperManagerCls = JEnv->FindClass("android/app/WallpaperManager");
if (!wallpaperManagerCls) {
    return nullptr;
}

// 3. 获取getInstance静态方法ID
jmethodID getInstanceMtd = JEnv->GetStaticMethodID(
    wallpaperManagerCls,
    "getInstance",
    "(Landroid/content/Context;)Landroid/app/WallpaperManager;"
);
if (!getInstanceMtd) {
    JEnv->DeleteLocalRef(wallpaperManagerCls);
    return nullptr;
}

// 4. 获取WallpaperManager实例
jobject wallpaperManager = JEnv->CallStaticObjectMethod(
    wallpaperManagerCls,
    getInstanceMtd,
    gameActivity
);
if (!wallpaperManager) {
    JEnv->DeleteLocalRef(wallpaperManagerCls);
    return nullptr;
}

// 5. 获取peekDrawable方法ID(替换为getDrawable方法名即可调用对应接口)
jmethodID peekDrawableMtd = JEnv->GetMethodID(
    wallpaperManagerCls,
    "peekDrawable",
    "()Landroid/graphics/drawable/Drawable;"
);
if (!peekDrawableMtd) {
    JEnv->DeleteLocalRef(wallpaperManager);
    JEnv->DeleteLocalRef(wallpaperManagerCls);
    return nullptr;
}

// 6. 调用方法获取壁纸Drawable
jobject wallpaperDrawable = JEnv->CallObjectMethod(
    wallpaperManager,
    peekDrawableMtd
);

// 7. 清理本地引用,避免内存泄漏
JEnv->DeleteLocalRef(wallpaperManager);
JEnv->DeleteLocalRef(wallpaperManagerCls);

// 返回获取到的壁纸Drawable
return wallpaperDrawable;

额外提示

  • 权限要求:Android 10及以下需申请READ_EXTERNAL_STORAGE权限;Android 11+需申请ACCESS_MEDIA_LOCATION权限,否则可能无法获取壁纸。
  • 如果你使用getDrawable(),只需将代码中的peekDrawable替换为getDrawable即可,两者方法签名完全一致。
  • 若使用NewScopedJavaObject管理引用,注意其自动释放机制,避免手动调用DeleteLocalRef导致冲突。

内容的提问来源于stack exchange,提问作者codenicks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:52:41