java android开发,小计一个断开BLE连接的方式

一、断开连接的调用方法

  • android.bluetooth.BluetoothGatt.disconnect()  断开连接
  • android.bluetooth.BluetoothGatt.close()  释放连接资源

二、源码分析

  • android.bluetooth.BluetoothGatt.disconnect()的源码分析
private IBluetoothGatt mService;//对象中的属性

BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device,
                                int transport) {
        mContext = context;
        mService = iGatt; //创建对象的时候,将gatt对象赋值给mService
        mDevice = device;
        mTransport = transport;
        mServices = new ArrayList<BluetoothGattService>();

        mConnState = CONN_STATE_IDLE;
}

public void disconnect() {
        if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return;

        try {
            mService.clientDisconnect(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
        }
}
  • android.bluetooth.BluetoothGatt.close()的源码分析
public void close() {
        if (DBG) Log.d(TAG, "close()");

        unregisterApp();
        mConnState = CONN_STATE_CLOSED;
}

private void unregisterApp() {
        if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
        if (mService == null || mClientIf == 0) return;

        try {
            mCallback = null;
            mService.unregisterClient(mClientIf);
            mClientIf = 0;
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
        }
}

三、断开连接小计

  • 网上看到的大部分处理方式

监听页面的生命周期,再页面需要执行销毁处理,判断gatt连接对象是否存在,如果存在,则同时调用上述的两种方式进行关闭连接操作处理。

但这样处理有个问题:

看上述的两段源码,close其实算得上是将callback置空处理,有点类似GC机制,如果同时使用,则在disconnect操作后,会触发android.bluetooth.BluetoothGattCallback().onConnectionStateChange(BluetoothGatt, int, int)的处理监听(这个是异步的,毕竟蓝牙底层处理需要时间),如果在调用disconnect后直接调用close(),将百分百出现空指针问题,切断开操作不够优雅!

  • 自己的处理方式

检测连接是否真正的断开,函数封装

public int getConnectedState() {
		int state = 100;
		if (lock_bluetoothManager != null && (lock_mac != null | lock_mac == "") && mBluetoothAdapter != null
				&& mBluetoothAdapter.isEnabled()) {
			BluetoothDevice bdevice = mBluetoothAdapter.getRemoteDevice(lock_mac);
			// 蓝牙连接状态为0,1,2,3 为了避免出问题初始化为100
			/**
			 * STATE_DISCONNECTED 0 STATE_CONNECTING 1 STATE_CONNECTED 2 STATE_DISCONNECTING
			 * 3
			 */
			state = lock_bluetoothManager.getConnectionState(bdevice, BluetoothProfile.GATT);
		}
		Log.i("getConnectedState()方法调用,返回数据为-->", String.valueOf(state));
		return state;
	}

具体断开操作思路: 

  1. 在需要断开连接的地方,调用  mBluetoothGatt.disconnect(); 进行尝试断开处理操作;
  2. 等待 onConnectionStateChange(BluetoothGatt, int, int) 状态监听函数的触发;
  3. 为了避免信号的变化导致的连接不稳定,需要对连接失败做一个处理,getConntectState();
  4. 在连接状态回调处,进行判断
  5. if (newState == BluetoothProfile.STATE_DISCONNECTED) {// 连接失败 或者连接断开都会调用此方法
    				Log.i("连接回调-->", "getConnectedState()");
    				if (getConnectedState() == BluetoothProfile.STATE_CONNECTED) {
    					Log.i("onConnectionStateChange-->", "连接伪失败");
    					return;
    				}
    				Log.i("onConnectionStateChange-->", "连接失败");
    				Message message = new Message();
    				message.what = CONNECT_FAIL;
    				AppSendMesg(message);
    }

    在CONNECT_FAIL中实现处理(此时的状态是真正的断开了连接了),此时需要对连接对象进行资源释放操作

  6. if(mBluetoothGatt != null) {
    	//释放资源
    	mBluetoothGatt.close();
    }

     

  7.  

 

以下是 Android 测试手机与智能血压计 BLE 蓝牙扫描、连接、认证、断开的代码示例,供参考: 首先,在 Manifest 中添加以下权限: ```xml <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> ``` 然后,在代码中实现 BLE 相关功能: ```java private BluetoothAdapter mBluetoothAdapter; private BluetoothLeScanner mBluetoothLeScanner; private ScanCallback mScanCallback; private BluetoothGatt mBluetoothGatt; // 初始化 BLE 相关对象 private void initBluetooth() { // 获取蓝牙适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 获取蓝牙扫描器 mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); } // 扫描 BLE 设备 private void startScan() { // 构建扫描过滤器 ScanFilter scanFilter = new ScanFilter.Builder() .setDeviceName("BloodPressure") // 设置设备名称 .setServiceUuid(ParcelUuid.fromString("00001810-0000-1000-8000-00805f9b34fb")) // 设置服务 UUID .build(); // 构建扫描设置 ScanSettings scanSettings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // 设置扫描模式 .build(); // 构建扫描回调 mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); // 获取设备地址 String deviceAddress = result.getDevice().getAddress(); // 停止扫描 stopScan(); // 连接设备 connectDevice(deviceAddress); } }; // 开始扫描 mBluetoothLeScanner.startScan(Collections.singletonList(scanFilter), scanSettings, mScanCallback); } // 停止扫描 BLE 设备 private void stopScan() { mBluetoothLeScanner.stopScan(mScanCallback); } // 连接 BLE 设备 private void connectDevice(String deviceAddress) { // 获取设备对象 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress); // 连接设备 mBluetoothGatt = device.connectGatt(this, false, mGattCallback); } // GATT 回调 private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED) { // 连接成功,开始认证 gatt.discoverServices(); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // 断开连接 gatt.close(); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if (status == BluetoothGatt.GATT_SUCCESS) { // 获取服务对象 BluetoothGattService service = gatt.getService(UUID.fromString("00001810-0000-1000-8000-00805f9b34fb")); if (service != null) { // 获取特征对象 BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("00002a35-0000-1000-8000-00805f9b34fb")); if (characteristic != null) { // 设置特征通知 gatt.setCharacteristicNotification(characteristic, true); // 获取描述对象 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); if (descriptor != null) { // 设置描述通知 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(descriptor); } } } } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); // 处理数据 byte[] data = characteristic.getValue(); } @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { super.onDescriptorWrite(gatt, descriptor, status); // 认证成功,开始接收数据 if (status == BluetoothGatt.GATT_SUCCESS) { // 发送认证指令 byte[] authCommand = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; BluetoothGattService service = gatt.getService(UUID.fromString("00001810-0000-1000-8000-00805f9b34fb")); if (service != null) { BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("00002a35-0000-1000-8000-00805f9b34fb")); if (characteristic != null) { characteristic.setValue(authCommand); gatt.writeCharacteristic(characteristic); } } } } }; // 断开 BLE 设备连接 private void disconnectDevice() { if (mBluetoothGatt != null) { mBluetoothGatt.disconnect(); } } ``` 以上代码实现了 BLE 设备的扫描、连接、认证和断开连接功能。其中,扫描时需要设置设备名称和服务 UUID,连接后需要发起服务发现、设置特征通知和描述通知,认证时需要发送认证指令,数据接收操作在 `onCharacteristicChanged` 方法中进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值