sugelawa 发表于 2013-09-23 16:26

Native code通过JNI获取DeviceId失败,有人可以帮忙看看吗?

本帖最后由 rover12421 于 2013-09-23 17:32 编辑

我想在Native code中获取IMEI,但不想先在Java中实现,再JNI调用,而是想直接在Native中调用getDeviceId去获取,但是在执行getApplicationContext的时候无法成功,有人帮忙看看吗?非常感谢!
char * get_imei2(JNIEnv *env, jobject context)
{
        jclass thiz_class = (*env)->FindClass(env, "android/app/Activity");
        jmethodID mid_cxt = (*env)->GetMethodID(env, thiz_class, "getApplicationContext", "()Ljava/lang/Object;");
        jobject app_ctx = (*env)->CallObjectMethod(env, context, mid_cxt);    // --------------在这里出错无法通过
        jclass cls = (*env)->FindClass(env, "android/context/Context");
        jmethodID mid = (*env)->GetMethodID(env, cls, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
        jfieldID fid = (*env)->GetStaticFieldID(env, cls, "TELEPHONY_SERVICE", "Ljava/lang/String;");
        jstring str = (*env)->GetStaticObjectField(env, cls, fid);
        jobject telephony = (*env)->CallObjectMethod(env, app_ctx, mid, str);
        cls = (*env)->FindClass(env, "android/telephony/TelephonyManager");
        mid =(*env)->GetMethodID(env, cls, "getDeviceId", "()Ljava/lang/String;");
        str = (*env)->CallObjectMethod(env, telephony, mid);
        jsize len = (*env)->GetStringUTFLength(env, str);
        char* deviceId = calloc(len + 1, 1);
        (*env)->GetStringUTFRegion(env, str, 0, len, deviceId);
        (*env)->DeleteLocalRef(env, str);
        /* to get a string in deviceId */

        return deviceId;
}

rover12421 发表于 2013-09-23 17:33

回复 1# sugelawa


    给你编辑了下,不然没法看.代码最好还是放到代码框框里~~

rover12421 发表于 2013-09-23 17:44

FindClass 和 GetMethodID 之后,看下结果是否为null
还有传进来的参数 context 也判断一下

sugelawa 发表于 2013-09-23 21:04

回复 2# rover12421 非常感谢,我找代码格式没找着来着。我检查传入的context应该是没问题的,不知道这部分代码是否正确?


   

rover12421 发表于 2013-09-24 01:06

回复 4# sugelawa


    代码逻辑是没啥问题,但是仔细看了下
getApplicationContext 的返回值不是Object,而是Context,所以你这里就写错了
jmethodID mid_cxt = (*env)->GetMethodID(env, thiz_class, "getApplicationContext", "()Landroid/content/Context;");

还是给每一步加个判断比较好,容易找问题

sugelawa 发表于 2013-09-24 10:18

本帖最后由 sugelawa 于 2013-09-24 10:18 编辑

回复 5# rover12421 多谢兄台,还有个疑问,为什么jclass cls = (*env)->FindClass(env, "android/content/Context");这行执行结果总是NULL,而env没问题,这行代码之前的代码执行也没问题。


   

rover12421 发表于 2013-09-24 11:23

回复 6# sugelawa


    你把你的测试代码打包放上来吧,我给你看看

sugelawa 发表于 2013-09-24 15:10

回复 7# rover12421



非常感谢,附件是我的代码。这是一个Android Studio工程,其中jni目录下有个build.sh,运行后直接会生成并将libjni.so放到目标位置,然后直接运行工程,就可以执行了。

刚看了,的确报错在Context的获取那里:09-24 15:01:44.40917058-17058/com.example.testjni W/dalvikvm﹕ JNI WARNING: JNI method called with exception pending
09-24 15:01:44.40917058-17058/com.example.testjni W/dalvikvm﹕ in Lcom/example/testjni/Manager;.getDeviceIdJNI:(Landroid/content/Context;)Ljava/lang/String; (GetMethodID)
09-24 15:01:44.40917058-17058/com.example.testjni W/dalvikvm﹕ Pending exception is:
09-24 15:01:44.40917058-17058/com.example.testjni I/dalvikvm﹕ java.lang.NoClassDefFoundError: android/context/Context

rover12421 发表于 2013-09-24 22:40

回复 8# sugelawa


    "java.lang.NoClassDefFoundError: android/context/Context"

哈哈.找了半天,原来是你写错了
jclass cls = (*env)->FindClass(env, "android/context/Context");
====>
jclass cls = (*env)->FindClass(env, "android/content/Context");

sugelawa 发表于 2013-09-24 23:18

回复 9# rover12421

这是从stackoverflow上找到的代码,害得我好苦,眼珠都瞪出来了愣是没发现。
非常感谢你,问题终于被解决了。


   
页: [1] 2
查看完整版本: Native code通过JNI获取DeviceId失败,有人可以帮忙看看吗?