前一章主要是FM的自动调频, 接下来我们就看看FM手动调频是如何进行的。如果不清楚FM自动调频的过程,请打开超链接查看FM搜索频率流程。

首先来看一下流程图:

2.滑动刻度盘HorizontalNumberPicker控件在监听事件里使用方法valueToFrequency(newVal)

1.长按左右箭头居中的频率字符串,弹出FrequencyPickerDialog调频对话框确定调用tuneRadio(frequency)调频。

获取到频率

protected int valueToFrequency(int value) {
mFrequency = mPrefs.getLowerLimit() + value *
mPrefs.getFrequencyStepSize();
return mFrequency;
}

发送一个handler 回调一个tuneRadio(frequency)调频。

Runnable mRadioChangeFrequency = new Runnable(){
public void run() {
mUpdatePickerValue = false;
tuneRadio(mFrequency);
}
};

3.手动点击按钮左右箭头, 通过监听调用:

int frequency =FmSharedPreferences.getNextTuneFrequency();

int frequency =FmSharedPreferences.getPrevTuneFrequency();

tuneRadio(frequency);进行调频

getNextTuneFrequency()方法通过判断频率最大限制范围,后加200(刻度)

getPrevTuneFrequency()方法通过判断频率最小限制范围,后减200(刻度)

调频方法分析

private void tuneRadio(int frequency)

private void tuneRadio(int frequency){
/* Issue the tune command only if tuneCommand is already not active */
if((mService != null) && (mCommandActive != CMD_TUNE) && isFmOn()) {
boolean bStatus = false;
try {
bStatus = mService.tune(frequency);
if (bStatus) {
postTimeoutHandler(CMD_TUNE);
}else {
if (isFmOn()) {
mCommandFailed = CMD_TUNE;
Log.e(LOGTAG, "mService.tune failed");
showDialog(DIALOG_CMD_FAILED);
}
}mTunedStation.setName("");
mTunedStation.setPI(0);
mTunedStation.setPty(0);
updateStationInfoToUI();
}catch (RemoteException e) {
e.printStackTrace();
}
}else {
Log.e(LOGTAG, "Delayed Tune handler stopped");
}
}

通过回调引用类调用FMRadioService类的tune()方法进行调频

bStatus = mService.tune(frequency);

发送一个广播连接是否超时

postTimeoutHandler(CMD_TUNE);

设置调频名字,更新FMRadioUI界面信息

mTunedStation.setName("");

mTunedStation.setPI(0);

mTunedStation.setPty(0);

updateStationInfoToUI()

(通过IFMRadioSrevice.aidl通信机制onbind返回的类的引用调用FMRadioService中的调频方法)

FMRadioService中的tune方法

public boolean tune(int frequency)

public boolean tune(int frequency) {
boolean bCommandSent=false;
double doubleFrequency = frequency/1000.00; Log.d(LOGTAG, "tuneRadio: " + doubleFrequency);
if (mReceiver != null)
{
mReceiver.setStation(frequency);
bCommandSent = true;
}
return bCommandSent;
}

调用FMReceiver类的setStation方法调频

public boolean setStation (intfrequencyKHz)

public boolean setStation (int frequencyKHz) {
int ret; mControl.setFreq(frequencyKHz);
ret = mControl.setStation(sFd);
if(ret < 0 )
{
return false;
}
else
{
return true;
}
}

调用FMRxControls类(FM读取控制台信息)设置频率

mControl.setFreq(frequencyKHz);

设置优化调频核心指定的频率

ret = mControl.setStation(sFd);

public int setStation(int fd) {
Log.d(TAG, "** Tune Using: "+fd);
int ret = FmReceiverJNI.setFreqNative(fd, mFreq);
Log.d(TAG, "** Returned: "+ret);
return ret;
}

最后调用FmReceiverJNI类

setFreqNative(fd, mFreq); 本地方法 JNI到 cpp文件

/*native interface */
static jint android_hardware_fmradio_FmReceiverJNI_setFreqNative
(JNIEnv * env, jobject thiz, jint fd, jint freq)
{
int err;
double tune;
struct v4l2_frequency freq_struct;
freq_struct.type = V4L2_TUNER_RADIO;
freq_struct.frequency = (freq*TUNE_MULT/1000);
err = ioctl(fd, VIDIOC_S_FREQUENCY, &freq_struct);
if(err < 0){
return FM_JNI_FAILURE;
}
return FM_JNI_SUCCESS;
}

