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

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

gpio 컨트롤관련하여 ledservice 가 바로 죽어 버리는현상이 나오는... [2]

  • biokk
  • 2015-01-17
  • 조회 수 224

ndk onTransact 함수에 대한 질문인데요 [1]

  • ice179
  • 2015-02-07
  • 조회 수 247

android binder 의 onTransact(uint32_t code, ...)의 code값은 ... [1]

  • ice179
  • 2015-01-29
  • 조회 수 290

ledservice , 라이브러리 추가 관련한 질문입니다 [3]

  • ice179
  • 2015-02-04
  • 조회 수 341

ndk 함수에서 c언어 동작은 onTransact 에서만 동작하나요? [3]

  • ice179
  • 2015-02-03
  • 조회 수 362

안드로이드 ndk gpio컨트롤 하기 질문입니다. [2]

  • ice179
  • 2015-01-16
  • 조회 수 434

3장 계산기 에러 file [2]

gpio 컨트롤 예제질문입니다. [3]

  • biokk
  • 2015-01-21
  • 조회 수 649

ndk 라이브러리추가 하는 질문입니다 [8]

  • ice179
  • 2015-02-11
  • 조회 수 820

ndk를 이용하여 일반 안드로이드 어플을 만들수가 있나요? [3]

  • biokk
  • 2015-07-25
  • 조회 수 1025

pluscalc 질문입니다. [1]

[예제17.ffmpeg를 활용한 player] ffmpeg를 활용한 player file

ffmpeg 예제에 대해 문의 드립니다. [1]

ics에서 OpenSL의 Playback Rate 안됨 [1]

NDK 에서 BYTE 나 BOOL 등은 사용 못하는지요? [1]

[예제15.Native_Thread] Native Thread 예제 file

[예제07/08.MethodCall] Native에서 JAVA의 Method를 호출하는 예... file

[예제14.JNI_onLoad] JNI_OnLoad 예제 file

ffmpeg 빌드관련 질문드립니다 file [6]

[예제16.GPIO제어] App. 에서 H/W 제어하는 예제 (native bind... file

사용자 로그인