[Asm] 纯文本查看 复制代码/**
* 查找低功耗蓝牙,该方法在4.3(API 18)以上,无法查找“传统蓝牙”
*
* @param scanInterval 扫描时长,单位:秒
* @param bluetoothAdapter
* @param btScanCallback 扫描结果回调
*/
public static void findBluetoothLE(int scanInterval, final BluetoothAdapter bluetoothAdapter, final BtScanCallback btScanCallback) {
try {
if (DeviceUtils.getInstance(context).checkPermission("android.permission.BLUETOOTH")
&& DeviceUtils.getInstance(context).checkPermission("android.permission.BLUETOOTH_ADMIN")) {
if (!bluetoothAdapter.isEnabled()) {
// 若蓝牙未打开,直接返回
btScanCallback.onScan(new ArrayList>());
return;
}
if (mScanning) {
// 正在扫描中,直接返回
btScanCallback.onScan(new ArrayList>());
return;
}
// 默认扫描6秒,若scanInterval不合法,则使用默认值
final int defaultInterval = 6;
if (scanInterval <= 0) {
scanInterval = defaultInterval;
}
// 4.3的低功耗蓝牙API
if (Build.VERSION.SDK_INT >= 18) {
final ArrayList> scanResult = new ArrayList<>();
// 5.0又引入了新的蓝牙API(4.3版本的API仍然可用)
if (Build.VERSION.SDK_INT < 21) {
// 定义扫描结果回调
final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
/**
*
* @param device 扫描到的设备实例,可从实例中获取到相应的信息。如:名称,mac地址
* @param rssi 可理解成设备的信号值。该数值是一个负数,越大则信号越强
* @param scanRecord 远程设备提供的广播数据的内容
*/
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
HashMap map = parseBtDevice2Map(device);
map.put("rssi", rssi);
//map.put("scanRecord", Data.byteToHex(scanRecord));
scanResult.add(map);
}
};
// 开始扫描
mScanning = true;
bluetoothAdapter.startLeScan(leScanCallback);
// 设置一段时间后停止扫描
Handler handler = HandlerThread.newHandler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
mScanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
btScanCallback.onScan(scanResult);
return false;
}
});
handler.sendEmptyMessageDelayed(0, scanInterval * 1000);
} else {
// 定义扫描结果回调
final ScanCallback mScanCallback = new ScanCallback() {
//当一个蓝牙ble广播被发现时回调
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.d(TAG, "onScanResult: " + result.getDevice().getAddress() + ", " + result.getDevice().getName());
super.onScanResult(callbackType, result);
//扫描类型有开始扫描时传入的ScanSettings相关
//对扫描到的设备进行操作。如:获取设备信息。
if (result != null) {
HashMap map = new HashMap<>();
BluetoothDevice device = result.getDevice();
if (device != null) {
map = parseBtDevice2Map(device);
}
map.put("rssi", result.getRssi());
ScanRecord scanRecord = result.getScanRecord();
scanResult.add(map);
}
}
// 批量返回扫描结果。一般蓝牙设备对象都是通过onScanResult(int,ScanResult)返回,
// 而不会在onBatchScanResults(List)方法中返回,除非手机支持批量扫描模式并且开启了批量扫描模式。
// 批处理的开启请查看ScanSettings。
//@param results 以前扫描到的扫描结果列表。
@Override
public void onBatchScanResults(List results) {
super.onBatchScanResults(results);
Log.d(TAG, "onBatchScanResults");
}
//当扫描不能开启时回调
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
//扫描太频繁会返回ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED,表示app无法注册,无法开始扫描。
Log.d(TAG, "onScanFailed. errorCode: " + errorCode);
}
};
//开始扫描
final BluetoothLeScanner mBLEScanner = bluetoothAdapter.getBluetoothLeScanner();
mScanning = true;
/** 也可指定过滤条件和扫描配置
//创建ScanSettings的build对象用于设置参数
ScanSettings.Builder builder = new ScanSettings.Builder()
//设置高功耗模式
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
//android 6.0添加设置回调类型、匹配模式等
if(android.os.Build.VERSION.SDK_INT >= 23) {
//定义回调类型
builder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
//设置蓝牙LE扫描滤波器硬件匹配的匹配模式
builder.setMatchMode(ScanSettings.MATCH_MODE_STICKY);
}
// 若设备支持批处理扫描,可以选择使用批处理,但此时扫描结果仅触发onBatchScanResults()
//if (bluetoothAdapter.isOffloadedScanBatchingSupported()) {
设置蓝牙LE扫描的报告延迟的时间(以毫秒为单位)
设置为0以立即通知结果
//builder.setReportDelay(0L);
//}
ScanSettings scanSettings = builder.build();
//可设置过滤条件,在第一个参数传入,但一般不设置过滤。
mBLEScanner.startScan(null, scanSettings, mScanCallback);
*/
mBLEScanner.startScan(mScanCallback);
// 设置一段时间后停止扫描
Handler handler = HandlerThread.newHandler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
mScanning = false;
mBLEScanner.stopScan((mScanCallback));
btScanCallback.onScan(scanResult);
return false;
}
});
handler.sendEmptyMessageDelayed(0, scanInterval * 1000);
}
} else {
findBluetoothLEAndClassic(scanInterval, bluetoothAdapter, btScanCallback);
}
} else {
// 缺少权限,直接返回
btScanCallback.onScan(new ArrayList>());
}
} catch (Throwable t) {
t.printStackTrace();
btScanCallback.onScan(new ArrayList>());
}
}