feat: 适配 Android 13,修复不安全内存问题 (#12)

This commit is contained in:
Mr剑侠客
2023-08-31 21:02:24 +08:00
committed by GitHub
parent 0f4fb7f553
commit 219bd73c33
17 changed files with 136 additions and 55 deletions

View File

@ -1,3 +1,8 @@
## 2.0.3
- `Android` Migrate to Android 13.
- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic)
## 2.0.2
- Combine iOS and macOS projects.

View File

@ -23,47 +23,47 @@ packages:
path: ".."
relative: true
source: path
version: "2.0.2"
version: "2.0.3"
bluetooth_low_energy_android:
dependency: transitive
description:
name: bluetooth_low_energy_android
sha256: "99cf2d82ea788f9f927513827f33b501a866902bbbdc20031b856fab7bcda61b"
sha256: e740179e5143c74e2f308c78d395d49054c941b95eb776884d52192b80ccfcee
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
bluetooth_low_energy_darwin:
dependency: transitive
description:
name: bluetooth_low_energy_darwin
sha256: b81cc04e04ad44063a05072ddc748e036a3f269a90af4c86b132689e66df404f
sha256: "49e9dc08281fb25f91472252dfbdf7d1d6d94983bf2e746382ad4b2dd8ba05fe"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
bluetooth_low_energy_linux:
dependency: transitive
description:
name: bluetooth_low_energy_linux
sha256: "11fc6a5f4c3d9121d2ac9b213a2f587dad2b091b7bfea648a709f0d70a909ca3"
sha256: d9576d89471e31b76cb2495dbb72aabaadc3aa093ad607f5aedb15518d5c20cb
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
bluetooth_low_energy_platform_interface:
dependency: transitive
description:
name: bluetooth_low_energy_platform_interface
sha256: "05ea2e4a802555065bda342099efec006b4d02c51806ee913fb82da90b5da60a"
sha256: dbc05f604e379ea7570db718a9ae7cf7fa08a20ee088a6f66de17b4acc7d9260
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
bluetooth_low_energy_windows:
dependency: transitive
description:
name: bluetooth_low_energy_windows
sha256: "404c704b88e516f23b5cd9bc3873f65593e868b8c6398292146ccda6e48fd335"
sha256: c4d11b2769da214b5ea20f50980c00f3c3229450e46f9d075cd64298e5a27057
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
bluez:
dependency: transitive
description:

View File

@ -1,6 +1,6 @@
name: bluetooth_low_energy
description: A Flutter plugin for controlling the bluetooth low energy.
version: 2.0.2
version: 2.0.3
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:
@ -10,11 +10,11 @@ environment:
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^2.0.2
bluetooth_low_energy_android: ^2.0.2
bluetooth_low_energy_darwin: ^2.0.2
bluetooth_low_energy_linux: ^2.0.2
bluetooth_low_energy_windows: ^2.0.2
bluetooth_low_energy_platform_interface: ^2.0.3
bluetooth_low_energy_android: ^2.0.3
bluetooth_low_energy_darwin: ^2.0.3
bluetooth_low_energy_linux: ^2.0.3
bluetooth_low_energy_windows: ^2.0.3
dev_dependencies:
flutter_test:

View File

@ -1,3 +1,8 @@
## 2.0.3
- `Android` Migrate to Android 13.
- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic)
## 2.0.2
- Combine iOS and macOS projects.

View File

@ -29,7 +29,7 @@ android {
namespace 'dev.yanshouwang.bluetooth_low_energy_android'
}
compileSdkVersion 31
compileSdkVersion 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8

View File

