转自: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"));

。。。

}

以后的应用层内容(略)

更多相关文章

  1. Android BlueDroid(二):BlueDroid蓝牙开启过程init
  2. Android 访问Webservice接口,参数对象不能串行化问题解决(java.lan
  3. Android 蓝牙开发(九)A2DP基本功能
  4. android低功耗蓝牙APP开发问题记录
  5. [置顶] 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发详解
  6. 汇总各种Android 蓝牙各种UUID
  7. Android蓝牙通信代码
  8. Android接口初了解

随机推荐

  1. 基于更新SQL语句理解MySQL锁定详解
  2. 使用PDO防sql注入的原理分析
  3. MySQL 8.0.13 下载安装教程图文详解
  4. MySQL5.6的zip包安装教程详解
  5. 如何批量生成MySQL不重复手机号大表实例
  6. Linux下安装mysql的教程详解
  7. mysql 8.0.12 安装图文教程
  8. win10下mysql 8.0.13 安装配置方法图文教
  9. mysql 8.0.13 安装配置方法图文教程
  10. 详解mysql中的concat相关函数