Android 收音机相关知识

FM收音机

概述

由Android手机硬件的调谐芯片,通过接收和解调电台发出的电磁波的调频(FM)或调幅(AM)信号,从而播放和展示相应的节目信息。所以本地收音机应用一般不需要联网,其核心依赖于硬件调谐芯片。所以不是所有的手机都能收听本地收音机,但大部分的手机都支持。

收音机的基本原理

收音机的核心原理就是:电台播音员播出音频经过设备处理成电信号并搭载无线电波进行调制频率或者调制振幅后发射出来,收音机听过天线获取到电波信号,经过解调还原出电信号并且通过信号放大等操作输出到喇叭将电信号还原为为音频信号。

收音机其他信息 RDS功能

RDS全称“Radio Data System” 无线数据广播系统;如果只有信号波,电台显示的信息会非常单调。只能展示当前的频率。电台的名称,节目信息,介绍等相关信息需要靠RDS来完成传输,它是在调频广播发射信号中利用副载波把电台名称等信息发送以数字的形式发送出去。收音机这边通过具有RDS功能的调谐芯片将信息进行解析出来,并且展示。
使用RDS的前提是:电台和收音机调谐芯片都必须同时支持RDS的功能;但目前只有少部分的电台支持RDS。
RDS有两个核心的功能:AF和TA;
AF是指当当前台的信号低于某个值得时候自动搜索该台的其他信号好的频道并且进行自动切换。以达到更好的用户体验。
TA功能是一个强制性播放的功能,如果发生重大事故,紧急通告等交通信息,会强制性切换到该频率进行播放。

Android开发FM收音机源码解析

层级结构:

硬件driver(由芯片厂家提供) -> HAL(遵循HAL接口协议) -> C动态库(JNI调用)-> Framework(RadioManager) -> Application(逻辑与界面)
RadioManager这个类在系统API中是hide的,如果想在AndroidStudio中编译是需要做处理的,可自行查阅,但获取framework.jar应该都是必须的

分析:

1- 控制面板的显示:采用widget桌面小部件的方式显示。和应用FM交互通过广播。
2- 点击空白区域打开,启动Activity界面。界面上进行操作,但是需要考虑,如果直接通过控制面板操作,则是不需要启动Activity也能播放。所以必须要有一个CoreService核 心服务在后台运行,不需要依赖界面。
3- 外部控制也应该是和Servicre进行交互。需要考虑其扩展性
4- 监听焦点获取与丢失并且进行逻辑处理。
设计:
CoreService 一个真正操作的核心服务
Activity 主界面
Widget 控制面板
代码设计模式:这个可以看自己,这里使用MVP模式。那么就会有两个Presenter:
RaidoPresenter 收音机核心操作(包含音频处理)
FavoritePresenter 收藏操作
其他外部控制,只需要设计数据交互模式即可。
在这里插入图片描述

Android实现FM收音机

通过JNI访问HAL层
com_android_server_fm_FmService.cpp

注册好JNI之后,启动service进行访问,要注意的是系统app在Android4.2以后不能直接通过传统的startservice(intent)启动,这样会出现权限问题,因为4.2以后Android引入多用户操作,需要如下方式启动
startServiceAsUser(mServiceIntent,newUserHandle(UserHandle.USER_CURRENT));

车机开发之收音机应用开发

关于收音机安卓调试开发逻辑一定要先理解的是收音机功能是独立的一个硬件模块,就算没有收音机apk,该功能应该也是能从小喇叭听到收音声音的,开发收音机apk只不过是方便用户查看收音信息和控制调台而已,但是对于车机来说就算什么都不做,至少应该发送一个切源命令到MCU去通知MCU将声音通道切换到收音机芯片,否则就算收到台了也会没声音的,因为车机设备存在多个声音来源模块到音效芯片,切到谁小喇叭就出谁的声音;下面是开发流程:

S700平台开发收音机apk应用的数据通信流程:

