현재 FM 수신 프로그램 앱 개발중인데 도대체 뭐가 잘못됐는지 미치겠습니다...
1.개발 Flow는 이렇습니다
- C++ 작성
- Android.mk 파일 작성
- ndk 컴파일 (.so 파일 생성)
- Java(jni) 작성
2.C++ 코딩내용
#define LOGI printf
#define LOG_TAG "fmradio"
#include "android_hardware_fmradio_FmReceiverJNI.h"
#include "jni.h"
#include "nativehelper/JNIHelp.h"
#include "utils/Log.h"
#include <cutils/log.h>
#include "utils/misc.h"
#include "android_runtime/AndroidRuntime.h"
#include <cutils/properties.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <math.h>
...중간생략
/* native interface */
static jint android_hardware_fmradio_FmReceiverJNI_acquireFdNative
(JNIEnv* env, jobject thiz, jstring path)
{
int fd;
int i;
char value = 0;
int init_success = 0;
LOGI("Radio starting\n");
hci_w(BCM4325_I2C_FM_RDS_SYSTEM, BCM4325_FM_RDS_SYSTEM_FM);
/* Write the POWER register again. If this fails, then we're screwed. */
if (hci_w(BCM4325_I2C_FM_RDS_SYSTEM,BCM4325_FM_RDS_SYSTEM_FM) < 0){
return FM_JNI_FAILURE;
}
/* Write the band setting, mno/stereo blend setting */
if(hci_w(BCM4325_I2C_FM_CTRL, BCM4325_FM_CTRL_MANUAL |BCM4325_FM_CTRL_STEREO) < 0){
return FM_JNI_FAILURE;
}
if (hci_w(BCM4325_I2C_FM_AUDIO_CTRL0,
BCM4325_FM_AUDIO_CTRL0_DAC_OUT_LEFT_ON | BCM4325_FM_AUDIO_CTRL0_DAC_OUT_RIGHT_ON |
BCM4325_FM_AUDIO_CTRL0_ROUTE_DAC_ENABLE | BCM4325_FM_AUDIO_CTRL0_DEMPH_75US) < 0) {
return FM_JNI_FAILURE;
}
return FM_JNI_SUCCESS;
}
...중간생략
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "acquireFdNative", "(Ljava/lang/String;)I",
(void*)android_hardware_fmradio_FmReceiverJNI_acquireFdNative},
중간생략...
/* int register_android_hardware_fm_fmradio(JNIEnv* env) */
int register_android_hardware_fmradio(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "android/hardware/fmradio/FmReceiverJNI", gMethods, NELEM(gMethods));
}
-------------------------------------------------------
3.Android.mk 내용
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -DHAVE_FM_RADIO
LOCAL_SRC_FILES := \
android_hardware_fm.cpp \
LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES := \
LOCAL_LDLIBS += -ldl
LOCAL_MODULE := FMRadio
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
4.컴파일 내용(NDK)
$ ./ndk-build -B -C FmRadio2/FMRadio/
make: Entering directory `/home/khandroid/android-ndk-r5/FmRadio2/FMRadio'
Compile thumb : FMRadio <= JNIHelp.c
Compile++ thumb : FMRadio <= android_hardware_fm.cpp
StaticLibrary : libstdc++.a
SharedLibrary : libFMRadio.so
Install : libFMRadio.so => libs/armeabi/libFMRadio.so
make: Leaving directory `/home/khandroid/android-ndk-r5/FmRadio2/FMRadio'
5.Java 코딩내용
윗부분 생략...
static {
try {
Log.i("JNI", "Trying to load libFMRadio.so");
//System.loadLibrary("FMRadio");
System.load("/data/data/com.quicinc.fmradio/lib/libFMRadio.so");
}
catch (UnsatisfiedLinkError ule) {
Log.e("JNI", "WARNING: Could not load libFMRadio.so");
}
}
중간생략...
Log.d(TAG, "FmReceiverJNI.acquireFdNative " + "로그 잘나옴, device = " + device);
sFd = FmReceiverJNI.acquireFdNative(device); <<-------- 이곳에서 Call
class FmReceiverJNI {
/**
* native method: Open device
* @return The file descriptor of the device
*
*/
static native int acquireFdNative(String path);
6.오류 로그 내용
01-03 22:09:06.291: DEBUG/FMRadio(12465): mService.fmOn() Start!!!!!!!!!!!!!!!
01-03 22:09:06.291: DEBUG/FMService(12465): fmOn
01-03 22:09:06.291: DEBUG/FmTransceiver(12465): FmReceiverJNI.acquireFdNative 로그 잘나옴, device = /dev/radio0
01-03 22:09:06.291: WARN/dalvikvm(12465): No implementation found for native Landroid/hardware/fmradio/FmReceiverJNI;.acquireFdNative (Ljava/lang/String;)I
01-03 22:09:06.291: DEBUG/AndroidRuntime(12465): Shutting down VM
01-03 22:09:06.291: WARN/dalvikvm(12465): threadid=1: thread exiting with uncaught exception (group=0x400259f8)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): FATAL EXCEPTION: main
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): java.lang.UnsatisfiedLinkError: acquireFdNative
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.hardware.fmradio.FmReceiverJNI.acquireFdNative(Native Method)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.hardware.fmradio.FmTransceiver.acquire(FmTransceiver.java:146)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.hardware.fmradio.FmReceiver.<init>(FmReceiver.java:286)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadioService.fmOn(FMRadioService.java:436)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadioService.access$8(FMRadioService.java:432)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadioService$ServiceStub.fmOn(FMRadioService.java:311)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadio.enableRadio(FMRadio.java:1561)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadio.access$15(FMRadio.java:1549)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadio$27.onServiceConnected(FMRadio.java:2767)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.quicinc.fmradio.FMRadio$ServiceBinder.onServiceConnected(FMRadio.java:2744)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.app.ActivityThread$PackageInfo$ServiceDispatcher.doConnected(ActivityThread.java:1280)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.app.ActivityThread$PackageInfo$ServiceDispatcher$RunConnection.run(ActivityThread.java:1297)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.os.Handler.handleCallback(Handler.java:587)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.os.Handler.dispatchMessage(Handler.java:92)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.os.Looper.loop(Looper.java:144)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at android.app.ActivityThread.main(ActivityThread.java:4937)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at java.lang.reflect.Method.invokeNative(Native Method)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at java.lang.reflect.Method.invoke(Method.java:521)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-03 22:09:06.300: ERROR/AndroidRuntime(12465): at dalvik.system.NativeStart.main(Native Method)
새해 복많이 받으시고
도움 부탁 드립니다...




중요한게 하나 있는데요...
CPP로 빌드할 경우 반드시 함수 선언하시고 그 부분을 extern "C"로 감싸줘야 합니다.
맹글링이던가... CPP로 빌드하면 함수 이름을 깨뜨리는 현상이 나오기 때문에...
호출이 안되는겁니다.