Android中FMRadio实现

转自:http://qiuzhenqing.blog.edu.cn/2010/576669.html。作者:qiuzhenqing

 

目前android还没有有关FMRadio的application接口类,下面对目前存在的一个实现案例进行分析。

 硬件: BCM4329 + CPCAP

        要求:BCM4327需要连接RX天线 

                   audio analog out与CPCAP相连

 软件:

  FMRadio.apk   --> Java应用

  libfmradio_jni.so : frameworks/base/fmradio/jni  --> Jni

  libfmradioplayer.so  :             -->    HAL

  libfmradiostackservice.so  :       -->    HAL

 

  libFMRadio.so 这是实现FM的基本功能库 比如搜台 依赖于libbluetooth libutils 之所以跟蓝牙相关,是因为BCM4329是个蓝牙+WIFI+FM的合成芯片,FM与蓝牙共用电源,发命令共用一个HCI。

  libaudio.so 

 

首先,在init.rc中,需要启动一个FM服务,这里叫fmradio,可执行文件叫fmradioserver

service fmradio /system/bin/fmradioserver

    group bluetooth

 

fmradioserver的代码示例:

int main(int argc, char** argv)

{

....

    FMRadioStackService::instantiate(); // start the fmradio.stack service

....

}

 

FMRadioStackService.cpp

void FMRadioStackService::instantiate() {

    defaultServiceManager()->addService(

            String16("fmradio.stack"), new FMRadioStackService());

}

 

通过这个FMRadioStackService类,FM的基本功能已经可用

 

class FMRadioStackService : public BnFMRadioStackService, protected Thread

{

public:

 

        static void instantiate();

 

。。。

 

        virtual bool powerOnDevice();

        virtual bool powerOffDevice();

        virtual void setFMRadioPlayerClient(const sp& client);

        virtual bool open();

        virtual bool getBand() const;

        virtual bool setBand(RADIO_BAND bind);

        virtual bool tune(unsigned int freq);

        virtual bool currentFreq() const;

        virtual bool setAudioMode(AUDIO_MODE mode);

        virtual bool getAudioMode() const;

        virtual bool seek(SEEK_DIRECTION direction);

        virtual bool stopSeek();

        virtual bool setVolume(unsigned int vol);

        virtual bool getVolume() const;

        virtual bool setEmphasisFilter(EMPHASIS_FILTER filter);

        virtual bool getEmphasisFilter() const;

        virtual bool setMute(MUTE_MODE mode);

        virtual bool isMute() const;

        virtual bool enableAudioTarget(AUDIO_TARGET val); // should be called after set band;

        virtual bool disableAudioTarget(AUDIO_TARGET val);

        virtual bool getRssiLevel();

        virtual int  getChipsetId();

        virtual bool close();

 

        static void fm_int_handler(FMRadio_Msgs_t, int, int, char*);

 

 

 

private:

 

        sp m_client;

。。。。

};

 

FMRadioStackService继承了BnFMRadioStackService, BnFMRadioStackService继承了BBinder与IFMRadioStackService,实现了onTransact()。如果把整个FMRadio看作是Client/Server模式的话,Server端就算完成了。这里有一个私有成员变量m_client显得比较奇怪,其实它是用来向上notify状态的,通过virtual void setFMRadioPlayerClient(const sp& client)赋值。

 

 

 

根据binder机制,我们知道一定会有一个BpFMRadioStackService,它继承BBinder与IFMRadioStackService,通过remote()->transact()实现IFMRadioStackService接口,给Client上层提供各种FMRadio功能的调用,当然remote()->transact()通过BnFMRadioStackService调到了真正的底层服务。

 

 

 

通过JNI gMethods

 

static JNINativeMethod gMethods[] = {

    {"powerOnDevice",    "()Z",      (void*)fmradio_powerOn },

    {"powerOffDevice",   "()Z",      (void*)fmradio_powerOff },

    {"open",       "()Z",            (void*)fmradio_open },

    {"getBand",    "()Z",            (void*)fmradio_getBand },

    {"setBand",    "(I)Z",           (void*)fmradio_setBand },

    {"tune",       "(I)Z",           (void*)fmradio_tune },

    {"currentFreq", "()Z",           (void*)fmradio_currentFreq },

    {"setAudioMode", "(I)Z",         (void*)fmradio_setAudioMode },

    {"getAudioMode", "()Z",          (void*)fmradio_getAudioMode },

    {"seek",         "(I)Z",         (void*)fmradio_seek },

    {"stopSeek",     "()Z",          (void*)fmradio_stopSeek },

    {"setVolume",    "(I)Z",         (void*)fmradio_setVolume },

    {"getVolume",    "()Z",          (void*)fmradio_getVolume },

    {"setEmphasisFilter", "(I)Z",    (void*)fmradio_setEmphasisFilter },

    {"getEmphasisFilter", "()Z",     (void*)fmradio_getEmphasisFilter },

    {"setMute",     "(I)Z",          (void*)fmradio_setMute },

    {"isMute",      "()Z",           (void*)fmradio_isMute },

    {"enableAudioTarget", "(I)Z",    (void*)fmradio_enableAudioTarget },

    {"disableAudioTarget","(I)Z",    (void*)fmradio_disableAudioTarget },

    {"close",       "()Z",           (void*)fmradio_close },

    {"native_setup", "(Ljava/lang/Object;)V",          (void*)fmradio_native_setup },

    {"native_finalize", "()V",       (void*)fmradio_native_finalize }

};

 

加上registerNativeMethods

 

    if(AndroidRuntime::registerNativeMethods(env, "com/motorola/fmradio/FMRadioPlayer", gMethods, NELEM(gMethods))>= 0) {

        result = JNI_VERSION_1_4;

    }

 

我们把com.motorola.fmradio.FMRadioPlayer这个FM类提供给了application developer.

 

当然,你还需要写一个FMRadioPlayer.cpp 把这些native方法申明一下。

 

 

 

以下的故事应该从native_setup开始,因为它绑定了fmradio.stack服务,所以它被放在了FMRadioPlayer的构造函数中。

 

JNIEXPORT void JNICALL fmradio_native_setup(JNIEnv *env, jobject obj, jobject weak_this)

{

    LOGI("IN JNI fmradio_native_setup/n");

 

    sp fmstack = getFMRadioStackService();//这里会有binder = sm->getService(String16("fmradio.stack"));

。。。

 

}

 

 

 

以后的应用层内容(略) 

你可能感兴趣的:(android,String,filter,jni,application,audio)