前一章主要是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. R----data.table包介绍学习

    相比dplyr包,data.table包能够更大程度地提高数据的处理速度,这里就简单介绍一下data.tale包的使用方法. data.table:用于快速处理大数据集的哦 数据的读取 data.ta ...

  2. python 注意事项

    常见错误 #4:  不理解Python的作用域 Python是基于 LEGB 来进行作用于解析的, LEGB 是 Local, Enclosing, Global, Built-in 的缩写.看起来“ ...

  3. 。【自学总结 3】------3ds Max 主工具栏

    1.选择并链接:选择对象,使其和其他对象建立父子关系. 2.断开选择链接:撤销链接关系. 3.选择过滤器列表:可以限制要选择的对象的特定类型和组合.例如,我们选择几何体后,其他对象就无法被选择. 4. ...

  4. 不用安装Oracle_Client就能使用PLSQL_Developer

    1. 下载oracle的客户端程序包(30M)       只需要在Oracle官方网站下载一个叫Instant Client Package的软件就可以了,这个软件不需要安装,只要解压就可以用了,很 ...

  5. ITerm2下使用ssh访问Linux

    通常情况下,iTerm2访问远程Linux使用ssh,与Termial基本一样,方法如下: ssh <用户名>@<ip> 然后输入访问的密码即可.当然还有的时候需要指定访问端口 ...

  6. LTE Module User Documentation(翻译8)——核心网(EPC)

    LTE用户文档 (如有不当的地方,欢迎指正!) 14 Evolved Packet Core (EPC)   我们现在讲解如何编写一个仿真程序——除了 LTE 无线接入网外,还允许仿真 EPC. EP ...

  7. [Git] 怎么使用Git让代码回到以前的某个节点

    我们可以使某个文件回到以前的某个节点,也可以使整个文件夹下面的文件都回到以前的某个节点,下面只介绍某个文件的,全部的类似. 按步骤操作完成后本地你选中的文件会变成红色,此时的代码还是原来的代码,但是G ...

  8. 项目忽然出现 The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path 解决方法

    0.环境: 新装win8.1系统,Tomcat配置无误. 1.错误: 项目中某一.jps页面忽然出现错误,鼠标点上去为:The superclass "javax.servlet.http. ...

  9. The import javax.servlet.http.HttpServletRequest cannot be resolved

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  10. (转)SQLServer实例讲解

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...