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

안녕하세요. 휴대폰의 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

PDK를 이용하여 안드로이드 프레임워크 so파일 참조에 관해서 질문있... [7]

예제를 따라하던 중 Android.mk 파일로 APK파일 생성 후 설치시 ... [6]

ndk 38페이지 질문_repo file [1]

안드로이드의 모든것 분석과 포팅 교재 관련 [2]

  • nexus26
  • 2011-07-05
  • 조회 수 10562

[Linux와 Android] 001 - 임베디드 시스템에 대하여 file

다시 질문 드립니다.ㅜㅜ apk 설치문제입니다. [3]

책 관련해서 질문이 있습니다. [1]

  • winpih
  • 2011-07-13
  • 조회 수 9030

안드로이드 init의 특징에 대해 질문있습니다. [2]

117쪽 ueventd 실행 부분.. [1]

475페이지 그림 외 건의 사항.. [2]

[Linux와 Android] 002 - UNIX/Linux system 개요 file

[Linux와 Android] 002 - UNIX/Linux system 개요(Continue......

p186. Gingerbread 센서 구조의 간략한 설명 요청드립니다. [3]

  • forone
  • 2011-08-25
  • 조회 수 8429

NDK를 이용한 camera 제어 예제에 대해 문의 드립니다. [7]

  • 죽유
  • 2013-01-11
  • 조회 수 8047

chapter7 안드로이드 오디오 서브시스템 에서 궁금한게 있습니다 [1]

개발환경 설정 중 문의사항입니다. file [1]

아래 [SDL 예제관련 에러 질문입니다.] 이어서... [3]

  • 민민
  • 2012-12-26
  • 조회 수 7753

책이 나온내용이지만 좀 다른예기일수도 잇네요 [1]

RGB 부분에 대해서 질문이 있습니다. [1]

  • ys2cdh
  • 2012-01-05
  • 조회 수 7380

JNI로 휴대폰 디바이스 번호를 구하려고 합니다 file [3]

  • fox8306
  • 2012-09-19
  • 조회 수 6878

사용자 로그인