@ -4,6 +4,7 @@ import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import android.os.Build
import java.util.concurrent.Executor
class MyBluetoothGattCallback(private val myCentralController: MyCentralController, private val executor: Executor) : BluetoothGattCallback() {
@ -21,10 +22,22 @@ class MyBluetoothGattCallback(private val myCentralController: MyCentralControll
}
}
override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray, status: Int) {
super.onCharacteristicRead(gatt, characteristic, value, status)
executor.execute {
myCentralController.onCharacteristicRead(characteristic, status, value)
}
}
// TODO: remove this override when minSdkVersion >= 33
override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
super.onCharacteristicRead(gatt, characteristic, status)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return
}
val value = characteristic.value
executor.execute {
myCentralController.onCharacteristicRead(characteristic, status)
myCentralController.onCharacteristicRead(characteristic, status, value)
}
}
@ -35,16 +48,41 @@ class MyBluetoothGattCallback(private val myCentralController: MyCentralControll
}
}
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray) {
super.onCharacteristicChanged(gatt, characteristic, value)
executor.execute {
myCentralController.onCharacteristicChanged(characteristic)
myCentralController.onCharacteristicChanged(characteristic, value)
}
}
// TODO: remove this override when minSdkVersion >= 33
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
super.onCharacteristicChanged(gatt, characteristic)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return
}
val value = characteristic.value
executor.execute {
myCentralController.onCharacteristicChanged(characteristic, value)
}
}
override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int, value: ByteArray) {
super.onDescriptorRead(gatt, descriptor, status, value)
executor.execute {
myCentralController.onDescriptorRead(descriptor, status, value)
}
}
// TODO: remove this override when minSdkVersion >= 33
override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
super.onDescriptorRead(gatt, descriptor, status)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return
}
val value = descriptor.value
executor.execute {
myCentralController.onDescriptorRead(descriptor, status)
myCentralController.onDescriptorRead(descriptor, status, value)
}
}

View File

