【问题标题】:Read Settings.Secure from the NDK - Invalid indirect reference in decodeIndirectRef从 NDK 读取 Settings.Secure - decodeIndirectRef 中的间接引用无效
【发布时间】:2014-01-17 14:49:22
【问题描述】:

我正在尝试从 NDK 中读取 ANDROID_ID 字符串。

编辑:底部的初始问题,这是我现在的位置:

我删除了static并将Jni代码更改为:

jstring JNICALL GEN_FUNCNAME(MyClass_nGetID)(JNIEnv *env,jobject obj
{

jclass  activity = env->GetObjectClass(obj);

jmethodID  mid_getContentResolver =env->GetMethodID(activity,"getContentResolver","()Landroid/content/ContentResolver;");

jobject contentObj =  env->CallObjectMethod(obj, mid_getContentResolver);

if(contentObj == NULL)
    return env->NewStringUTF("method 1 null");

jclass secClass=env->FindClass("android/provider/Settings$Secure");

if(secClass == NULL)
    return env->NewStringUTF("class 2 null");

jmethodID secMid = env->GetStaticMethodID(secClass,"getString","(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");

if(secMid == NULL)
    return env->NewStringUTF("method 2 null");

jstring jandroid_id = (jstring) env->CallStaticObjectMethod(secClass,secMid,contentObj,"android_id");

if(jandroid_id == NULL)
    return env->NewStringUTF("android id null");

现在第一阶段似乎可以工作,但我在CallStaticObjectMethod 上收到以下错误:

W/dalvikvm(2698): Invalid indirect reference 0x7509bd4c in decodeIndirectRef
I/dalvikvm(2698):   at android.provider.Settings$Secure.getString(Settings.java:-1)
I/dalvikvm(2698):   at mypackage.myclass.nGetID(Native Method)

感谢您迄今为止的帮助! :)

我可以使用 Java 成功读取它:

final String android_id = Secure.getString(this.getContentResolver(),Secure.ANDROID_ID); 

我在 JNI 中的函数 CallObjectMethod 上收到 JNI 警告和 VM 崩溃。

有什么我忘了做的吗?

JNI_WARNING:

W/dalvikvm(14911): JNI WARNING: can't call Landroid/content/Context;.getContentResolver on instance of Ljava/lang/Class; (CallObjectMethodV)

VM 崩溃日志:

E/dalvikvm(14911): VM aborting
A/libc(14911): Fatal signal 6 (SIGABRT) at 0x00003a3f (code=-6), thread 14911 

我的 JNI 函数:

jstring GEN_FUNCNAME(MyClass_nGetID)(JNIEnv *env,jobject obj)

{
jclass  act = env->GetObjectClass(obj);
jclass  clsontentResolver = env->FindClass("android/content/Context");


jmethodID  mid_getContentResolver = env->GetMethodID(clsontentResolver,"getContentResolver","()Landroid/content/ContentResolver;");

jobject contentObj = env->CallObjectMethod(act, mid_getContentResolver);

jclass secClass=env->FindClass("android/provider/Settings$Secure");

jmethodID secMid=env->GetStaticMethodID(secClass,"getString","(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");

jstring jandroid_id= (jstring) env->CallStaticObjectMethod(secClass,secMid,contentObj,"android_id");

return jandroid_id;

}

我的 Java 主类:

public class MyClass extends Activity {

    TextView text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView)findViewById(R.id.text);

        text.setText(nGetID());

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    static { System.loadLibrary("mylib"); }
    public final static native String nGetID();

}

非常感谢!

【问题讨论】:

  • 出于好奇:为什么在 Java 中有现成可用的 API 时要从本机读取设置 DB?
  • 应用程序的最终用户将有权访问 Java 代码,我不希望他直接“修改”他的 ANDROID_ID。 (即使我知道有一些方法可以在有根设备上做到这一点)。

标签: java android android-ndk android-contentresolver


【解决方案1】:

(编辑)

要将字符串传递回 Java,您需要使用 NewStringUTF。像这样:

jstring jStringParam = getEnv()->NewStringUTF("android_id");
jstring jandroid_id = (jstring) env->CallStaticObjectMethod(secClass,secMid,contentObj,jStringParam);
// Remember to release when done!
getEnv()->DeleteLocalRef(jStringParam);

(首期)

jobject obj 未附加到实例

public final static native String nGetID(); 被定义为静态,这意味着它不会“附加”到任何对象实例。

在你的 JNI 函数中 行jclass act = env->GetObjectClass(obj); - 你传入jobject obj

尝试在没有static 的情况下声明nGetID(),这应该可以解决问题。你有什么理由想要它static

【讨论】:

  • 我收到完全相同的警告,并且 VM 中止删除 static。我没有特殊原因使用它,这是因为我得到了其他需要静态的 Jni 调用。
  • 在您调用 CallObjectMethod 之前,mid_getContentResolver 是否被设置为任何东西?
  • 没有。但是我改变了一些关于如何将当前类发送到这个函数的东西,这部分现在似乎可以工作了(见更新的问题)。我现在正在研究另一个问题(仍在更新的问题中)。非常感谢您的帮助丹尼。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
相关资源
最近更新 更多