Android 蓝牙开发之A2DP基本功能
本文主要是Android做为Audio Source端,A2DP的基本操作:包括连接、断开连接、设置优先级、获取优先级、获取A2DP连接状态、获取A2DP连接的设备列表等功能。
1.简介
Audio Source(音频源) 音频的输入端对音频数据进行编码,发送到Sink端。 A2DP全名是Advanced Audio Distribution Profile,高质量音频数据传输的协议,其定义里了传送单声道或立体声等高质量音频(区别于蓝牙SCO链路上传输的普通语音)信息的协议和过程。A2DP的典型应用是将音乐播放器的音频数据发送到耳机或音箱。
A2DP定义了两种角色:
Audio Source(音频源) 音频的输入端对音频数据进行编码,发送到Sink端。
Audio Sink(音频接收器) 接收到音频数据后,进行解码操作还原出音频。
2.A2DP profile
要想操作A2DP相关,首先要获取A2DP代理对象,获取代理对象的方法比较简单,如下:
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
if(!mBtAdapter.isEnabled()){
//弹出对话框提示用户是后打开
Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler, 1);
}
//获取A2DP代理对象
mBtAdapter.getProfileProxy(mContext, mListener, BluetoothProfile.A2DP);
getProfileProxy并不会直接返回A2DP代理对象,而是通过mListener中回调获取。
private ServiceListener mListener = new ServiceListener() {
@Override
public void onServiceDisconnected(int profile) {
if(profile == BluetoothProfile.A2DP){
mA2dp = null;
}
}
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if(profile == BluetoothProfile.A2DP){
mA2dp = (BluetoothA2dp) proxy; //转换
}
}
};
成功会回调mListener中的onServiceConnected函数,判断proflie是否为BluetoothProfile.A2DP,转换为BluetoothA2dp对象。通过代理对象即可进行A2DP的相关操作了
3.A2DP操作
A2DP连接首先需要与蓝牙耳机进行配对,如何配对这里就不细说了。
我这里是连接到之前配对过的一个设备。设备名称为:
private final String BT_NAME = "QCY-QY7";
获取该设备,首先获取配对的蓝牙设备,然后遍历这些蓝牙设备,找出蓝牙名称符合条件的设备,就是要操作的设备,
//获取配对的蓝牙设备
Set<BluetoothDevice> bondDevice = mBtAdapter.getBondedDevices();
for(BluetoothDevice device:bondDevice){
//获取指定名称的设备
if(BT_NAME.equals(device.getName())){
mConnectDevice = device;
}
}
mConnectDevice为要操作的设备。
3.1 A2DP连接
private void connectA2dp(BluetoothDevice device){
setPriority(mConnectDevice, 100); //设置priority
try {
//通过反射获取BluetoothA2dp中connect方法(hide的),进行连接。
Method connectMethod =BluetoothA2dp.class.getMethod("connect",
BluetoothDevice.class);
connectMethod.invoke(mA2dp, device);
} catch (Exception e) {
e.printStackTrace();
}
}
BluetoothA2dp中的connect方法是hide的,不能直接访问,需要通过反射的机制获取该方法进行连接。连接成功后手机可以播放音乐,声音就会从蓝牙耳机出来。
3.2 断开连接
private void disConnectA2dp(BluetoothDevice device){
setPriority(mConnectDevice, 0);
try {
//通过反射获取BluetoothA2dp中connect方法(hide的),断开连接。
Method connectMethod =BluetoothA2dp.class.getMethod("disconnect",
BluetoothDevice.class);
connectMethod.invoke(mA2dp, device);
} catch (Exception e) {
e.printStackTrace();
}
}
BluetoothA2dp中的disconnect方法也是hide的,与connect类似.
3.3 设置优先级
设置优先级是必要的,否则可能导致连接或断开连接失败等问题。
public void setPriority(BluetoothDevice device, int priority) {
if (mA2dp == null) return;
try {//通过反射获取BluetoothA2dp中setPriority方法(hide的),设置优先级
Method connectMethod =BluetoothA2dp.class.getMethod("setPriority",
BluetoothDevice.class,int.class);
connectMethod.invoke(mA2dp, device, priority);
} catch (Exception e) {
e.printStackTrace();
}
}
3.4 获取优先级
public int getPriority(BluetoothDevice device) {
int priority = 0;
if (mA2dp == null) return priority;
try {//通过反射获取BluetoothA2dp中getPriority方法(hide的),获取优先级
Method connectMethod =BluetoothA2dp.class.getMethod("getPriority",
BluetoothDevice.class);
priority = (Integer) connectMethod.invoke(mA2dp, device);
} catch (Exception e) {
e.printStackTrace();
}
return priority;
}
3.5 获取与某设备A2DP连接状态
mA2dp.getConnectionState(device);
3.6 获取连接设备列表
//返回值类型List<BluetoothDevice>
mA2dp.getConnectedDevices();
3.7 A2DP是否正在发送音频流
//返回值类型boolean,表示设备是否在通过A2DP发送音频流。
mA2dp.isA2dpPlaying(device);
4.状态监听
通过广播接收者监听A2DP连接状态的改变,A2DP播放状态的改变。
private void initReceiver(){
//注册广播接收者监听状态改变
IntentFilter filter = new IntentFilter(BluetoothA2dp.
ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
registerReceiver(mReceiver, filter);
}
广播接收者,通过intent获取状态值。
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i(TAG,"onReceive action="+action);
//A2DP连接状态改变
if(action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)){
int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED);
Log.i(TAG,"connect state="+state);
}else if(action.equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)){
//A2DP播放状态改变
int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING);
Log.i(TAG,"play state="+state);
}
}
};
连接小demo:http://download.csdn.net/detail/vnanyesheshou/9841491
转载出处:http://blog.csdn.net/vnanyesheshou/article/details/71713786
Android 蓝牙开发之A2DP基本功能的更多相关文章
- Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
前言: 为了加快开发效率,目前公司一些功能使用H5开发,这里难免会用到Js与Java函数互相调用的问题,这个Android是提供了原生支持的,不过存在安全隐患,今天我们来学习一种安全方式来满足Js与j ...
- Android混合开发之WebView与Javascript交互
前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...
- Android安全开发之WebView中的地雷
Android安全开发之WebView中的地雷 0X01 About WebView 在Android开发中,经常会使用WebView来实现WEB页面的展示,在Activiry中启动自己的浏览器,或者 ...
- Android混合开发之WebView使用总结
前言: 今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结. 混合开发相关博客: Android混合开发之WebView使用总结 Android混合开 ...
- Android安全开发之ZIP文件目录遍历
1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在“../”的字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接s ...
- Android驱动开发之Hello实例
Android驱动开发之Hello实例: 驱动部分 modified: kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_defconf ...
- android软件开发之webView.addJavascriptInterface循环渐进【二】
本篇文章由:http://www.sollyu.com/android-software-development-webview-addjavascriptinterface-cycle-of-gra ...
- android软件开发之webView.addJavascriptInterface循环渐进【一】
本篇文章由:http://www.sollyu.com/android-software-development-webview-addjavascriptinterface-cycle-of-gra ...
- Android NDK开发之C调用Java及原生代码断点调试(二)
上一篇中,我们主要学习了Java调用本地方法,并列举了两大特殊实例来例证我们的论据,还没学习的伙伴必须先去阅读下,本次的学习是直接在上一篇的基础上进行了.点击:Android NDK开发之从Java与 ...
随机推荐
- PowerShell 获取系统的硬件信息
1.获取系统的BIOS的信息: Get-WMIObject -Class Win32_BIOS 2.获取内存信息: Get-WMIObject -Class Win32_PhysicalMemory ...
- JavaScript的基础学习(一)
一.JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase ...
- Shiro过滤器的维护与匹配执行
servlet的初始化会触发核心过滤器的创建: public Object getObject() throws Exception { if (instance == null) { instanc ...
- 洛谷——P2708 硬币翻转
P2708 硬币翻转 题目背景 难度系数:☆☆☆☆☆(如果你看懂了) 题目描述 从前有很多个硬币摆在一行,有正面朝上的,也有背面朝上的.正面朝上的用1表示,背面朝上的用0表示.现在要求从这行的第一个硬 ...
- 洛谷——P1609 最小回文数
题目描述 回文数是从左向右读和从右向左读结果一样的数字串. 例如:121.44 和3是回文数,175和36不是. 对于一个给定的N,请你寻找一个回文数P,满足P>N. 满足这样条件的回文数很多, ...
- Xamarin.Forms教程下载安装JDK配置环境变量
Xamarin.Forms教程下载安装JDK配置环境变量 Xamarin.Form环境配置下载安装JDK JDK是编程Java程序必须的软件.也许有人会问我们用的C#为什么还有Java呢?这是因为我们 ...
- FlowPortal BPM官网改版了,推出20个流程免费基础版
我一直使用的FlowPortal BPM官网网站近期改版了,看起来更加高大上了.不仅美感提高了,所传递的信息,特别是新老用户所需要的信息也更多了. 对于新版网站,我觉得比较赞的地方: 1.新增开发者中 ...
- [BZOJ3167][P4099][HEOI2013]SAO(树形DP)
题目描述 Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...
- hdu 4055 Number String (基础dp)
Number String Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 【计算几何】【凸包】Gym - 101164H - Pub crawl
平面上n个点,点之间沿直线走,规划一条路线,每次只能往左半平面的点走,走过最多的点. 显然所有的点都能走过. n^2的暴力显然是每次找左边与其所形成夹角最小的点,但这样过不了(卡常数?). 或者每轮不 ...