@ -8,6 +8,7 @@ import android.bluetooth.BluetoothGattDescriptor
import android.bluetooth.BluetoothGattService
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.bluetooth.BluetoothStatusCodes
import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
@ -41,9 +42,9 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
private val myApi = MyCentralControllerFlutterApi(binaryMessenger)
private val myRequestPermissionResultListener = MyRequestPermissionResultListener(this)
private val myReceiver = MyBroadcastReceiver(this)
private val myBroadcastReceiver = MyBroadcastReceiver(this)
private val myScanCallback = MyScanCallback(this)
private val myGattCallback = MyBluetoothGattCallback(this, executor)
private val myBluetoothGattCallback = MyBluetoothGattCallback(this, executor)
private val cachedDevices = mutableMapOf<Int, BluetoothDevice>()
private val cachedGATTs = mutableMapOf<Int, BluetoothGatt>()
@ -108,12 +109,12 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
private fun register() {
val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
context.registerReceiver(myReceiver, filter)
context.registerReceiver(myBroadcastReceiver, filter)
registered = true
}
private fun unregister() {
context.unregisterReceiver(myReceiver)
context.unregisterReceiver(myBroadcastReceiver)
registered = false
}
@ -153,9 +154,9 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
val autoConnect = false
cachedGATTs[deviceKey] = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val transport = BluetoothDevice.TRANSPORT_LE
device.connectGatt(context, autoConnect, myGattCallback, transport)
device.connectGatt(context, autoConnect, myBluetoothGattCallback, transport)
} else {
device.connectGatt(context, autoConnect, myGattCallback)
device.connectGatt(context, autoConnect, myBluetoothGattCallback)
}
connectCallbacks[deviceKey] = callback
} catch (e: Throwable) {
@ -252,9 +253,15 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
}
val myTypeArgs = myTypeNumber.toMyGattCharacteristicTypeArgs()
val writeType = myTypeArgs.toType()
val writing = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val writeCode = gatt.writeCharacteristic(characteristic, value, writeType)
writeCode == BluetoothStatusCodes.SUCCESS
} else {
// TODO: remove this when minSdkVersion >= 33
characteristic.value = value
characteristic.writeType = writeType
val writing = gatt.writeCharacteristic(characteristic)
gatt.writeCharacteristic(characteristic)
}
if (!writing) {
throw IllegalStateException()
}
@ -289,8 +296,14 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
}
val value = if (state) BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
else BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
val writing = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val writeCode = gatt.writeDescriptor(descriptor, value)
writeCode == BluetoothStatusCodes.SUCCESS
} else {
// TODO: remove this when minSdkVersion >= 33
descriptor.value = value
val writing = gatt.writeDescriptor(descriptor)
gatt.writeDescriptor(descriptor)
}
if (!writing) {
throw IllegalStateException()
}
@ -339,8 +352,14 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
if (unfinishedCallback != null) {
throw IllegalStateException()
}
val writing = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val writeCode = gatt.writeDescriptor(descriptor, value)
writeCode == BluetoothStatusCodes.SUCCESS
} else {
// TODO: remove this when minSdkVersion >= 33
descriptor.value = value
val writing = gatt.writeDescriptor(descriptor)
gatt.writeDescriptor(descriptor)
}
if (!writing) {
throw IllegalStateException()
}
@ -381,13 +400,8 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
if (action != BluetoothAdapter.ACTION_STATE_CHANGED) {
return
}
// val previousState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.STATE_OFF)
val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF)
// val myPreviousStateArgs = previousState.toMyCentralStateArgs()
val myStateArgs = state.toMyCentralStateArgs()
// if (myStateArgs == myPreviousStateArgs) {
// return
// }
val myStateNumber = myStateArgs.raw.toLong()
myApi.onStateChanged(myStateNumber) {}
}
@ -509,11 +523,10 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
}
}
fun onCharacteristicRead(characteristic: BluetoothGattCharacteristic, status: Int) {
fun onCharacteristicRead(characteristic: BluetoothGattCharacteristic, status: Int, value: ByteArray) {
val characteristicKey = characteristic.hashCode()
val callback = readCharacteristicCallbacks.remove(characteristicKey) ?: return
if (status == BluetoothGatt.GATT_SUCCESS) {
val value = characteristic.value
callback(Result.success(value))
} else {
val error = IllegalStateException("Read characteristic failed with status: $status.")
@ -532,18 +545,16 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
}
}
fun onCharacteristicChanged(characteristic: BluetoothGattCharacteristic) {
fun onCharacteristicChanged(characteristic: BluetoothGattCharacteristic, value: ByteArray) {
val characteristicKey = characteristic.hashCode()
val myCharacteristicKey = characteristicKey.toLong()
val value = characteristic.value
myApi.onCharacteristicValueChanged(myCharacteristicKey, value) {}
}
fun onDescriptorRead(descriptor: BluetoothGattDescriptor, status: Int) {
fun onDescriptorRead(descriptor: BluetoothGattDescriptor, status: Int, value: ByteArray) {
val descriptorKey = descriptor.hashCode()
val callback = readDescriptorCallbacks.remove(descriptorKey) ?: return
if (status == BluetoothGatt.GATT_SUCCESS) {
val value = descriptor.value
callback(Result.success(value))
} else {
val error = IllegalStateException("Read descriptor failed with status: $status.")

View File

@ -5,10 +5,12 @@ import android.bluetooth.le.ScanResult
class MyScanCallback(private val myCentralController: MyCentralController) : ScanCallback() {
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
myCentralController.onScanFailed(errorCode)
}
override fun onScanResult(callbackType: Int, result: ScanResult) {
super.onScanResult(callbackType, result)
myCentralController.onScanResult(result)
}
}

View File

@ -1,6 +1,6 @@
name: bluetooth_low_energy_android
description: Android implementation of the bluetooth_low_energy plugin.
version: 2.0.2
version: 2.0.3
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:
@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^2.0.2
bluetooth_low_energy_platform_interface: ^2.0.3
dev_dependencies:
flutter_test:

View File

@ -1,3 +1,8 @@
## 2.0.3
- `Android` Migrate to Android 13.
- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic)
## 2.0.2
- Combine iOS and macOS projects.

View File

@ -1,6 +1,6 @@
name: bluetooth_low_energy_darwin
description: iOS and macOS implementation of the bluetooth_low_energy plugin.
version: 2.0.2
version: 2.0.3
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:
@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^2.0.2
bluetooth_low_energy_platform_interface: ^2.0.3
dev_dependencies:
flutter_test:

View File

@ -1,3 +1,8 @@
## 2.0.3
- `Android` Migrate to Android 13.
- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic)
## 2.0.2
- Combine iOS and macOS projects.

View File

@ -1,6 +1,6 @@
name: bluetooth_low_energy_linux
description: Linux implementation of the bluetooth_low_energy plugin.
version: 2.0.2
version: 2.0.3
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:
@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^2.0.2
bluetooth_low_energy_platform_interface: ^2.0.3
bluez: ^0.8.1
dev_dependencies:

View File

@ -1,3 +1,8 @@
## 2.0.3
- `Android` Migrate to Android 13.
- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic)
## 2.0.2
- Combine iOS and macOS projects.

View File

@ -1,6 +1,6 @@
name: bluetooth_low_energy_platform_interface
description: A common platform interface for the bluetooth_low_energy plugin.
version: 2.0.2
version: 2.0.3
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:

View File

@ -1,3 +1,8 @@
## 2.0.3
- `Android` Migrate to Android 13.
- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic)
## 2.0.2
- Combine iOS and macOS projects.

View File

@ -1,6 +1,6 @@
name: bluetooth_low_energy_windows
description: Windows implementation of the bluetooth_low_energy plugin.
version: 2.0.2
version: 2.0.3
homepage: https://github.com/yanshouwang/bluetooth_low_energy
environment:
@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^2.0.2
bluetooth_low_energy_platform_interface: ^2.0.3
win32: ^5.0.6
dev_dependencies: