gpt4 book ai didi

android - 将数据写入 Android 中的蓝牙 LE 特性

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:02:05 24 4
gpt4 key购买 nike

虽然也有人问过类似的问题,但还是略有不同。我知道如何将数据传递到连接的 BLE 设备,但我认为我做错了什么需要帮助。下面的代码包含我的类中扩展 BroadcastReceiver 的所有方法。

  1. 我扫描并连接到“PEN_ADDRESS”指定的设备。
  2. 在 `onServicesDiscovered` 方法中,我寻找其 `UUID` 包含 `abcd` 的服务。
  3. 然后我遍历此服务的特征,并在其 `UUID` 中查找具有特定字符串的三个特征。
  4. 第三个特征是可写特征,我尝试通过调用方法 `writeCharac(mGatt,writeChar1,123); 来写入数据上面传递的数据“123”只是一个虚拟数据。

我在尝试写入此特性时调试了我的代码,但是在 writeCharac 方法中放置断点时,我发现 status 值为 false,表明写入是不成功。我在这里错过了什么吗?请帮忙!

public class BackgroundReceiverFire extends BroadcastReceiver {
Context context;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mGatt;
private BluetoothLeService mBluetoothLeService;
private boolean mScanning;
private final String TAG = "READING: ";
private BluetoothDevice mDevice;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
private final String PEN_ADDRESS = "FB:23:AF:42:5C:56";
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;

public void onReceive(Context context, Intent intent) {
this.context = context;
Toast.makeText(context, "Started Scanning", LENGTH_SHORT).show();
initializeBluetooth();
startScan();
}

private void initializeBluetooth() {
mHandler = new Handler();

// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();

// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this.context, "No Bluetooth", LENGTH_SHORT).show();
return;
}
}

private void startScan() {
scanLeDevice(true);
}

private void stopScan() {
scanLeDevice(false);
}

private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);

mScanning = true;
//Scanning for the device
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}

private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getAddress().matches(PEN_ADDRESS)) {
connectBluetooth(device);
Toast.makeText(context, "Device Found: " + device.getAddress(), Toast.LENGTH_LONG).show();

}
}
};

private void connectBluetooth(BluetoothDevice insulinPen) {
if (mGatt == null) {
Log.d("connectToDevice", "connecting to device: " + insulinPen.toString());
mDevice = insulinPen;
mGatt = insulinPen.connectGatt(context, true, gattCallback);
scanLeDevice(false);// will stop after first device detection
}
}

private void enableBluetooth() {
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
scanLeDevice(true);
}

private void disableBluetooth() {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
}

private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {


@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "STATE_DISCONNECTED");
Log.i("gattCallback", "reconnecting...");
BluetoothDevice mDevice = gatt.getDevice();
mGatt = null;
connectBluetooth(mDevice);
break;
default:
Log.e("gattCallback", "STATE_OTHER");
break;
}

}

public void onServicesDiscovered(BluetoothGatt gatt, int status) {
mGatt = gatt;
List<BluetoothGattService> services = mGatt.getServices();
Log.i("onServicesDiscovered", services.toString());
Iterator<BluetoothGattService> serviceIterator = services.iterator();
while(serviceIterator.hasNext()){
BluetoothGattService bleService = serviceIterator.next();
if(bleService.getUuid().toString().contains("abcd")){
//Toast.makeText(context,"Got the service",Toast.LENGTH_SHORT);
BluetoothGattCharacteristic readChar1 = bleService.getCharacteristics().get(0);
for (BluetoothGattDescriptor descriptor : readChar1.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(readChar1, true);
}
//mGatt.readCharacteristic(readChar1);

BluetoothGattCharacteristic readChar2 = bleService.getCharacteristics().get(1);
for (BluetoothGattDescriptor descriptor : readChar2.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(readChar2, true);
}
//mGatt.readCharacteristic(readChar2);

BluetoothGattCharacteristic writeChar1 = bleService.getCharacteristics().get(2);
for (BluetoothGattDescriptor descriptor : writeChar1.getDescriptors()) {
descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(writeChar1, true);
}
writeCharac(mGatt,writeChar1,123);
}
}

//gatt.readCharacteristic(therm_char);

}
public void writeCharac(BluetoothGatt gatt, BluetoothGattCharacteristic charac, int value ){
if (mBluetoothAdapter == null || gatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*
BluetoothGattCharacteristic charac = gattService
.getCharacteristic(uuid);
*/
if (charac == null) {
Log.e(TAG, "char not found!");
}

int unixTime = value;
String unixTimeString = Integer.toHexString(unixTime);
byte[] byteArray = hexStringToByteArray(unixTimeString);
charac.setValue(byteArray);
boolean status = mGatt.writeCharacteristic(charac);
if(status){
Toast.makeText(context,"Written Successfully",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"Error writing characteristic",Toast.LENGTH_SHORT).show();
}
}

public byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len/2];

for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}

return data;
}

public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
Log.i("onCharacteristicRead", characteristic.toString());
String characteristicValue = characteristic.getValue().toString();
Log.d("CHARACTERISTIC VALUE: ", characteristicValue);
gatt.disconnect();
}

public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic) {
String value = characteristic.getValue().toString();
Log.d(TAG,value);
}

};

最佳答案

虽然BLE API本质上是异步的,但实际的信号传输必然是同步的。在开始任何连接/写入/读取操作之前,您必须等待先前的连接/写入/读取调用回调。

在您的代码 onServicesDiscovered(BluetoothGatt gatt, int status) 函数中,您在尝试写入特性之前调用了两次 mGatt.writeDescriptor(descriptor)。 API 将拒绝启动您的写入请求,因为它正忙于写入描述符,并为您的 mGatt.writeCharacteristic(charac) 调用返回 false。

所以在调用writeCharacteristic之前等待writeDescriptor回调即可。这种性质没有很好的记录,但您可以找到一些来源 herehere .

关于android - 将数据写入 Android 中的蓝牙 LE 特性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36163998/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com