权限,权限,权限!重要事情说三遍!Android6.0以上,蓝牙扫描需要开启蓝牙的相关权限还有 定位权限
1.扫描
Android 8.0 使用下面的方法扫描,会发现扫描出来的设备和系统扫描出来的不一样,还拿不到蓝牙设备的名称
@deprecated
BluetoothAdapter.startLeScan(BluetoothAdapter.LeScanCallback callback);
解决办法是Android 8.0使用新的api —startDiscovery
//使用startDiscovery,在黑屏的情况下也可以进行扫描
BluetoothAdapter.startDiscovery();
使用startDiscovery()方法需要注册广播监听扫描状态,和获取扫描结果,直接看代码吧
private ScanBroadcastReceiver scanBroadcastReceiver;
/**
* 使用新api扫描
* 注册蓝牙扫描监听
*/
public void registerScanBroadcast() {
Application application = App.getApp();
//注册蓝牙扫描状态广播接收者
if (scanBroadcastReceiver == null && application != null) {
scanBroadcastReceiver = new ScanBroadcastReceiver();
IntentFilter filter = new IntentFilter();
//开始扫描
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//扫描结束
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//扫描中,返回结果
filter.addAction(BluetoothDevice.ACTION_FOUND);
//扫描模式改变
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
//注册广播接收监听,用完不要忘了解注册哦
application.registerReceiver(scanBroadcastReceiver, filter);
}
}
//监听扫描广播
private class ScanBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("BluetoothScan","intent="+intent.toString());
String action = intent.getAction();
if (action != null) {
switch (action) {
case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
Log.d("BluetoothScan","扫描模式改变");
break;
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.d("BluetoothScan","扫描开始");
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.d("BluetoothScan","扫描结束");
break;
case BluetoothDevice.ACTION_FOUND:
Log.d("BluetoothScan","发现设备");
//获取蓝牙设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null && null != device.getName()) {
int rssi = -120;
Bundle extras = intent.getExtras();
String lv = "";
if (extras != null) {
//获取信号强度
rssi = extras.getShort(BluetoothDevice.EXTRA_RSSI);
}
Log.d("BluetoothScan", "rssi=" + rssi + " name=" + device.getName() +
" address=" + device.getAddress() + " lv=" + lv);
}
break;
}
}
}
}
2.配对
拿到了蓝牙设备,下面开始进行配对吧,下面以配对蓝牙耳机为例,进行配对。如果是手机,配对完还得进行连接,其他蓝牙设备有些直接连接即可,具体自己慢慢去发掘吧
老样子上代码
private ConnectBroadcastReceiver connectBroadcastReceiver;
/**
* 监听配对状态
*/
public synchronized void registerConnectBroadcast() {
Application application = App.getApp();
//注册蓝牙开关状态广播接收者
if (connectBroadcastReceiver == null && application != null) {
connectBroadcastReceiver = new ConnectBroadcastReceiver();
IntentFilter filter = new IntentFilter();
//已连接
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
//连接断开
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
//配对状态改变
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//配对请求,也就系统弹窗提示是否进行配对
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
application.registerReceiver(connectBroadcastReceiver, filter);
}
}
private class ConnectBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("BluetoothConnect","intent="+intent.toString());
String action = intent.getAction();
if (action != null) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (action) {
case BluetoothDevice.ACTION_ACL_CONNECTED:{
Log.d("BluetoothConnect","已连接");
break;
}
case BluetoothDevice.ACTION_ACL_DISCONNECTED:{
Log.d("BluetoothConnect","断开连接");
break;
}
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
Log.d("BluetoothConnect","配对状态改变");
if (device != null) {
if(device.getBondState() == BluetoothDevice.BOND_NONE){
Log.d("BluetoothConnect","配对失败");
}
else if(device.getBondState() == BluetoothDevice.BOND_BONDING){
Log.d("BluetoothConnect","配对中");
}
else if(device.getBondState() == BluetoothDevice.BOND_BONDED){
Log.d("BluetoothConnect","配对成功");
}
}
break;
case BluetoothDevice.ACTION_PAIRING_REQUEST:{
//配对的验证码,如果是-1侧不需要验证码
int key = intent.getExtras().getInt(BluetoothDevice.EXTRA_PAIRING_KEY,-1);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
try {
//1.确认配对
boolean success = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if(key != -1){
success = device.setPin(String.valueOf(key).getBytes());
}else {
//需要系统权限,如果没有系统权限,就点击弹窗上的按钮配对吧
success = device.setPairingConfirmation(true);
}
}
Log.d("BluetoothConnect","key="+key+" bond="+success);
//如果没有将广播终止,则会出现一个一闪而过的配对框。
abortBroadcast();
} catch (Exception e) {
Log.e("BluetoothConnect","反射异常:"+e);
}
}
break;
}
}
}
}
}
3.取消配对
//通过反射,调用removeBond方法取消配对
public boolean removeBond(Class btClass, BluetoothDevice btDevice) throws Exception {
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
//调用
removeBond(BluetoothDevice.getClass(), BluetoothDevice);
列子源码
https://gitee.com/asdfung/test-ble
参考
感谢大佬们无私分享
https://blog.csdn.net/qq_30710673/article/details/79816168
https://www.jianshu.com/p/795bb0a08beb
比较好用的蓝牙库FastBle,不过使用的是旧的扫描api,github地址:https://github.com/Jasonchenlijian/FastBle