(1) 首先,收音机是单独的一个硬件模块(6831),功能都是mcu去实现去控制的,跟应用层没关系,我们的Radio收音机apk只是拿到mcu发来的数据进行显示,仅此而已,应用层基本干不了什么实际操作,无非就是调用几个api接口发送某些指令可以简单通知mcu去控制收音机模块,这是对收音机apk开发的一个整体的认识;
(2) 其次,数据初始化问题:在apk主界面打开时通过发送指令去拿,然后更新UI,无非就是当前波段,当前频率,预存电台列表等信息,有seekbar则需要将当前频率转换成seekbar的进度值设置到seekbar中即可,没有就不需要;
(3) 最后,做法问题:之前的做法都是FM分FM1和FM2以及FM3,每个FM都有6个预存电台,现在只返回一个FM1就代表是FM波段,并直接返回18个预存电台信息;AM也是一样,之前是分AM1和AM2,现在直接是返回AM1就代表AM波段了,返回6个预存电台,点击UI界面FM和AM按钮时切换波段发送指令分别是mMcuManager.mcuRadioBandSet(39)和McuManager.mcuRadioBandSet(42),之前的FM2,FM3,AM2对应的指令基本就作废了,无用了;全局搜索电台功能是点击按钮调用mMcuManager.mcuRadioScan()接口去实现的,这个搜索是从头到尾搜索,搜索到的电台会依次存到18个预存电台中,等到搜索完成之后会每个电台播放几秒钟供用户自己选择,如果不选择,那么等所有搜索到的台播放完之后就会跳到第一个搜索到的电台;向上向下搜索都是搜到可用电台就停止下来不会继续搜索了;6831收音机芯片是支持RDS的,但是RDS国外才会使用到的,国内无效;
### 如何在Java中生成JAR包 在 Java 中,可以通过 `jar` 工具生成 JAR 包。以下是关于如何生成 JAR 包的具体方法及其常见问题的解决方案。 #### 使用命令行生成 JAR 包 通过命令行工具可以轻松创建 JAR 文件。例如,以下命令用于将指定文件和目录打包成 JAR 文件: ```bash jar -cvfm my.jar manifest.mf 1.txt com/ ``` 上述命令中的参数含义如下: - `-c`: 创建新的归档文件。 - `-v`: 显示详细的输出信息。 - `-f`: 指定生成的 JAR 文件名。 - `-m`: 将清单文件的内容添加到 JAR 文件的 MANIFEST.MF 文件中[^1]。 其中,`com/` 表示要将当前目录下的 `com` 目录(包括其子目录和文件)打包到 JAR 文件中。如果存在名为 `com.example` 的包,并且该包下有多个类文件,则可以直接使用 `com` 来指定将其打包到 JAR 文件中。 #### 运行生成的 JAR 包 为了运行生成的 JAR 包,需要确保 JAR 文件中有正确的主清单条目(Main-Class)。例如,在运行 `hello.jar` 文件之前,必须确认其 MANIFEST.MF 文件指定了入口点类。 --- ### 生成 JAR 包时常见的问题及解决方案 #### 1. **本地 JAR 包无法被打包进部署包** 当项目依赖于本地 JAR 包时,可能在发布阶段出现问题,导致这些本地 JAR 包未被正确包含在最终的部署包中。为了解决此问题,可以在 Maven 配置中调整依赖项的范围(scope),并将本地 JAR 包显式安装到本地仓库中。完成配置后,重新执行 `mvn install` 即可成功引入本地 JAR 包[^2]。 #### 2. **API 变更引发兼容性问题** 在升级第三方库版本时,可能会因为 API 的变更而导致现有代码失效。为了避免此类问题,建议在升级前仔细阅读新版本的文档说明,并测试关键功能模块以验证兼容性[^3]。 #### 3. **DLL 或 SO 库加载失败** 对于某些需要动态链接库支持的应用程序,导出为可运行 JAR 包时可能出现 DLL 或 SO 加载失败的情况。一种可行的解决方案是将所需的库文件与 JAR 包一同打包,并通过自定义逻辑设置库路径。另一种方式是在运行环境中手动配置环境变量,指向所需库的位置[^4]。 #### 4. **资源文件丢失** 在将项目导出为 JAR 包的过程中,有时会发现图片、音效等资源文件未能正确嵌入到 JAR 文件中。这通常是由于构建脚本或 IDE 设置不当引起的。解决办法之一是检查项目的资源目录结构,确保它们能够被正确识别并复制到目标位置。此外,还可以尝试修改构建工具的相关配置选项,比如 Ant 脚本或 Gradle 构建文件[^5]。 --- ### 示例代码:生成带主类的 JAR 文件 假设我们有一个简单的 Java 程序,其主类位于 `com.example.Main` 下。下面是一个完整的流程演示: 1. 编写 `MANIFEST.MF` 文件,内容如下: ``` Manifest-Version: 1.0 Main-Class: com.example.Main ``` 2. 执行编译操作: ```bash javac -d out src/com/example/Main.java ``` 3. 利用 `jar` 命令生成 JAR 文件: ```bash jar -cvfm MyProgram.jar manifest.mf -C out . ``` 4. 测试运行生成的 JAR 文件: ```bash java -jar MyProgram.jar ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呼唤2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值