android studio 蓝牙透传

蓝牙透传

关于蓝牙透传,基本步骤如下:

1、设置蓝牙权限

2、打开蓝牙

3、蓝牙搜索

4、蓝牙连接与通讯

测试使用android4.4版本手机与蓝牙4.0硬件模块;

1、设置蓝牙权限(android6.0以下)

蓝牙权限在AndroidManifest.xml中加入如下代码:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

如果想要只在支持BLE的安卓设备上运行则需要再加如下:

<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/> 

2、打开蓝牙

//打开蓝牙
public void ble_open() {
    //获取蓝牙适配器实例
    BluetoothAdapter ble_adapter = BluetoothAdapter.getDefaultAdapter();
    if(ble_adapter !=null){
        //判断蓝牙是否已打开
        if (!ble_adapter.isEnabled()) {
            //打开蓝牙,强制打开,不安全
            //ble_adapter.enable();
            //弹窗询问是否打开,推荐,可以重新onActivityResult确认是否打开
            Intent ble_intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(ble_intent,0);
        }
    }else
        Toast.makeText(this, "该设备不支持蓝牙", Toast.LENGTH_SHORT).show();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 0){
        switch (resultCode){
            case RESULT_OK:
                //蓝牙打开成功
                break;
            case RESULT_CANCELED:
                //蓝牙打开失败
                break;
        }
    }
}

3、蓝牙搜索

搜索蓝牙设备有三种方法:

1、startLeScan(LeScanCallback)此方法适用于4.3以上版本,扫描结果通过实现BluetoothAdapter.LeScanCallback接口方法onLeScan来接收

2、此外startScan(ScanCallbackcallback)适用于5.0以上;

3、ble_adapter.startDiscovery()虽然说是兼容经典蓝牙和低功耗蓝牙,但有些设备无法检测到低功耗蓝牙;startDiscovery是一个异步方法,其过程:系统发送BluetoothAdapter.ACTIOINDISCOVERYSTARTED的广播 ,然后搜到一个蓝牙设备就发送一个BluetoothDevice.ACTIONFOUND的广播,结束发送BluetoothAdapter.ACTIONFINISHED的广播,整个过程耗时12s,这也说明搜索结果需要注册一个广播来接收;

public void ble_scan(View view) {
    //判断是否处于扫描状态
    if (isScan)
        return;
    //扫描时间设为10s
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            ble_adapter.stopLeScan(MainActivity.this);
            isScan = false;
        }
    }, 10000);
    //开始扫描
    if (ble_adapter.isEnabled()) {
        ble_adapter.startLeScan(this);
        isScan = true;
        text_list.setVisibility(View.VISIBLE);
    }
}   
/**
 * 返回扫描结果的回调
 * @param device     蓝牙信息相关类,可以获取蓝牙名称,地址,绑定状态等
 * @param rssi       蓝牙设备信号值,正常为负值,值越大信号越强
 * @param scanRecord 远程设备提供的配对号
 */
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
    if (device.getName().equals(ble_name)) {
        BleDevice bleDevice = new BleDevice(device, rssi, false);
        if (!ble_list.contains(bleDevice))
            ble_list.add(bleDevice);
        sendMSG(FIND_BLE_DEVICE);
        ble_adapter.stopLeScan(this);
    }
}

4、蓝牙连接与通讯

//连接设备
public void ble_connect(String address, final int position) {
    BluetoothDevice device = ble_adapter.getRemoteDevice(address);
    ble_gatt = device.connectGatt(this, true, new BluetoothGattCallback() {
        //连接状态改变回调
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                ble_list.get(position).setConnect(true);
                sendMSG(CONNECT_SUCCESS);
                //连接成功,开始搜索服务,一定要调用此方法,否则获取不到服务
                gatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                ble_list.get(position).setConnect(false);
                sendMSG(CONNECT_FAILED);
                ble_gatt.close();
            }
        }

        //发现服务时,调用回调,表示可以通信了
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            UUID service_UUID = Constants.CX21_SERVICE_UUID;
            UUID characteristic_UUID = Constants.CX21_CHARACTERISTIC_UUID;
            //通过UUID找到服务
            ble_GattService = gatt.getService(service_UUID);
            //找到服务后在通过UUID找到特征
            ble_Characteristic = ble_GattService.getCharacteristic(characteristic_UUID);
            if (ble_Characteristic != null) {
                //启用onCharacteristicChanged(),用于接收数据
                Boolean isTrue = gatt.setCharacteristicNotification(ble_Characteristic, true);
                BluetoothGattDescriptor descriptor = ble_Characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                gatt.writeDescriptor(descriptor);
                sendMSG(SERVICE_DISCOVERED);
            } else {
                sendMSG(SERVICE_DISCOVERED_FAILED);
                return;
            }
        }

        //由于远程特征通知而触发的回调
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            //使用的蓝牙设备发送的是16进制,需要处理,否则会乱码
            receive = bytesToHexString(characteristic.getValue());
            sendMSG(RECEIVE_MSG);
        }

        //写入成功的回调
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            if (BluetoothGatt.GATT_SUCCESS == status) {
                sendMSG(WRITE_SUCCESS);
            }
        }

        //读取成功回调
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if (BluetoothGatt.GATT_SUCCESS == status) {
            String receive = "";
            for (int i = 0; i < characteristic.getValue().length; i++) {
                int v = characteristic.getValue()[i] & 0xFF;
                receive += Integer.toHexString(v);
            }
            Log.e("connect", "read:" + receive);
    }
}
    });
}

1)、向蓝牙模块写数据如下:

String writeData = "00801001015A";
ble_Characteristic.setValue(getHexBytes(writeData));
gatt.writeCharacteristic(ble_Characteristic);

如果写入成功会回调onCharacteristicWrite方法;

2)、读数据:

gatt.readCharacteristic(ble_Characteristic);

如果读取成功,可以在onCharacteristicRead中获取到数据;


版权声明:本文为qq_38757742原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。