Need BLUETOOTH PRIVILEGED permission以及requestMtu導致藍牙斷連問題
在部分Android手機上,當連接上GATTService后直接requestMtu有可能會造成藍牙連接中斷,隨后繼續重新連接會報錯Need BLUETOOTH PRIVILEGED permission
1 //掃描成功后連接gatt 2 BluetoothDevice mRemoteDevice = mBluetoothAdapter.getRemoteDevice(result.getDevice().getAddress()); 3 BluetoothGatt mBluetoothGatt = mRemoteDevice.connectGatt(getContext(), false, bluetoothGattCallback);
在 BluetoothGattCallback 監聽的 onConnectionStateChange(BluetoothGatt gatt, int status, int newState)方法中直接requestMtu(512) 會直接導致藍牙斷開連接
1 private int setMTUInt = 512; 2 3 4 @Override 5 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 6 super.onConnectionStateChange(gatt, status, newState); 7 8 if (newState == BluetoothProfile.STATE_CONNECTED) { //// 連接成功 9 //雖然這里的boolean會為true但是實際上會失敗,并且導致藍牙斷開鏈接 10 boolean requestMtu = gatt.requestMtu(setMTUInt); 11 Log.e(TAG,"設置 requestMtu:"+requestMtu); 12 13 } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // 連接斷開 14 //清除緩存,防止Need BLUETOOTH PRIVILEGED permission 15 refreshDeviceCache(); 16 //將MTU的值減少,值可以隨意設置 17 setMTUInt -= 100; 18 // 關閉GATT客戶端 19 mBluetoothGatt.close(); 20 } 21 }
在監聽的onMtuChanged(BluetoothGatt gatt, int mtu, int status)方法中,確認mtu設置成功后,再去請求特征值
1 @Override 2 public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { 3 super.onMtuChanged(gatt, mtu, status); 4 5 // 開始查找GATT服務器提供的服務 6 gatt.discoverServices(); 7 8 }
隨后在監聽的onServicesDiscovered(BluetoothGatt gatt, int status)方法中設置特征
@Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if (status == BluetoothGatt.GATT_SUCCESS) { //設置特征值 requestCharacteristic(); } }
清除緩存的方法,gatt本身有提供清除緩存方法,但是不給外部直接調用,所以使用反射的方式進行調用,建議在每次開啟掃描設備時也清除一下緩存,防止鏈接過其他設備后直接鏈接新設備報錯 java.lang.SecurityException: Need BLUETOOTH PRIVILEGED permission: Neither user 10208 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
1 public boolean refreshDeviceCache() { 2 if (mBluetoothGatt != null) { 3 Log.e(TAG,"清除緩存 refreshDeviceCache"); 4 try { 5 BluetoothGatt localBluetoothGatt = mBluetoothGatt; 6 Method localMethod = localBluetoothGatt.getClass().getMethod( 7 "refresh", new Class[0]); 8 if (localMethod != null) { 9 boolean bool = ((Boolean) localMethod.invoke( 10 localBluetoothGatt, new Object[0])).booleanValue(); 11 return bool; 12 } 13 } catch (Exception localException) { 14 Log.i(TAG, "An exception occured while refreshing device"); 15 } 16 } 17 return false; 18 }

浙公網安備 33010602011771號