【发布时间】: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