서적에 관한 질문 및 오류 등을 문의 할 수 있으며, 저자로부터 직접 답변을 받을 수 있습니다.

안녕하세요. 휴대폰의 getDeviceId()를 구하기 위해서 아래와 같은 코드를 작성하였습니다. 하지만 //에러라고 표시한 부분에서 오류가 발생하며 프로그램이 죽습니다.

09-19 04:55:22.289: W/dalvikvm(1621): JNI WARNING: can't call Landroid/content/Context;.getSystemService on instance of Ljava/lang/Class;

LogCat에는 위와 같은 메시지로 call하지 못하였다고 합니다.

/*
jstring buf_devid = NULL;

jclass cls_context = (*env)->FindClass(env, "android/content/Context");
jfieldID fid = (*env)->GetStaticFieldID(env, cls_context, "TELEPHONY_SERVICE", "Ljava/lang/String;");
jstring str = (*env)->GetStaticObjectField(env, cls_context, fid);
jmethodID mid = (*env)->GetMethodID(env, cls_context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject telephony = (*env)->CallObjectMethod(env, cls_context, mid, str); //에러
jclass cls_tm = (*env)->FindClass(env, "android/telephony/TelephonyManager");
mid = (*env)->GetMethodID(env, cls_tm, "getDeviceId", "()Ljava/lang/String;");
str = (*env)->CallObjectMethod(env, cls_tm, mid);
jsize len_jstr = (*env)->GetStringUTFLength(env, str);
(*env)->GetStringUTFRegion(env, str, 0, len_jstr, buf_devid);

return (*env)->NewStringUTF(env, buf_devid);
/*

소스를 첨부하였으며 확인 부탁드리겠습니다.. 감사합니다.


전호철

2012.09.20 05:26:41
*.47.84.67

제가 지금 소스를 잠시 살펴보니 getSystemService 라는 함수가 Context class에서 abstract 함수로 되어 있어서 호출을 못하고 있는것으로 보입니다.

getSystemService 가 실제 구현되어 있는 클래스에서 호출을 해야 할것 같은데요.

 

지금 제 pc 환경이 올려주신 소스를 돌려볼 수가 없는상태라. 내일 회사에가서 확인해보면 정확히 알수 있을것 같습니다.

 

 

 

전호철

2012.09.21 03:52:26
*.200.239.210

아~ 이제야 소스확인을 했습니다.


올려주신 코드를 보니 


JNIEXPORT jstring JNICALL Java_com_sklee_jnitest_HelloJNI_getString(JNIEnv *env, jobject object){

jstring buf_devid = NULL;


jclass cls_context = (*env)->FindClass(env, "android/content/Context");

jfieldID fid = (*env)->GetStaticFieldID(env, cls_context, "TELEPHONY_SERVICE", "Ljava/lang/String;");

jstring str = (*env)->GetStaticObjectField(env, cls_context, fid);

jmethodID mid = (*env)->GetMethodID(env, cls_context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");

jobject telephony = (*env)->CallObjectMethod(env, cls_context, mid, str);  <= 여기가 잘못되었는데 왜냐하면 context 객체가 생성된 타이밍에서 getSystemService 를 가져오셔야 합니다. 왜냐하면 abstract 함수이기 때문이죠. 

다시 말해서 Activity가 만들어지면서 context가 생기는데 이 context를 통해서 저 함수를 호출하셔야 한다는 말이죠

jclass cls_tm = (*env)->FindClass(env, "android/telephony/TelephonyManager");

mid = (*env)->GetMethodID(env, cls_tm, "getDeviceId", "()Ljava/lang/String;");

str = (*env)->CallObjectMethod(env, cls_tm, mid); <= 여기서도 마찬가지로 액티비티에서 나온 context 를 통해서 생성된 TelephonyManager를 통해서 호출해야 합니다.

jsize len_jstr = (*env)->GetStringUTFLength(env, str);

(*env)->GetStringUTFRegion(env, str, 0, len_jstr, buf_devid);


return (*env)->NewStringUTF(env, buf_devid);

}







제가 코드를 다시 정리해 보았는데 이렇게 짜시면 되겠습니다.


자바에서 하는 순서 그대로 Native 에서 하시면 됩니다.


---------------------------------------------------------------------------------------------------------------------------------------

JAVA CODE


package com.sklee.jnitest;


import android.app.Activity;

import android.content.Context;

import android.os.Bundle;

import android.telephony.TelephonyManager;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.TextView;


public class JNITestActivity extends Activity {

    private TextView mTextView;

    private Context mContext;


    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);


        mContext = getApplicationContext();

        mTextView = (TextView) findViewById(R.id.textivew);

        System.loadLibrary("hellojni");


        findViewById(R.id.btn).setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                /*

                 * TelephonyManager tManager = (TelephonyManager)

                 * getSystemService(Context.TELEPHONY_SERVICE); String mDeviceID

                 * = tManager.getDeviceId(); Log.e("HOHO", "HOHO : " +

                 * mDeviceID);

                 */

                mTextView.setText(getString());

            }

        });

    }


    public native String getString();

}



---------------------------------------------------------------------------------------------------------------------------------------

NATIVE CODE


#include <string.h>

#include <jni.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <android/log.h>

#include "HelloJNI.h"


#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "libnav", __VA_ARGS__)

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG  , "libnav", __VA_ARGS__)

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO   , "libnav", __VA_ARGS__)

#define LOGW(...) __android_log_print(ANDROID_LOG_WARN   , "libnav", __VA_ARGS__)

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "libnav", __VA_ARGS__)


JNIEXPORT jstring JNICALL Java_com_sklee_jnitest_JNITestActivity_getString(JNIEnv *env, jobject obj){


    jclass cls =(*env)->GetObjectClass(env, obj);

    jfieldID fid = (*env)->GetFieldID(env, cls, "mContext", "Landroid/content/Context;");

    jobject mContext = (*env)->GetObjectField(env, obj, fid);

    jclass cls_context = (*env)->FindClass(env, "android/content/Context");

    jmethodID getSystemService = (*env)->GetMethodID(env, cls_context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");

    jfieldID TELEPHONY_SERVICE = (*env)->GetStaticFieldID(env, cls_context, "TELEPHONY_SERVICE", "Ljava/lang/String;");

    jstring str = (*env)->GetStaticObjectField(env, cls_context, TELEPHONY_SERVICE);

    jobject telephonymanager = (*env)->CallObjectMethod(env, mContext, getSystemService, str);

    jclass cls_tm = (*env)->FindClass(env, "android/telephony/TelephonyManager");

    jmethodID getDeviceId = (*env)->GetMethodID(env, cls_tm, "getDeviceId", "()Ljava/lang/String;");

    jstring deviceid = (*env)->CallObjectMethod(env, telephonymanager, getDeviceId);

    jsize len_jstr = (*env)->GetStringUTFLength(env, deviceid);

    LOGE("HOHO deviceid lenth : %d",len_jstr);

    return deviceid;

}


fox8306

2012.09.21 18:25:30
*.150.0.242

감사합니다.. 큰 도움 되었습니다.

List of Articles
번호 제목 글쓴이 날짜sort 조회 수
83 ffmpeg HOPLAY [3] 네이쳐 2013-12-01 4792
82 안드로이드의 모든 것NDK (고현철,전호철 지음) 책 실습 중 문제에... [1] 어떤이의꿈 2013-10-02 5404
81 init: sys_prop: unable to stop service ctl [DVBService] ... [2] 제임스59 2013-09-22 5480
80 NDK 책내용중에 3.11 외부 라이브러리 활용하기 에서 질문 드립니... file [5] 엽스 2013-08-30 5590
79 ndk 38페이지 질문_repo file [1] 제임스59 2013-08-28 12060
78 여러 분들이 말씀하신 것처럼 책(NDK)의 예제코드를 올려주실 수 없... [2] 트론 2013-08-24 5255
77 surfaceflinger에서 화면을 dump뜨는 메카니즘에 대해서... 김바람 2013-08-19 5134
76 안드로이드 4.2 프레임버퍼 접근 질문드려요~! [6] 범내 2013-07-30 5951
75 [압축된 07-TestSkia 예제파일 올려주세요] [1] 밥줘잉 2013-05-23 5664
74 MediaServer 에 관련해서 질문드려요 [10] 김바람 2013-03-27 6581
73 3rd party app에서 프레임워크 수정된 걸 적용시키려면 어떻게 해야... [3] 김바람 2013-03-17 4839
72 [예제12.SDL] Android 에서 SDL 사용하는 예제 실행 안됨 문의... [7] 둘리 2013-03-12 5609
71 PDK를 이용하여 안드로이드 프레임워크 so파일 참조에 관해서 질문있... [7] 김바람 2013-03-07 26831
70 예제를 따라하던 중 Android.mk 파일로 APK파일 생성 후 설치시 ... [6] 김바람 2013-03-05 12345
69 네이티브 스레드로 자바 콜백 만들기 질문드립니다. [2] 조재영 2013-02-14 5662
68 GPIO 컨트롤 하기 예제 중 insmod에 관하여 문의드립니다. [2] 미누유희 2013-02-13 5127
67 OpenGL 책p168 예제 질문드립니다. Android홀릭 2013-02-06 5413
66 카메라로부터 프래임 데이터 추출하는 예제 입니다. file [1] 죽유 2013-01-24 5383
65 NDK를 이용한 camera 제어 예제에 대해 문의 드립니다. [7] 죽유 2013-01-11 8050
64 NEON관련 좋은 참고 문서가 있을까요? [7] 죽유 2013-01-10 5393

사용자 로그인