Bluetooth蓝牙相关知识

蓝牙(Bluetooth)是一种短距离的无线通信技术标准,蓝牙5.1最大传输距离可达300米。

1.权限

使用蓝牙时,需要相关权限(例如蓝牙开关、扫描、配对、连接等)

在AndroidManifest.xml中加入相应的权限

  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>:允许程序发现和配对蓝牙设备,该权限用于管理蓝牙设备,主要用于配对前的操作;

  <uses-permission android:name="android.permission.BLUETOOTH"/>:允许程序连接到已配对的蓝牙设备,请求连接、接收连接、传输数据需要该权限,主要用于配对后进行操作;

2.蓝牙各种状态广播监听

可以利用广播监听,进行相应处理;

常见广播如下,详情参考注释:

String ACTION_STATE_CHANGED = BluetoothAdapter.ACTION_STATE_CHANGED; //蓝牙开关状态变化

String ACTION_CONNECTION_STATE_CHANGED = BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED; //蓝牙连接状态变化

String ACTION_DISCOVERY_STARTED = BluetoothAdapter.ACTION_DISCOVERY_STARTED; //启动扫描

String ACTION_DISCOVERY_FINISHED = BluetoothAdapter.ACTION_DISCOVERY_FINISHED;//扫描结束

String ACTION_FOUND = BluetoothDevice.ACTION_FOUND;//发现设备

String ACTION_DISAPPEARED = "android.bluetooth.device.action.DISAPPEARED";//发现设备

String ACTION_NAME_CHANGED = BluetoothDevice.ACTION_NAME_CHANGED;//设备名称变化

String ACTION_CLASS_CHANGED = BluetoothDevice.ACTION_CLASS_CHANGED;//BluetoothClass变化

String ACTION_BOND_STATE_CHANGED = BluetoothDevice.ACTION_BOND_STATE_CHANGED;//配对状态变化

String ACTION_PAIRING_REQUEST = BluetoothDevice.ACTION_PAIRING_REQUEST;//配对请求

String ACTION_PAIRING_CANCEL = "android.bluetooth.device.action.PAIRING_CANCEL";//配对失败

String ACTION_UUID = BluetoothDevice.ACTION_UUID;//设备UUID变化

3.蓝牙相关API

3.1.BluetoothAdapter--蓝牙适配器

所有蓝牙设备交互的入口。通过蓝牙适配器可以对蓝牙进行基本操作,如:打开关闭蓝牙,查找设备,配对设备,获取已配对的设备等。

BluetoothAdapter.getDefaultAdapter()该静态方法获取适配器对象。

3.2.BluetoothDevice--蓝牙设备

代表一个远程蓝牙设备。通过BluetoothDevice查询设备的名称、地址、类和连接状态等信息。

3.3.BluetoothHeadset--蓝牙耳机

提供用于手机的蓝牙耳机的支持。

3.4.BluetoothProfile--蓝牙协议

代表蓝牙协议的接口。是设备间基于蓝牙通信的无线接口说明。为了保持Bluetooth设备之间的兼容,蓝牙规范中定义了Profile,Profile定义了设备如何实现一种连接或者应用。

profile的种类:GAP\SDAP\SPP\GOEP\A2DP等

A2DP:Advanced Audio Distribution Profile 高级音频分发规范。如手机的高质量音乐播放,可以传到蓝牙立体声耳机或者车载设备;A2DP主要的目的是双向传递高质量的音频流。

HSP:Headset Profile 耳机规范。最常使用的规范。用蓝牙耳机可以控制手机:接听、挂断、调节音量。

HID:Human Interface Device Profile 人机接口设备规范。如无线蓝牙鼠标

GAP:General Access Profile 基本访问规范。这个规范是其他规范的基础。定义了在Bluetooth设备间建立基带链路的通用方法。

FTP:File Transfer Profile 文件传输规范。用的次数比较多的规范。手机之间互传文件,手机与PC之间传输文件。

BPP:Basic Priting Profile 基本打印规范。如手机可以把文本、邮件、图片等发送给打印机,让打印机完成打印。

VDP:Video Distribution Profile 视频发布规范。定义了Bluetooth设备如何通过Bluetooth无线技术以流传输视频。

4.蓝牙操作过程

操作大体分成几步:打开蓝牙-->扫描蓝牙可用设备-->蓝牙配对-->蓝牙连接

4.1.开关功能

/**

* 打开蓝牙

 * return true indicate adapter startup has begun, or false on immediate error

 */

public boolean enable(){

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

adapter.enable();

}

/**

* 关闭蓝牙

 * return true indicate adapter shutdown has begun, or false on immediate error

 */

public boolean disable(){

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

adapter.disable();

}

/**

 * 获取当前蓝牙状态

 * @return {@link #STATE_ON} or {@link #STATE_TURNING_ON} or {@link #STATE_OFF} 

 * or {@link #STATE_TURNING_OFF}.

 */

public int getState(){

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

return adapter.getState();

}

4.2.扫描功能

打开蓝牙后,既可扫描蓝牙设备。

/**

 * 扫描刷新

 * 需要权限

 * <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

 * @return true on success or false on error

 */

public boolean startScan(){

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

return adapter.startDiscovery();

}

/**
 * 取消扫描搜索
 * 需要权限
 * <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 * @return
 */
public boolean cancelScan(){
	BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
	return adapter.cancelDiscovery();
}

