基于蓝牙的遥控智能音乐播放器的实现
2017-10-21吕品品
吕品品
摘要:本文介绍了一款基于蓝牙、ARM 平台和Java虚拟机手持设备的遥控智能音乐播放器的具体实现。详细阐述了系统蓝牙遥控的实现;为了在客户端进行音乐播放,讨论了基于OBEX协议的音乐文件的下载功能模块的实现;设计实现了对客户端音乐播放进度的控制,并对客户端接收过程中遇到的蓝牙字符串乱码问题加以解决。
关键词:音乐播放器;蓝牙;OBEX
1.蓝牙遥控的实现
蓝牙通信实现不同设备之间的数据共享与数据交换,提供的是近距离设备之间的通信。蓝牙链接的建立依据蓝牙设备所处的地位分为主动链接和被动链接。对于每一次蓝牙通信链接的建立,服务器总是出于被动链接的地位,服务器必须先行启动,时刻监听,只要有客户机请求,就立即处理并响应回传信息,但决不会主动提供服务。客户机可以随时提出请求,通过網络得到服务,也可以关机离开,一次请求与服务的过程是由客户机首先激发的。在客户端建立主动链接的过程中,需要首先进行设备发现和服务发现,然后进行数据传输。在服务器建立被动链接的过程中,需要首先选择传输协议,然后监听到来的链接请求,之后接收链接请求,建立链接,开始进行数据的传输。
由于系统端口资源有限,对一个服务器应用程序不能独自占用一个端口号,而且独占端口会导致两个不同的server程序在同一个端口进行监听,出现端口冲突。为了解决这一问题,蓝牙协议在标准端口运行SDP服务解决。当服务器程序启动时会注册服务记录到SDP服务,SDP为其动态分配端口。当远程客户端链接到设备时,首先向服务器提供所搜索的服务的UUID,SDP server然后返回符合的服务列表,这样就避免了问题的发生。
2.基于OBEX的客户端文件推送与音乐文件下载
OBEX 传输协议定义了数据对象及两个设备用来交换这些对象的通信协议。OBEX 使应用程序能在 Bluetooth 技术协议栈及 IrDA栈上工作。对于Bluetooth设备,仅支持面向连接的 OBEX。蓝牙协议栈的RFCOMM协议可以仿效RS-232 串行端口的状态和串行电缆线设置,用于提供串行数据传输。通过提供串行端口仿真,RFCOMM 可以同时支持系统保留串行端口应用程序以及应用程序中的OBEX协议。因此,选用了基于RFCOMM的OBEX实现文件的传输。
播放器服务器端在向进入服务区内的蓝牙设备发送文件之前,需要先判断该设备是否支持OBEX协议。若发现设备支持OBEX_FILE_PUSH服务并获得其端口号,则推送客户端给用户,若没有发现响应的端口则进行下一次的推送,直到所有被发现设备全部执行结束为止,客户端推送结束。服务器对进入服务范围内的蓝牙手持设备,发送广播信息,获取设备的MAC地址。而后根据MAC地址,使用SDP协议,查询手持设备上用于支持OBEX协议传输的RFCOMM所使用的channel号。通过该channel号,服务器与手持终端建立了面向连接的传输。服务器首先使用这个链接管道向手持终端发送提示信息,如果手持终端确认接受文件下载,那么服务器向管道写入文件数据流,直至传输完毕;如果用户选择拒绝接受,服务器将与该客户断开连接,选择下一个蓝牙设备进行发送。
音乐下载功能的实现利用了文件推送模块。客户端链接管理线程收到下载音乐命令后通过OBEX协议对对应的音乐进行下载,为了实现代码的复用,对当前客户端的物理地址信息进行了标识,若搜索的设备地址信息与客户端匹配,则建立链接并发送对应的歌曲到手机客户端中。客户端推送和音乐下载过程中都用到OBEX推送。在实现的过程中首先通过系统调用fork( )建立子进程,在子进程中再通过系统调用执行/mnt/yaffs目录下的obex_test程序完成文件的具体推送。
3.客户端歌曲播放进度的实现
为了实现歌曲播放时间的动态显示,使用了java.util包下的Timer类和TimerTask类。首先通过timer = new Timer();初始化计时器对象。通过task = new ClockTask(this);初始化定时任务的对象实例。ClockTask扩展java.util包中的TimerTask类并且实现其中的run()方法,在run()方法中编写逻辑代码,ClockTask维持一个实例变量count,在每次run()运行的时候把count加1,这样就可以记录时间。为了实现暂停以及重新启动,在ClockTask中添加一个boolean类型的标记。
通过timer.schedule(task, 0, 1000); 方法设定计时开始,每经过1s调用clocktask对象的run方法更新客户端界面歌曲当前时间。由此实现了歌曲的播放时间进度显示功能。
4. 客户端接收蓝牙字符串乱码的解决
服务器通过L2CAP协议传输给客户端信息的编码方式为UNICODE,为了实现传输中文。需要将客户端接收的信息进行处理。各种编码格式如下,
UTF-8: 1-3字节可变;
UNICODE: 2字节一个字符;
GB2312: 2字节一个字符。
为了区分不同的字符,在服务器端对发送信息做了进一步的处理,在各个字符之间使用"#"进行间隔,在客户端首先将接收字符串用"#"分割。对获得的每个字符单独处理,如字符长度为4则传输数据为整型数据,通过Java中静态的处理方法,将其转换为整形,并进一步追加到返回字符串中去,若本身为字符数据,则直接追加至返回字符串,由此实现了中文信息的传输。
参考文献:
[1]博创科技.UP-NETARM2410-S Linux 嵌入式系统实验指导书[M].北京: 博创兴业科
[2]金纯、林金朝,蓝牙协议及其源代码分析. 国防工业出版社,2006年第 1 版.
[3]孙琼.嵌入式Linux应用程序开发详解.人民邮电出版社,2006.
[4]周立功等.ARM嵌入式系统基础教程.第1版.北京航空航天大学出版社.2005.
[5]高建华,王殊. 基于 S3C2410 型微处理器和 UDAl341 型立体声音频编解码器的嵌入式音频系统设计. 国外电子与元器件,2006.endprint