将数据写入Android

时间:2016-03-22 19:56:55

标签: android bluetooth bluetooth-lowenergy

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

  1. 我扫描并连接到'PEN_ADDRESS`指定的设备。
  2. 在`onServicesDiscovered`方法中,我寻找一个'UUID`包含`abcd`的服务。
  3. 然后我循环了这些服务的特性,并在他们的`UUID`中寻找具有特定字符串的三个特征。
  4. 第三个特性是一个可写特性,我试图通过调用方法`writeCharac(mGatt,writeChar1,123)来写数据。 上面传递的数据“123”只是一个虚拟数据。
  5. 我在尝试写入此特性时调试了我的代码,但是在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);
            }
    
        };
    

3 个答案:

答案 0 :(得分:5)

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

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

所以只需等待writeDescriptor回调,然后再调用writeCharacteristic。这种性质没有详细记录,但您可以找到一些来源herehere

答案 1 :(得分:0)

感谢@reTs和@pooja的建议。问题是由于这两条线     mGatt = null {
{1}}
在STATE_DISCONNECTED中。我已经弄明白了,但不记得确切的原因。发布它以防它有用。

答案 2 :(得分:-3)

您是否检查了&#39; writechar1&#39;你传递给writeCharac()的btcharacteristic值是什么?