几天以来,我尝试在我的APP中实现BLE连接。我知道我尝试连接的设备功能齐全,所以问题一定出在我的代码上。
我使用BluetoothLeScanner.startScan()
方法。
但是永远不会调用回调方法。
public void startScan() {
if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
isScanning = true;
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mainActivityHandler.setMSG("Scan stopped");
isScanning = false;
leScanner.stopScan(scanCallback);
}
}, SCAN_TIME);
mainActivityHandler.setMSG("Start scan");
try {
leScanner.startScan(scanCallback);
} catch (Exception e) {
mainActivityHandler.catchError(e);
}
} else mainActivityHandler.catchError(new Exception("Bluetooth not activated"));
}
我的CallbackMethod(不知道我是否正确使用了gatt,但这是另一个问题):
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onBatchScanResults(List<ScanResult> results) {
mainActivityHandler.setMSG("Callback");
isScanning = false;
try {
mainActivityHandler.setMSG("Connected to " + results.get(0).getDevice().getName());
gatt = results.get(0).getDevice().connectGatt(mainActivity, true, bluetoothGattCallback);
BluetoothGattDescriptor descriptor;
for (int i = 0; i < charIDs.length; i++) {
gatt.setCharacteristicNotification(gatt.getService(serviceID[0]).getCharacteristic(charIDs[i]), true);
descriptor = gatt.getService(serviceID[0]).getCharacteristic(charIDs[0]).getDescriptor(charIDs[i]);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
}
} catch (Exception e) {
mainActivityHandler.catchError(e);
}
}
};
答案 0 :(得分:2)
问题在于您仅覆盖onBatchScanResults
方法,而不覆盖onScanResult
方法。 onBatchScanResults
仅在以下情况下触发:
ScanSettings
将ScanSettings.SCAN_MODE_LOW_POWER
模式设置为ScanSettings.Builder
(这是默认设置)。setReportDelay(long reportDelayMillis)
中的ScanSettings.Builder
将报告延迟时间设置为大于0的某个值。reportDelayMillis -报告延迟(以毫秒为单位)。设置为0可立即通知结果。值> 0会使扫描结果排队,并在请求的延迟后或内部缓冲区填满时传递。
例如:
public void startScan(BluetoothLeScanner scanner) {
ScanFilter filter = new ScanFilter.Builder().setDeviceName(null).build();
ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>();
filters.add(filter);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.setReportDelay(1l)
.build();
Log.i(TAG,"The setting are "+settings.getReportDelayMillis());
scanner.startScan(filters,settings,BLEScan);
}
但是,您可能只想一次获得一次结果,而不是一批结果。为此,您无需修改ScanSettings,只需要在onScanResult
中覆盖ScanCallback
方法即可。
private ScanCallback mScanCallback =
new ScanCallback() {
public void onScanResult(int callbackType, ScanResult result) {
System.out.println(result.getDevice().getName())
// Do whatever you want
};
...
};
无论如何,我强烈建议您使用库RxAndroidBle。它的维护非常好,可以立即解决许多BLE问题(扫描可能是BLE中不太复杂的部分)。
使用该库,可以像这样进行扫描:
Disposable scanSubscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder()
// .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // change if needed
// .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // change if needed
.build()
// add filters if needed
)
.subscribe(
scanResult -> {
// Process scan result here.
},
throwable -> {
// Handle an error here.
}
);
// When done, just dispose.
scanSubscription.dispose();
答案 1 :(得分:0)
清单:
您是否启用了该位置,请确保已为Api 23之后的设备专门启用了该位置。此外,还有一个免费的应用nrfconnect(我使用过的东西),请下载该文件并查看它是否可以检测到设备。
这也是我用过的
private void startScan() {
try {
if (!hasPermissions() || mScanning) {
return;
}
List<ScanFilter> filters = new ArrayList<>();
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
mScanResults = new ArrayList<>();
mScanCallback = new DeviceScanCallback();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
handleProgress(true, getString(R.string.lbl_scanning));
mBluetoothLeScanner.startScan(filters, settings, mScanCallback);
mScanning = true;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (activity == null || !isAdded()) {
return;
}
if (getResources() != null) {
handleProgress(false, getResources().getString(R.string.lbl_scanning));
stopScan();
}
}
}, 20000);
} catch (Exception e) {
Toast.makeText(activity, getString(R.string.scan_failed), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
//使用回调的类
private class DeviceScanCallback extends ScanCallback {
@Override
public void onScanResult(int callbackType, ScanResult result) {
try {
if (result != null && result.getScanRecord() != null && result.getScanRecord().getDeviceName() != null) {
Log.d("Device name", "" + result.getScanRecord().getDeviceName());
if (result.getScanRecord().getDeviceName().startsWith(ConstantClass.DEVICE_IDENTIFIER)) {
addScanResult(result);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
try {
for (ScanResult result : results) {
Log.i("ScanResult - Results", result.toString() + " " + result.getDevice().getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e(TAG, "BLE Scan Failed with code " + errorCode);
}
private void addScanResult(ScanResult result) {
try {
BluetoothDevice device = result.getDevice();
if (mScanResults != null) {
mScanResults.add(device);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}