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

안녕하세요. 휴대폰의 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
103 PDK를 이용하여 안드로이드 프레임워크 so파일 참조에 관해서 질문있... [7] 김바람 2013-03-07 26815
102 예제를 따라하던 중 Android.mk 파일로 APK파일 생성 후 설치시 ... [6] 김바람 2013-03-05 12338
101 ndk 38페이지 질문_repo file [1] 제임스59 2013-08-28 12060
100 안드로이드의 모든것 분석과 포팅 교재 관련 [2] nexus26 2011-07-05 10588
99 [Linux와 Android] 001 - 임베디드 시스템에 대하여 file 고도리 2011-06-21 9496
98 다시 질문 드립니다.ㅜㅜ apk 설치문제입니다. [3] 여월광 2014-03-07 9132
97 책 관련해서 질문이 있습니다. [1] winpih 2011-07-13 9036
96 안드로이드 init의 특징에 대해 질문있습니다. [2] 얼사마 2011-07-12 9024
95 117쪽 ueventd 실행 부분.. [1] 홍순민 2011-08-30 8855
94 475페이지 그림 외 건의 사항.. [2] 장병남 2011-07-22 8635
93 [Linux와 Android] 002 - UNIX/Linux system 개요 file 고도리 2011-06-22 8626
92 [Linux와 Android] 002 - UNIX/Linux system 개요(Continue...... 고도리 2011-07-02 8573
91 p186. Gingerbread 센서 구조의 간략한 설명 요청드립니다. [3] forone 2011-08-25 8432
90 NDK를 이용한 camera 제어 예제에 대해 문의 드립니다. [7] 죽유 2013-01-11 8050
89 chapter7 안드로이드 오디오 서브시스템 에서 궁금한게 있습니다 [1] 가쓰비 2011-12-16 8017
88 개발환경 설정 중 문의사항입니다. file [1] 정바타 2011-10-14 7907
87 아래 [SDL 예제관련 에러 질문입니다.] 이어서... [3] 민민 2012-12-26 7759
86 책이 나온내용이지만 좀 다른예기일수도 잇네요 [1] 가쓰비 2011-12-21 7578
85 RGB 부분에 대해서 질문이 있습니다. [1] ys2cdh 2012-01-05 7382
84 아..권한 하고 마운트 에서 막혀버리네요..ㅜㅜ [1] 여월광 2014-03-09 7361

사용자 로그인