在Android程序中可以实现自动扫描蓝牙、配对蓝牙、建立数据通道。
蓝牙分不同类型,可以参考(http://gqdy365.iteye.com/admin/blogs/2229304)
可以入下面方法获取蓝牙设备支持的类型:
BluetoothDevice device;
Arrays.toString(device.getUuids());
我的蓝牙音箱支持的类型有:
0000111e-0000-1000-8000-00805f9b34fb:Handsfree
0000110b-0000-1000-8000-00805f9b34fb:AudioSink
0000110e-0000-1000-8000-00805f9b34fb:AVRemoteControl
00001203-0000-1000-8000-00805f9b34fb:GenericFileTransfer
这篇文字只讨论如何与蓝牙耳机(蓝牙音箱)连接。
蓝牙耳机一般都支持A2DP(蓝牙立体声,用于音乐播放)、HFP协议(通话),参考:http://gqdy365.iteye.com/admin/blogs/2231553
所以下面操作要同时操作A2DP和HFP,两个都连接成功,才算连接成功;
一、A2DP的操作可以分三步:
1、扫描蓝牙设备:
注册并监听广播:
BluetoothAdapter.ACTION_DISCOVERY_STARTED
BluetoothDevice.ACTION_FOUND
BluetoothAdapter.ACTION_DISCOVERY_FINISHED
启动扫描:
BluetoothAdapter.getDefaultAdapter().startDiscovery();
对扫描的结果按类型进行筛选,只保留我们需要的蓝牙耳机:
if(device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET
|| device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE){
//蓝牙耳机
}
2、配对指定的蓝牙设备:
这个跟配对普通蓝牙一样,方法如下:
public static boolean createBond(BluetoothDevice btDevice){
boolean result = false;
try{
Method m = btDevice.getClass().getDeclaredMethod("createBond",new Class[]{});
m.setAccessible(true);
Boolean originalResult = (Boolean) m.invoke(btDevice);
result = originalResult.booleanValue();
}catch(Exception ex){
}
return result;
}
等配对完成之后就是要建立数据连接;
3、建立数据连接:
if you SDK between 11 and 16.call a2dp.connectSink(btDevice) or a2dp.connect(btDevice)
private static IBluetoothA2dp getIBluetoothA2dp() {
IBluetoothA2dp ibta = null;
try {
final Class serviceManager = Class.forName("android.os.ServiceManager");
final Method getService = serviceManager.getDeclaredMethod("getService", String.class);
final IBinder iBinder = (IBinder) getService.invoke(null, "bluetooth_a2dp");
final Class iBluetoothA2dp = Class.forName("android.bluetooth.IBluetoothA2dp");
final Class[] declaredClasses = iBluetoothA2dp.getDeclaredClasses();
final Class c = declaredClasses[0];
final Method asInterface = c.getDeclaredMethod("asInterface", IBinder.class);
asInterface.setAccessible(true);
ibta = (IBluetoothA2dp) asInterface.invoke(null, iBinder);
} catch (final Exception e) {
Log.e("Error " + e.getMessage());
}
return ibta;
}
参考:http://stackoverflow.com/questions/8467178/working-around-a2dp-and-hfp-limitations-of-android-pre-honeycomb
如果API大于16需要用如下的方法:
private void initA2dpService(){
// Intent i = getExplicitIntent(mContext,new Intent(IBluetoothA2dp.class.getName()));//5.0以上系统需要显示intent
//详细参考http://blog.csdn.net/l2show/article/details/47421961
Intent i = new Intent(IBluetoothA2dp.class.getName());
boolean success = mContext.bindService(i, mConnection, Context.BIND_AUTO_CREATE);
if (success) {
} else {
}
}
public ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
try {
mA2dpService = IBluetoothA2dp.Stub.asInterface(service);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
public Intent getExplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
建立连接:mA2dpService.connect(device);
断开连接:mA2dpService.disconnect(device);
参考:http://stackoverflow.com/questions/14705167/how-connect-paired-bluetooth-a2dp-device-on-android-4-2-using-reflection
http://blog.csdn.net/qs_csu/article/details/45114251
二、HFP操作:
下面只针对4.0及以上版本;
1、初始化:
private void initOrCloseBtCheck(boolean init){
if(init){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.getProfileProxy(mContext, new ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
},BluetoothProfile.HEADSET);
}else{
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET,mBluetoothHeadset);
}
}
建立连接:
Method m = mBluetoothHeadset.getClass().getDeclaredMethod("connect",BluetoothDevice.class);
m.setAccessible(true);
//连接Headset
boolean successHeadset = (Boolean)m.invoke(mBluetoothHeadset, device);
断开连接:
Method m = mBluetoothHeadset.getClass().getDeclaredMethod("disconnect",BluetoothDevice.class);
m.setAccessible(true);
m.invoke(mBluetoothHeadset, device);
三、状态判断:
蓝牙耳机连接成功:
mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_DISCONNECTED && mBluetoothHeadset.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED
断开成功:
(mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_CONNECTED || mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_PLAYING)
&& mBluetoothHeadset.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED
分享到:
相关推荐
Android平台下,对普通耳机以及蓝牙耳机插拔状态的监控,代码中有做蓝牙耳机SCO通话建立
Android蓝牙无线对讲demo(手机连接蓝牙耳机后可通过蓝牙耳机实时对讲,音量可调)。记得手机要先连接蓝牙耳机,才能通过蓝牙耳机对讲。
Android例子源码有蓝牙耳机功能的蓝牙例子
Android与蓝牙耳机建立连接的一些代码,希望能起到抛砖引玉的效果,大家一起学习
app连接蓝牙模块2.0进行互相通讯,使用androidstudio编写,页面相对简单,但是功能完善,蓝牙必须先配对再在app中连接
android 蓝牙 耳机 开发
Android手机连接蓝牙打印机实现打印功能。适用于所有蓝牙打印机。代码可以直接使用。
手机链接蓝牙耳机状态测试 告诉你手机是不是连接到蓝牙耳机了 自己做的时候要看java文件最上面的提示
android安卓切换听筒-外放-蓝牙耳机设备
此demo是用来开启蓝牙耳机的Sco模式,进而行录音,然后保存到手机sd卡中的。
NULL 博文链接:https://zht19880706.iteye.com/blog/1671002
通过蓝牙功能与设备进行连接以及获取设备传输过来的数据
android连接蓝牙打印机,实现搜索连接,自定义输入打印内容
java实现电脑和Android蓝牙连接源代码
项目地址:android实现蓝牙聊天功能 1、程序简单的界面 2、客户端,主动连接 package com.bluetooth.tool; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import ...
android 蓝牙hid协议开发,实现手机连接蓝牙鼠标、键盘、扫描枪.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
程序实现功能:开启、关闭、连接蓝牙,SCAN周围蓝牙并获得蓝牙名字,地址,信号强度RSSI,连接状态,因为当时是为了做一个蓝牙定位,所以按照需求还添加了一个是否是自己买的蓝牙基站的Textview。 当判断SCAN到的...
Android开发蓝牙耳机按键监听(蓝牙监听应用测试)demo-(手机连接蓝牙耳机后可通过蓝牙音量键远程控制手机执行操作)
Android 蓝牙HFP 连接、SCO连接流程图(协议栈),非常详细的从btif-bta-btm-hci 数据流程走向,以及从controller收到数据到btm层,将Android 源码使用流程图的形式画了出来,使Android 蓝牙开发者更清楚数据收发...