/**
 * 需要权限
 * <uses-permission android:name="android.permission.BLUETOOTH"/>
 * @return
 */
public boolean isDiscovering(){
	BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
	return adapter.isDiscovering();
}

4.3.蓝牙规范代理功能

上面已经介绍过BluetoothProfile了,种类很多,每个profile服务不同的功能。连接蓝牙耳机的话,只需要获得HeadsetProfile既可。BluetoothHeadset继承了BluetoothProfile。

/**
 * 获取蓝牙配置规范代理
 * @param context
 * @param listener
 */
public void openProfileProxy(Context context, BluetoothProfile.ServiceListener listener, int profile){
	BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
	adapter.getProfileProxy(context, listener, profile);
    //adapter.getProfileProxy(context, mHeadsetListner, BluetoothProfile.HEADSET);
}

/**
 * 关闭蓝牙配置规范代理
 *
 */
public void closeProfileProxy(int profile, BluetoothProfile proxy){
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    adapter.closeProfileProxy(profile, proxy);
    //adapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);

}

/**
 * 监听蓝牙规范代理,获取Headset规范代理
 */
private BluetoothProfile.ServiceListener mHeadsetListner = new BluetoothProfile.ServiceListener(){
    public void onServiceConnected(int profile, BluetoothProfile proxy) {
	        BluetoothHeadset service = (BluetoothHeadset) proxy;//获取Headset规范代理
	        List<BluetoothDevice> deviceList = service.getConnectedDevices();//已经连接的设备
    }
    public void onServiceDisconnected(int profile) {
	        // TODO Auto-generated method stub    
    }
}

};

在打开蓝牙时,调用openProfileProxy获取蓝牙规范代理。关闭蓝牙时,调用closeProfileproxy关闭蓝牙配置规范代理。

4.4.配对功能

扫描到蓝牙设备后,选择蓝牙设备进行配对。配对之后,方可连接。

/**
 * 获取已配对设备
 * 需要权限
 * <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 * @return set of {@link BluetoothDevice}, or null on error.
 */
public Set<BluetoothDevice> getBondDevices(){
	BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
	return adapter.getBondedDevices();
}

/**
 * 获取目标设备的配对状态,
 * <uses-permission android:name="android.permission.BLUETOOTH"/>
 * @param targetDevice
 * @return state of {@link BluetoothDevice.BOND_BONDED}(paired), or {@link BluetoothDevice.BOND_NONE}(no paired), 
 * or {@link BluetoothDevice.BOND_BONDING}(pairing).
 */
public int getBondState(BluetoothDevice targetDevice){
	return targetDevice.getBondState();
}

/**
 * 蓝牙配对
 * 配对前,先关闭扫描,避免配对成功后发生扫描阻塞
 * <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 * @return
 */
public boolean pair(BluetoothDevice targetDevice){
	if(isDiscovering()){
		cancelScan();
	}	
	return targetDevice.createBond();
}

4.5.连接功能

选择某一个规范连接蓝牙设备,针对蓝牙耳机,选择使用BluetoothHeadset。

/**
 * 查看目标设备是否支持某个规范,返回值大于0说明支持该规范内的功能
 * <uses-permission android:name="android.permission.BLUETOOTH"/>
 * @param profile
 * @param targetDevice
 * @return priority of device
 */
public int getPriority(BluetoothProfile profile, BluetoothDevice targetDevice){	
	try {
            Method method = profile.getClass().getMethod("getPriority", 
            BluetoothDevice.class);
            return (int) method.invoke(profile, targetDevice);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
	return 0;
}

/**
 * 根据某个规范来连接
 * <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 * @param service {@link BluetoothHeadset} 
 * 			implements {@link BluetoothProfile}
 * @param targetDevice
 * @return
 */
public boolean connect(BluetoothProfile service, BluetoothDevice targetDevice){
	     try {
	            Method method = service.getClass().getMethod("connect", 
                        BluetoothDevice.class);
	            return (Boolean) method.invoke(service, targetDevice);
            } catch (Exception e) {
	            // TODO Auto-generated catch block
	            e.printStackTrace();
            } 
		return false;
}

/**
 * 根据某个规范来断开
 * <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 * @param service {@link BluetoothHeadset} implements {@link BluetoothProfile}
 * @param targetDevice
 * @return
 */
public boolean disconnect(BluetoothProfile service, BluetoothDevice targetDevice){
		try {
	            Method method = service.getClass().getMethod("disconnect", 
                      BluetoothDevice.class);
	            return (Boolean) method.invoke(service, targetDevice);
            } catch (Exception e) {
	            // TODO Auto-generated catch block
	            e.printStackTrace();
            }
		return false;
}

/**
 *	获取连接的蓝牙设备
 *
 */
public BluetoothDevice getConnectDevice(){
  List<BluetoothDevice> devices = mBluetoothHeadset.getConncetedDevices();
  if(devices != null && devices.size() > 0){
    return devices.get(0);
  }
}

5.总结

在打开蓝牙后,等待一秒左右去做扫描蓝牙设备操作,成功率高。扫描开始与结束,都会有相应的广播发出。在这个过程,存储BluetoothDevice,通过BluetoothDevice.getAddress()得到Mac地址,BluetoothDevice.getName()获得蓝牙设备名称。配对成功后,连接目标蓝牙设备。连接成功或者断开蓝牙连接设备,均能收到相应广播,在收到广播后,启动sco连接或者断开sco连接,既可以在终端和蓝牙耳机之间切换音频发声。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值