Android FM模块学习之三 FM手动调频的更多相关文章

  1. Android FM模块学习之一 FM启动流程

    最近在学习FM模块,FM是一个值得学习的模块,可以从上层看到底层. 上层就是FM的按扭操作和界面显示,从而调用到FM底层驱动来实现广播收听的功能. FM启动流程:如下图: 先进入FMRadio.jav ...

  2. Android FM 模块学习之四 源码解析(1)

    Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 前一章我们了解了FM手动调频,接下 ...

  3. Android FM模块学习之四源码解析(一)

    转自:http://blog.csdn.net/tfslovexizi/article/details/41516149?utm_source=tuicool&utm_medium=refer ...

  4. Android FM模块学习之四源码分析(3)

    接着看FM模块的其他几个次要的类的源码.这样来看FM上层的东西不是太多. 请看android\vendor\qcom\opensource\fm\fmapp2\src\com\caf\fmradio\ ...

  5. Android FM模块学习之四源码学习(2)

    前几章我们分析了FM模块的几个主要的类文件,今天要分析的是:FMTransceiver.java   // 某些工程中名称为FMRadioService.java public class FmTra ...

  6. Android FM模块学习之二 FM搜索频道

    最近在学习FM模块,FM是一个值得学习的模块,可以从上层看到底层.上层就是FM的按扭操作和界面显示,从而调用到FM底层驱动来实现广播收听的功能. 看看FM启动流程:如下图: 先进入FMRadio.ja ...

  7. Android FM模块学习之二 FM搜索频率流程

    上一篇大概分析了一下FM启动流程,若不了解Fm启动流程的,能够去打开前面的链接先了解FM启动流程,接下来我们简单分析一下FM的搜索频率流程. 在了解源代码之前.我们先看一下流程图: 事实上从图中能够看 ...

  8. Android Bluetooth模块学习笔记

    一.蓝牙基础知识 1.蓝牙( Bluetooth )是一种无线技术标准,可实现固定设备.移动设备和楼宇个人域网之间的短距离数据交换.蓝牙基于设备低成本的收发器芯片,传输距离近.低功耗. 2.微波频段: ...

  9. 爱了,字节跳动大神最佳整理:582页Android NDK七大模块学习宝典,理论与实践

    前言 时至今日,短视频App可谓是如日中天,一片兴兴向荣.随着短视频的兴起,音视频开发也越来越受到重视,而且薪资水涨船高,以一线城市为例,音视频工程开发的薪资比Android应用层开发高出40%. 但 ...

随机推荐

  1. [问题2014S12] 复旦高等代数II(13级)每周一题(第十二教学周)

    [问题2014S12]  设 \(A,B\) 都是 \(n\) 阶半正定实对称阵, 证明: \(AB\) 的所有特征值都是非负实数. 进一步, 若 \(A,B\) 都是正定实对称阵, 证明: \(AB ...

  2. Cheatsheet: 2016 01.01 ~ 01.31

    Mobile An Introduction to Cordova: Basics Web Angular 2 versus React: There Will Be Blood How to Bec ...

  3. 获取ip

    需要引用System.Web http://stackoverflow.com/questions/4879837/smart-way-to-get-the-public-internet-ip-ad ...

  4. CSS基础介绍

    CSS介绍 CSS是指层叠样式表,CSS样式表极大的提高了工作效率 CSS基础语法 1. 首先选择一个属性 2. 选择了属性以后,用大括号括起来 3. 括号里面是对应的属性和属性值,如: select ...

  5. 左边图标右边文字,在div里居中

  6. Ggoogle Protocol Buffer的使用 (基于C++语言)

    首先说明的是Protocol Buffle是灵活高效的.它的一个很好的优点(很重要的,我认为)就是后向兼容性--当我们扩展了了.proto文件后,我们照样可以用它来读取之前生成的文件. 之前已经写了关 ...

  7. Delphi IDE 设置

    显示编译进度 Tools/Environment Options

  8. Pycharm使用问题# Interpreter设置

    Pycharm可以迅速更换interpreter版本. 在菜单栏选择File-Settings打开Settings设置对话框,选择展开Interpreter选项: 使用列表右侧的+和—即可增加和删除I ...

  9. java中获取ServletContext常见方法

    http://blog.sina.com.cn/s/blog_3fe961ae0100wjnf.html 1.在javax.servlet.Filter中直接获取 ServletContext con ...

  10. 从零搭建mongo分片集群的简洁方法

    一.目录 1.mongo路径,config数据路径,shard数据路径