From 817c01bf80fd1757f60e1aa8d02be3667b8bf897 Mon Sep 17 00:00:00 2001 From: fdp <1286779656@qq.com> Date: Wed, 4 Jun 2025 15:56:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5ota=E5=8D=87=E7=BA=A7demo?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcshareddata/swiftpm/Package.resolved | 213 --- lib/data/services/network/nw_api.dart | 3 +- .../controllers/ota_upgrade_controller.dart | 7 +- .../azure_speech/AzureAsrHelper.kt | 87 +- .../yunqiinnovation/ble_service/BleService.kt | 2 +- local_plugins/ota/.gitignore | 33 + local_plugins/ota/.metadata | 33 + local_plugins/ota/CHANGELOG.md | 3 + local_plugins/ota/LICENSE | 1 + local_plugins/ota/README.md | 15 + local_plugins/ota/analysis_options.yaml | 4 + local_plugins/ota/android/.gitignore | 9 + local_plugins/ota/android/build.gradle | 68 + .../android/libs/jl_bt_ota_V1.9.2-release.aar | Bin 0 -> 247632 bytes local_plugins/ota/android/settings.gradle | 1 + .../ota/android/src/main/AndroidManifest.xml | 4 + .../com/example/ota/DeviceConnection.kt | 26 + .../main/kotlin/com/example/ota/OtaPlugin.kt | 148 ++ .../ota/tool/bluetooth/BTEventCbHelper.kt | 91 ++ .../ota/tool/bluetooth/BluetoothHelper.kt | 204 +++ .../ota/tool/bluetooth/CallbackImpl.kt | 12 + .../ota/tool/bluetooth/CallbackRunnable.kt | 23 + .../ota/tool/bluetooth/OnBTEventCallback.kt | 38 + .../example/ota/tool/bluetooth/OtaConstant.kt | 54 + .../example/ota/tool/config/ConfigHelper.kt | 187 +++ .../com/example/ota/tool/ota/OTAManager.kt | 149 ++ .../tool/ota/ble/BleEventCallbackManager.java | 175 +++ .../example/ota/tool/ota/ble/BleManager.java | 1194 +++++++++++++++++ .../ota/tool/ota/ble/SendBleDataThread.java | 295 ++++ .../ota/ble/interfaces/BleEventCallback.java | 68 + .../ota/ble/interfaces/IBleEventCallback.java | 108 ++ .../ota/tool/ota/ble/interfaces/IBleOp.java | 16 + .../ble/interfaces/OnThreadStateListener.java | 14 + .../ble/interfaces/OnWriteDataCallback.java | 25 + .../ota/tool/ota/ble/model/BleDevice.java | 155 +++ .../ota/tool/ota/ble/model/BleScanInfo.java | 99 ++ local_plugins/ota/ios/.gitignore | 38 + local_plugins/ota/ios/Assets/.gitkeep | 0 local_plugins/ota/ios/Classes/OtaPlugin.swift | 19 + .../ota/ios/Resources/PrivacyInfo.xcprivacy | 14 + local_plugins/ota/ios/ota.podspec | 29 + local_plugins/ota/lib/ota.dart | 19 + local_plugins/ota/lib/ota_method_channel.dart | 34 + .../ota/lib/ota_platform_interface.dart | 41 + local_plugins/ota/pubspec.yaml | 72 + pubspec.yaml | 3 +- 46 files changed, 3613 insertions(+), 220 deletions(-) delete mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 local_plugins/ota/.gitignore create mode 100644 local_plugins/ota/.metadata create mode 100644 local_plugins/ota/CHANGELOG.md create mode 100644 local_plugins/ota/LICENSE create mode 100644 local_plugins/ota/README.md create mode 100644 local_plugins/ota/analysis_options.yaml create mode 100644 local_plugins/ota/android/.gitignore create mode 100644 local_plugins/ota/android/build.gradle create mode 100644 local_plugins/ota/android/libs/jl_bt_ota_V1.9.2-release.aar create mode 100644 local_plugins/ota/android/settings.gradle create mode 100644 local_plugins/ota/android/src/main/AndroidManifest.xml create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/DeviceConnection.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BTEventCbHelper.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BluetoothHelper.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackImpl.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackRunnable.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OnBTEventCallback.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OtaConstant.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/config/ConfigHelper.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/OTAManager.kt create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleEventCallbackManager.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleManager.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/SendBleDataThread.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/BleEventCallback.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleEventCallback.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleOp.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnThreadStateListener.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnWriteDataCallback.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleDevice.java create mode 100644 local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleScanInfo.java create mode 100644 local_plugins/ota/ios/.gitignore create mode 100644 local_plugins/ota/ios/Assets/.gitkeep create mode 100644 local_plugins/ota/ios/Classes/OtaPlugin.swift create mode 100644 local_plugins/ota/ios/Resources/PrivacyInfo.xcprivacy create mode 100644 local_plugins/ota/ios/ota.podspec create mode 100644 local_plugins/ota/lib/ota.dart create mode 100644 local_plugins/ota/lib/ota_method_channel.dart create mode 100644 local_plugins/ota/lib/ota_platform_interface.dart create mode 100644 local_plugins/ota/pubspec.yaml diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 3deebfc3a..000000000 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,213 +0,0 @@ -{ - "originHash" : "fb7ecff82f4ff109531189491cc6cc2299a7357c61874f58bae1e0f7b7d9e8d0", - "pins" : [ - { - "identity" : "abseil-cpp-binary", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/abseil-cpp-binary.git", - "state" : { - "revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5", - "version" : "1.2024072200.0" - } - }, - { - "identity" : "app-check", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/app-check.git", - "state" : { - "revision" : "61b85103a1aeed8218f17c794687781505fbbef5", - "version" : "11.2.0" - } - }, - { - "identity" : "appauth-ios", - "kind" : "remoteSourceControl", - "location" : "https://github.com/openid/AppAuth-iOS.git", - "state" : { - "revision" : "2781038865a80e2c425a1da12cc1327bcd56501f", - "version" : "1.7.6" - } - }, - { - "identity" : "dkcamera", - "kind" : "remoteSourceControl", - "location" : "https://github.com/zhangao0086/DKCamera", - "state" : { - "branch" : "master", - "revision" : "5c691d11014b910aff69f960475d70e65d9dcc96" - } - }, - { - "identity" : "dkimagepickercontroller", - "kind" : "remoteSourceControl", - "location" : "https://github.com/zhangao0086/DKImagePickerController", - "state" : { - "branch" : "4.3.9", - "revision" : "0bdfeacefa308545adde07bef86e349186335915" - } - }, - { - "identity" : "dkphotogallery", - "kind" : "remoteSourceControl", - "location" : "https://github.com/zhangao0086/DKPhotoGallery", - "state" : { - "branch" : "master", - "revision" : "311c1bc7a94f1538f82773a79c84374b12a2ef3d" - } - }, - { - "identity" : "firebase-ios-sdk", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/firebase-ios-sdk", - "state" : { - "revision" : "3663b1aa6c7a1bed67ee80fd09dc6d0f9c3bb660", - "version" : "11.13.0" - } - }, - { - "identity" : "flutterfire", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/flutterfire", - "state" : { - "revision" : "a80a123386fd4904cad6938673020a7bcf31b2f2", - "version" : "3.13.0-firebase-core-swift" - } - }, - { - "identity" : "googleappmeasurement", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleAppMeasurement.git", - "state" : { - "revision" : "543071966b3fb6613a2fc5c6e7112d1e998184a7", - "version" : "11.13.0" - } - }, - { - "identity" : "googledatatransport", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleDataTransport.git", - "state" : { - "revision" : "617af071af9aa1d6a091d59a202910ac482128f9", - "version" : "10.1.0" - } - }, - { - "identity" : "googlesignin-ios", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleSignIn-iOS.git", - "state" : { - "revision" : "a7965d134c5d3567026c523e0a8a583f73b62b0d", - "version" : "7.1.0" - } - }, - { - "identity" : "googleutilities", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleUtilities.git", - "state" : { - "revision" : "60da361632d0de02786f709bdc0c4df340f7613e", - "version" : "8.1.0" - } - }, - { - "identity" : "grpc-binary", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/grpc-binary.git", - "state" : { - "revision" : "cc0001a0cf963aa40501d9c2b181e7fc9fd8ec71", - "version" : "1.69.0" - } - }, - { - "identity" : "gtm-session-fetcher", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/gtm-session-fetcher.git", - "state" : { - "revision" : "a2ab612cb980066ee56d90d60d8462992c07f24b", - "version" : "3.5.0" - } - }, - { - "identity" : "gtmappauth", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GTMAppAuth.git", - "state" : { - "revision" : "5d7d66f647400952b1758b230e019b07c0b4b22a", - "version" : "4.1.1" - } - }, - { - "identity" : "interop-ios-for-google-sdks", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/interop-ios-for-google-sdks.git", - "state" : { - "revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe", - "version" : "101.0.0" - } - }, - { - "identity" : "leveldb", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/leveldb.git", - "state" : { - "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", - "version" : "1.22.5" - } - }, - { - "identity" : "nanopb", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/nanopb.git", - "state" : { - "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", - "version" : "2.30910.0" - } - }, - { - "identity" : "promises", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/promises.git", - "state" : { - "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", - "version" : "2.4.0" - } - }, - { - "identity" : "sdwebimage", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SDWebImage/SDWebImage", - "state" : { - "revision" : "cac9a55a3ae92478a2c95042dcc8d9695d2129ca", - "version" : "5.21.0" - } - }, - { - "identity" : "swift-protobuf", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-protobuf.git", - "state" : { - "revision" : "d72aed98f8253ec1aa9ea1141e28150f408cf17f", - "version" : "1.29.0" - } - }, - { - "identity" : "swiftygif", - "kind" : "remoteSourceControl", - "location" : "https://github.com/kirualex/SwiftyGif.git", - "state" : { - "revision" : "4430cbc148baa3907651d40562d96325426f409a", - "version" : "5.4.5" - } - }, - { - "identity" : "tocropviewcontroller", - "kind" : "remoteSourceControl", - "location" : "https://github.com/TimOliver/TOCropViewController", - "state" : { - "revision" : "a634cb7cdfd580006e79a6e74e64417fe9e9783b", - "version" : "2.7.4" - } - } - ], - "version" : 3 -} diff --git a/lib/data/services/network/nw_api.dart b/lib/data/services/network/nw_api.dart index c5ed95dd8..94d7115f8 100644 --- a/lib/data/services/network/nw_api.dart +++ b/lib/data/services/network/nw_api.dart @@ -1,6 +1,5 @@ class NWApi { // static const baseApi = "https://www.deapsound.com"; - //测试服务器链接地址,经常修改变动,开发使用 static const baseApi = "https://api.deapsound.com"; - // static const baseApi = "https://api.ideapsound.com"; + //static const baseApi = "https://api.ideapsound.com"; } diff --git a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart index 992ca6838..c9c827551 100644 --- a/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart +++ b/lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart @@ -8,6 +8,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:path_provider/path_provider.dart'; import 'package:jl_ota/jl_ota.dart'; +import 'package:ota/ota.dart'; import '../../../data/services/ble_manager.dart'; class OtaUpgradeController extends GetxController { @@ -22,7 +23,7 @@ class OtaUpgradeController extends GetxController { final isUpdateAvailable = true.obs; final RxDouble progress = 0.0.obs; - final JlOta jla = JlOta(); + var jlota = Ota(); // 蓝牙服务 final _bleManager = Get.find(); @override @@ -54,6 +55,7 @@ class OtaUpgradeController extends GetxController { Future _getCurrentVersion() async { try { + jlota.getPlatformVersion(); // 添加获取设备信息的重试机制 DeviceInfo? deviceInfo = _bleManager.deviceInfo.value; @@ -292,7 +294,8 @@ class OtaUpgradeController extends GetxController { // 开始升级 void _installApp(String path) async { - jla.getPlatformVersion(); + jlota.searchDevices(); + jlota.startUpgrade(); // JlOtaPlugin() // final File file = File(path); // if (await file.exists()) { diff --git a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt index abbe6e38a..4ed987ea4 100644 --- a/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt +++ b/local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureAsrHelper.kt @@ -24,6 +24,10 @@ import com.microsoft.cognitiveservices.speech.audio.AudioStreamFormat import java.util.concurrent.BlockingQueue import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.TimeUnit + +import java.io.File +import java.io.FileOutputStream +import java.io.RandomAccessFile /** * Azure语音识别辅助类,支持麦克风和外部音频源的单次和连续语音识别 * @@ -528,7 +532,12 @@ class AzureAsrHelper(private val context: Context) { private inner class MicrophoneStream : PullAudioInputStreamCallback() { private var audioRecord: AudioRecord? = null private var echoCanceler: AcousticEchoCanceler? = null - + private var currentAudioFile: File? = null + private var fos: FileOutputStream? = null + + // 用于存储音频数据的缓冲区 + private val dataBuffer = mutableListOf() + private var totalBytesWritten = 0 // 音频配置 private val sampleRate = 16000 private val channelConfig = AudioFormat.CHANNEL_IN_MONO @@ -546,6 +555,20 @@ class AzureAsrHelper(private val context: Context) { */ private fun initMicrophone() { try { + // 创建新的音频文件 + val timestamp = System.currentTimeMillis() + val filePath = context.getExternalFilesDir(null)?.absolutePath + "/recorded_audio_$timestamp.wav" + currentAudioFile = File(filePath) + currentAudioFile?.createNewFile() + + // 仅写入初始文件头 + fos = FileOutputStream(currentAudioFile).apply { + write(generateWavHeader(0)) // 初始0长度 + close() + } + + // 追加音频数据到文件 + fos = FileOutputStream(currentAudioFile, true) // 创建录音对象 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { val format = AudioFormat.Builder() @@ -616,18 +639,80 @@ class AzureAsrHelper(private val context: Context) { Log.e(tag, "读取音频数据失败: $result") return 0 } + // 将音频数据保存成wav格式的音频文件 + saveAudioDataToWav(buffer, result) return result } catch (e: Exception) { Log.e(tag, "读取音频异常: ${e.message}") return 0 } } + /** + * 保存音频数据到 WAV 文件 + */ +private fun saveAudioDataToWav(buffer: ByteArray, length: Int) { + // 复制数据到新数组 + val copy = ByteArray(length) + System.arraycopy(buffer, 0, copy, 0, length) + + // 添加到缓冲区 + dataBuffer.add(copy) + totalBytesWritten += length + + // 写入文件 + try { + fos?.write(copy, 0, length) + } catch (e: Exception) { + Log.e(tag, "写入音频数据失败: ${e.message}") + } +} + + // 更新文件头生成(修正RIFF长度计算) + private fun generateWavHeader(dataLength: Int): ByteArray { + val totalLength = 36 + dataLength // RIFF块总长度 = 头部36字节 + 音频数据 + val byteRate = sampleRate * 2 * 1 // 采样率 * 字节/样本 * 通道数 + return byteArrayOf( + 'R'.code.toByte(), 'I'.code.toByte(), 'F'.code.toByte(), 'F'.code.toByte(), + (totalLength and 0xFF).toByte(), ((totalLength shr 8) and 0xFF).toByte(), + ((totalLength shr 16) and 0xFF).toByte(), ((totalLength shr 24) and 0xFF).toByte(), + 'W'.code.toByte(), 'A'.code.toByte(), 'V'.code.toByte(), 'E'.code.toByte(), + 'f'.code.toByte(), 'm'.code.toByte(), 't'.code.toByte(), ' '.code.toByte(), + 16, 0, 0, 0, // PCM头长度 + 1, 0, // PCM格式 + 1, 0, // 单声道 + (sampleRate and 0xFF).toByte(), ((sampleRate shr 8) and 0xFF).toByte(), 0, 0, // 采样率 + (byteRate and 0xFF).toByte(), ((byteRate shr 8) and 0xFF).toByte(), 0, 0, // 字节率 + 2, 0, // 块对齐 (通道数 * 样本位数/8) + 16, 0, // 样本位数 + 'd'.code.toByte(), 'a'.code.toByte(), 't'.code.toByte(), 'a'.code.toByte(), + (dataLength and 0xFF).toByte(), ((dataLength shr 8) and 0xFF).toByte(), + ((dataLength shr 16) and 0xFF).toByte(), ((dataLength shr 24) and 0xFF).toByte() + ) + } /** * 关闭音频资源 */ override fun close() { releaseAudioResources() + try { + // 关闭文件流 + fos?.close() + + // 更新WAV文件头 + currentAudioFile?.let { file -> + RandomAccessFile(file, "rw").use { raf -> + raf.seek(0) + raf.write(generateWavHeader(totalBytesWritten)) + } + Log.d(tag, "音频文件保存完成: ${file.absolutePath}") + } + } catch (e: Exception) { + Log.e(tag, "更新WAV文件头失败: ${e.message}") + } finally { + fos = null + currentAudioFile = null + } } /** diff --git a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt index 999d56c3a..7ca013ed9 100644 --- a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt +++ b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt @@ -80,7 +80,7 @@ object BleService { private var bluetoothLeScanner: BluetoothLeScanner? = null // GATT连接相关 - private var bluetoothGatt: BluetoothGatt? = null + var bluetoothGatt: BluetoothGatt? = null private var notifyChar: BluetoothGattCharacteristic? = null private var writeChar: BluetoothGattCharacteristic? = null private var audioChar: BluetoothGattCharacteristic? = null diff --git a/local_plugins/ota/.gitignore b/local_plugins/ota/.gitignore new file mode 100644 index 000000000..e7d347d9d --- /dev/null +++ b/local_plugins/ota/.gitignore @@ -0,0 +1,33 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +build/ diff --git a/local_plugins/ota/.metadata b/local_plugins/ota/.metadata new file mode 100644 index 000000000..6015b831a --- /dev/null +++ b/local_plugins/ota/.metadata @@ -0,0 +1,33 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "ea121f8859e4b13e47a8f845e4586164519588bc" + channel: "stable" + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc + - platform: android + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc + - platform: ios + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/local_plugins/ota/CHANGELOG.md b/local_plugins/ota/CHANGELOG.md new file mode 100644 index 000000000..41cc7d819 --- /dev/null +++ b/local_plugins/ota/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/local_plugins/ota/LICENSE b/local_plugins/ota/LICENSE new file mode 100644 index 000000000..ba75c69f7 --- /dev/null +++ b/local_plugins/ota/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/local_plugins/ota/README.md b/local_plugins/ota/README.md new file mode 100644 index 000000000..26563dd24 --- /dev/null +++ b/local_plugins/ota/README.md @@ -0,0 +1,15 @@ +# ota + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/to/develop-plugins), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + diff --git a/local_plugins/ota/analysis_options.yaml b/local_plugins/ota/analysis_options.yaml new file mode 100644 index 000000000..a5744c1cf --- /dev/null +++ b/local_plugins/ota/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/local_plugins/ota/android/.gitignore b/local_plugins/ota/android/.gitignore new file mode 100644 index 000000000..161bdcdaf --- /dev/null +++ b/local_plugins/ota/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx diff --git a/local_plugins/ota/android/build.gradle b/local_plugins/ota/android/build.gradle new file mode 100644 index 000000000..b6ead6ba6 --- /dev/null +++ b/local_plugins/ota/android/build.gradle @@ -0,0 +1,68 @@ +group = "com.example.ota" +version = "1.0-SNAPSHOT" + +buildscript { + ext.kotlin_version = "1.8.22" + repositories { + google() + mavenCentral() + } + + dependencies { + classpath("com.android.tools.build:gradle:8.7.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: "com.android.library" +apply plugin: "kotlin-android" + +android { + namespace = "com.example.ota" + + compileSdk = 35 + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11 + } + + sourceSets { + main.java.srcDirs += "src/main/kotlin" + test.java.srcDirs += "src/test/kotlin" + } + + defaultConfig { + minSdk = 21 + } + + dependencies { + implementation("com.jieli.jl_bt_ota:jl_bt_ota:1.9.2") + testImplementation("org.jetbrains.kotlin:kotlin-test") + testImplementation("org.mockito:mockito-core:5.0.0") + add("compileOnly", project(":ble_service")) + } + + testOptions { + unitTests.all { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + outputs.upToDateWhen {false} + showStandardStreams = true + } + } + } +} diff --git a/local_plugins/ota/android/libs/jl_bt_ota_V1.9.2-release.aar b/local_plugins/ota/android/libs/jl_bt_ota_V1.9.2-release.aar new file mode 100644 index 0000000000000000000000000000000000000000..9ecf85489156cc660994da8ddd84b341e47ece08 GIT binary patch literal 247632 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

3T-;)Tt1#K?rrwJyEzYLi9O|Z$3frAq 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

IQ=q*TSc4M*Iw5Y#NO%PlOqJcHUW7rFbNyQ9s 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

ZAKzx!5c4(nnW$9~K(}G=F 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 r`~M6AKz + + diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/DeviceConnection.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/DeviceConnection.kt new file mode 100644 index 000000000..0a9abdb19 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/DeviceConnection.kt @@ -0,0 +1,26 @@ +package com.jieli.otasdk.model + +import android.bluetooth.BluetoothDevice + +/** + * @author zqjasonZhong + * @since 2022/9/9 + * @email zhongzhuocheng@zh-jieli.com + * @desc 设备连接状态 + */ +class DeviceConnection(val device: BluetoothDevice?, var state: Int) { + + override fun hashCode(): Int { + return device.hashCode() + } + + override fun equals(other: Any?): Boolean { + if (other !is DeviceConnection) return false + return device == other.device + } + + override fun toString(): String { + return "DeviceConnection(device=$device, state=$state)" + } + +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt new file mode 100644 index 000000000..cabac136a --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt @@ -0,0 +1,148 @@ +package com.example.ota + +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result + +import android.bluetooth.BluetoothDevice +import android.content.Context +import com.jieli.otasdk.tool.ota.OTAManager +import com.jieli.jl_bt_ota.constant.ErrorCode +import com.jieli.jl_bt_ota.constant.StateCode +import com.jieli.jl_bt_ota.interfaces.BtEventCallback +import com.jieli.jl_bt_ota.interfaces.IUpgradeCallback +import com.jieli.jl_bt_ota.model.base.BaseError +import com.jieli.jl_bt_ota.model.response.TargetInfoResponse +import com.jieli.jl_bt_ota.util.BluetoothUtil +import com.jieli.jl_bt_ota.util.CHexConver +import com.jieli.jl_bt_ota.util.JL_Log +import com.jieli.otasdk.tool.bluetooth.BluetoothHelper +import androidx.lifecycle.MutableLiveData +import com.jieli.otasdk.model.DeviceConnection +import android.util.Log +import androidx.annotation.NonNull +import com.jieli.otasdk.tool.config.ConfigHelper +import com.yunqiinnovation.ble_service.BleService + class CustomUpdateCallback( + + val device: BluetoothDevice? +) : IUpgradeCallback { + companion object { + private const val TAG = "JlOtaPlugin" + private const val CHANNEL_NAME = "com.yunqiinnovation.jl_ota" + private const val EVENT_CHANNEL_NAME = "com.yunqiinnovation.jl_ota/events" + + } + + override fun onStartOTA() { + Log.d(TAG, "onStartOTA开始升级") + // viewModel.otaStateMLD.value = OTAStart(device) + } + + override fun onNeedReconnect(addr: String?, isNewReconnectWay: Boolean) { + Log.d(TAG, "onNeedReconnect需要重新链接") + + } + + override fun onProgress(type: Int, progress: Float) { + Log.d(TAG, "onProgress正在进展") + //viewModel.otaStateMLD.value = OTAWorking(device, type, progress) + } + + override fun onStopOTA() { + Log.d(TAG, "onStartOTA停止升级") + + } + + override fun onCancelOTA() { + Log.d(TAG, "onCancelOTA取消升级") + + } + + override fun onError(error: BaseError?) { + val errorMessage = error?.message ?: "Unknown error" + Log.e(TAG, "升级失败: ${error?.message ?: "未知错误"}") + + // 如果需要打印完整错误对象信息(假设BaseError有重写toString()) + Log.d(TAG, "完整错误对象: ${error ?: "null"}") + } +} + +/** OtaPlugin */ +class OtaPlugin: FlutterPlugin, MethodCallHandler { + /// The MethodChannel that will the communication between Flutter and native Android + /// + /// This local reference serves to register the plugin with the Flutter Engine and unregister it + /// when the Flutter Engine is detached from the Activity + private lateinit var channel : MethodChannel + private lateinit var context: Context + +private lateinit var bluetoothHelper : BluetoothHelper + val otaConnectionMLD = MutableLiveData() + val mandatoryUpgradeMLD = MutableLiveData() + private lateinit var otaManager : OTAManager + + private val bluetoothCallback = object : BtEventCallback() { + + override fun onConnection(device: BluetoothDevice?, status: Int) { + if ((status == StateCode.CONNECTION_FAILED || status == StateCode.CONNECTION_DISCONNECT) && bluetoothHelper.getConnectedDevice() != null) { + bluetoothHelper.disconnectDevice(bluetoothHelper.getConnectedDevice()) + } + otaConnectionMLD.value = DeviceConnection(device, status) + } + + override fun onMandatoryUpgrade(device: BluetoothDevice?) { + mandatoryUpgradeMLD.postValue(device!!) + } + } + override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + context = flutterPluginBinding.applicationContext + channel = MethodChannel(flutterPluginBinding.binaryMessenger, "ota") + channel.setMethodCallHandler(this) + + Log.d("TAG", "onAttachedToEngine") + } + + override fun onMethodCall(call: MethodCall, result: Result) { + if (call.method == "getPlatformVersion") { + Log.d("TAG", "Connection") + // otaManager.configHelper + // 确保先初始化 ConfigHelper + ConfigHelper.initialize(context) + otaManager = OTAManager(context) + bluetoothHelper = BluetoothHelper(context) + // 如果需要额外的初始化逻辑,请在这里添加 + otaManager.registerBluetoothCallback(bluetoothCallback) + + // otaManager.registerBluetoothCallback(bluetoothCallback) + result.success("Android ${android.os.Build.VERSION.RELEASE}") + }else if (call.method == "searchDevices") { + Log.d("TAG", "searchDevices") + // otaManager.configHelper + BleService.disconnect() + // 确保先初始化 ConfigHelper + otaManager.bluetoothHelper.startScan(BleService.bluetoothGatt?.device) + + // otaManager.registerBluetoothCallback(bluetoothCallback) + result.success("Android ${android.os.Build.VERSION.RELEASE}") + } else if (call.method == "startUpgrade") { + Log.d("TAG", "startUpgrade") + var filePath = "/storage/emulated/0/Download/JieLiOTA/upgrade/update - v0.1.0_添加杰理OTA,优化主从切换拾音丢失问题.ufw" + otaManager.bluetoothOption.firmwareFilePath = filePath + otaManager.startOTA( + CustomUpdateCallback( + otaManager.bluetoothHelper.getConnectedDevice() + ) + ) + result.success("Android ${android.os.Build.VERSION.RELEASE}") + } else { + result.notImplemented() + } + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BTEventCbHelper.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BTEventCbHelper.kt new file mode 100644 index 000000000..5661e20a4 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BTEventCbHelper.kt @@ -0,0 +1,91 @@ +package com.jieli.otasdk.tool.bluetooth + +import android.bluetooth.BluetoothDevice +import android.os.Handler +import android.os.Looper +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo +import java.util.* + +/** + * @author zqjasonZhong + * @since 2022/9/14 + * @email zhongzhuocheng@zh-jieli.com + * @desc 蓝牙事件回调辅助类 + */ +class BTEventCbHelper : OnBTEventCallback() { + private val callbacks = mutableListOf() + private val uiHandler = Handler(Looper.getMainLooper()) + + fun registerCallback(callback: OnBTEventCallback) { + if (callbacks.contains(callback)) return + callbacks.add(callback) + } + + fun unregisterCallback(callback: OnBTEventCallback) { + if (callbacks.isEmpty()) return + callbacks.remove(callback) + } + + fun release() { + callbacks.clear() + uiHandler.removeCallbacksAndMessages(null) + } + + override fun onAdapterChange(bEnabled: Boolean) { + callbackEvent(object : CallbackImpl { + override fun onCallback(callback: OnBTEventCallback) { + callback.onAdapterChange(bEnabled) + } + }) + } + + override fun onDiscoveryChange(bStart: Boolean, scanType: Int) { + callbackEvent(object : CallbackImpl { + override fun onCallback(callback: OnBTEventCallback) { + callback.onDiscoveryChange(bStart, scanType) + } + }) + } + + override fun onDiscovery(device: BluetoothDevice?, bleScanMessage: BleScanInfo?) { + callbackEvent(object : CallbackImpl { + override fun onCallback(callback: OnBTEventCallback) { + callback.onDiscovery(device, bleScanMessage) + } + }) + } + + override fun onDeviceConnection(device: BluetoothDevice?, way: Int, status: Int) { + callbackEvent(object : CallbackImpl { + override fun onCallback(callback: OnBTEventCallback) { + callback.onDeviceConnection(device, way, status) + } + }) + } + + override fun onReceiveData(device: BluetoothDevice?, way: Int, uuid: UUID?, data: ByteArray?) { + callbackEvent(object : CallbackImpl { + override fun onCallback(callback: OnBTEventCallback) { + callback.onReceiveData(device, way, uuid, data) + } + }) + } + + override fun onBleMtuChange(device: BluetoothDevice?, mtu: Int, status: Int) { + callbackEvent(object : CallbackImpl { + override fun onCallback(callback: OnBTEventCallback) { + callback.onBleMtuChange(device, mtu, status) + } + }) + } + + private fun callbackEvent(impl: CallbackImpl?) { + if (null == impl) return + val runnable = CallbackRunnable(callbacks, impl) + if (Thread.currentThread().id == Looper.getMainLooper().thread.id) { + runnable.run() + } else { + uiHandler.post(runnable) + } + } +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BluetoothHelper.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BluetoothHelper.kt new file mode 100644 index 000000000..85ec1eb32 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BluetoothHelper.kt @@ -0,0 +1,204 @@ +package com.jieli.otasdk.tool.bluetooth + +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothProfile +import android.content.Context +import com.jieli.jl_bt_ota.util.BluetoothUtil +import com.jieli.jl_bt_ota.util.CHexConver +import com.jieli.otasdk.tool.config.ConfigHelper +import com.jieli.otasdk.tool.ota.ble.BleManager +import com.jieli.otasdk.tool.ota.ble.interfaces.BleEventCallback +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo +import com.jieli.otasdk.tool.bluetooth.OtaConstant +import java.util.* +import android.util.Log +/** + * @author zqjasonZhong + * @since 2022/9/14 + * @email zhongzhuocheng@zh-jieli.com + * @desc 蓝牙操作辅助类 + */ +class BluetoothHelper(private val context: Context) { + + private val configHelper = ConfigHelper.getInstance() + private val bleManager = BleManager.getInstance(context)!! + private val btEventCbHelper = BTEventCbHelper() + + companion object { + + const val TAG: String = "BluetoothHelper" + + @Volatile + private var instance: BluetoothHelper? = null + + fun getInstance(context: Context): BluetoothHelper = instance ?: synchronized(this) { + instance ?: BluetoothHelper(context).also { instance = it } + } + } + + private val bleEventCallback = object : BleEventCallback() { + + override fun onAdapterChange(bEnabled: Boolean) { + btEventCbHelper.onAdapterChange(bEnabled) + } + + override fun onDiscoveryBleChange(bStart: Boolean) { + btEventCbHelper.onDiscoveryChange(bStart, OtaConstant.PROTOCOL_BLE) + } + + override fun onDiscoveryBle(device: BluetoothDevice?, bleScanMessage: BleScanInfo?) { + btEventCbHelper.onDiscovery(device, bleScanMessage) + } + + override fun onBleConnection(device: BluetoothDevice?, status: Int) { + btEventCbHelper.onDeviceConnection(device, OtaConstant.PROTOCOL_BLE, status) + } + + override fun onBleDataNotification( + device: BluetoothDevice?, + serviceUuid: UUID?, + characteristicsUuid: UUID?, + data: ByteArray? + ) { + btEventCbHelper.onReceiveData( + device, + OtaConstant.PROTOCOL_BLE, + characteristicsUuid, + data + ) + } + + override fun onBleDataBlockChanged(device: BluetoothDevice?, block: Int, status: Int) { + btEventCbHelper.onBleMtuChange(device, block, status) + } + } + + + + init { +// if (configHelper.isBleWay()) { + bleManager.registerBleEventCallback(bleEventCallback) +// } else { + +// } + } + + fun destroy() { + bleManager.unregisterBleEventCallback(bleEventCallback) + bleManager.destroy() + + btEventCbHelper.release() + instance = null + } + + fun registerCallback(callback: OnBTEventCallback) { + btEventCbHelper.registerCallback(callback) + } + + fun unregisterCallback(callback: OnBTEventCallback) { + btEventCbHelper.unregisterCallback(callback) + } + + fun isConnected(): Boolean { + return getConnectedDevice() != null + } + + fun isDeviceConnected(device: BluetoothDevice?): Boolean { + return BluetoothUtil.deviceEquals(getConnectedDevice(), device) + } + + fun isScanning(): Boolean = + bleManager.isBleScanning + + + fun isConnecting(): Boolean = + bleManager.isBleScanning + + + fun getConnectedDevice(): BluetoothDevice? { + + return bleManager.connectedBtDevice + + } + + fun getConnectedGatt(): BluetoothGatt? { + return if (configHelper.isBleWay()) { + bleManager.getConnectedBtGatt(getConnectedDevice()) + } else { + null + } + } + + fun getBleMtu(): Int { + return if (configHelper.isBleWay()) { + return bleManager.getBleMtu(getConnectedDevice()) + } else { + 20 + } + } + + fun startScan(device: BluetoothDevice?) { + Log.i(TAG, ", startScan" + device); + + bleManager.startLeScan(device) + + } + + fun stopScan() { + + bleManager.stopLeScan() + + } + + fun connectDevice(device: BluetoothDevice?): Boolean = + + bleManager.connectBleDevice(device) + + + fun disconnectDevice(device: BluetoothDevice?) { + + bleManager.disconnectBleDevice(device) + + } + + fun connectBleDevice(device: BluetoothDevice?): Boolean = + bleManager.connectBleDevice(device) + + fun reconnectDevice(address: String?, isUseNewAdv: Boolean) { + if (configHelper.isBleWay()) { + bleManager.reconnectDevice(address, isUseNewAdv) + } else { + //TODO:需要增加SPP自定义回连方式 + } + } + + fun writeDataToDevice(bluetoothDevice: BluetoothDevice?, byteArray: ByteArray?): Boolean { + if (null == bluetoothDevice || null == byteArray || byteArray.isEmpty()) return false + if (bleManager.connectedBtDevice != null) {//目前连接的设备是ble + bleManager.writeDataByBleAsync( + bluetoothDevice, + BleManager.BLE_UUID_SERVICE, + BleManager.BLE_UUID_WRITE, + byteArray + ) { device, serviceUUID, characteristicUUID, result, data -> + Log.i( + TAG, + "-writeDataByBleAsync- device:${ + printDeviceInfo(device) + }, result = $result,\ndata:[${ + CHexConver.byte2HexStr(data) + }]" + ) + } + } + return true + } + + private fun printDeviceInfo(device: BluetoothDevice?): String? { + //return AppUtil.printBtDeviceInfo(device) + //注释掉 + return "返回设备信息" + } + +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackImpl.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackImpl.kt new file mode 100644 index 000000000..52709b99c --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackImpl.kt @@ -0,0 +1,12 @@ +package com.jieli.otasdk.tool.bluetooth + +/** + * @author zqjasonZhong + * @since 2022/9/14 + * @email zhongzhuocheng@zh-jieli.com + * @desc 回调实现类 + */ +interface CallbackImpl { + + fun onCallback(callback: T) +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackRunnable.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackRunnable.kt new file mode 100644 index 000000000..62bea6970 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackRunnable.kt @@ -0,0 +1,23 @@ +package com.jieli.otasdk.tool.bluetooth + +/** + * @author zqjasonZhong + * @since 2022/9/14 + * @email zhongzhuocheng@zh-jieli.com + * @desc 回调处理类 + */ +class CallbackRunnable constructor( + private val callbacks: MutableList, + private val impl: CallbackImpl? +) : + Runnable { + + override fun run() { + if (callbacks.isEmpty() || impl == null) return + val temp = mutableListOf() + temp.addAll(callbacks) + temp.forEach { + impl.onCallback(it) + } + } +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OnBTEventCallback.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OnBTEventCallback.kt new file mode 100644 index 000000000..41a93eeb4 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OnBTEventCallback.kt @@ -0,0 +1,38 @@ +package com.jieli.otasdk.tool.bluetooth + +import android.bluetooth.BluetoothDevice +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo +import java.util.* + +/** + * @author zqjasonZhong + * @since 2022/9/14 + * @email zhongzhuocheng@zh-jieli.com + * @desc 蓝牙事件回调 + */ +open class OnBTEventCallback { + + open fun onAdapterChange(bEnabled: Boolean) { + + } + + open fun onDiscoveryChange(bStart: Boolean, scanType: Int) { + + } + + open fun onDiscovery(device: BluetoothDevice?, bleScanMessage: BleScanInfo?) { + + } + + open fun onDeviceConnection(device: BluetoothDevice?, way: Int, status: Int) { + + } + + open fun onReceiveData(device: BluetoothDevice?, way: Int, uuid: UUID?, data: ByteArray?) { + + } + + open fun onBleMtuChange(device: BluetoothDevice?, mtu: Int, status: Int) { + + } +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OtaConstant.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OtaConstant.kt new file mode 100644 index 000000000..c7cfb37cb --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OtaConstant.kt @@ -0,0 +1,54 @@ +package com.jieli.otasdk.tool.bluetooth + +import java.util.* + +/** + * 常量声明 + * + * @author zqjasonZhong + * @date 2019/12/30 + */ +class OtaConstant { + + companion object { + + val UUID_A2DP: UUID = UUID.fromString("0000110b-0000-1000-8000-00805f9b34fb") + val UUID_SPP: UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb") + + //Ble协议 + const val PROTOCOL_BLE = 0 + //Spp协议 + const val PROTOCOL_SPP = 1 + + const val CURRENT_PROTOCOL = PROTOCOL_BLE + + //是否使用设备认证 + const val IS_NEED_DEVICE_AUTH = true + + //是否HID设备连接 + const val HID_DEVICE_WAY = false + + //是否需要自定义连接方式 + const val NEED_CUSTOM_RECONNECT_WAY = false + + //是否使用SPP多通道连接 + const val USE_SPP_MULTIPLE_CHANNEL = false + + //是否使用自动化测试 + const val AUTO_TEST_OTA = false + //自动化测试次数 + const val AUTO_TEST_COUNT = 30 + + //是否自动化测试时允许容错 + const val AUTO_FAULT_TOLERANT = false + //容错次数 + const val AUTO_FAULT_TOLERANT_COUNT = 1 + + //dir + const val DIR_ROOT = "JieLiOTA" + const val DIR_UPGRADE = "upgrade" + const val DIR_LOGCAT = "logcat" + + const val SCAN_TIMEOUT = 16 * 1000L + } +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/config/ConfigHelper.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/config/ConfigHelper.kt new file mode 100644 index 000000000..2e75a9a0a --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/config/ConfigHelper.kt @@ -0,0 +1,187 @@ +package com.jieli.otasdk.tool.config + +import android.annotation.SuppressLint +import android.content.Context +import androidx.annotation.IntRange +import com.jieli.jl_bt_ota.constant.BluetoothConstant +import com.jieli.otasdk.tool.bluetooth.OtaConstant + +/** + * @author zqjasonZhong + * @since 2022/9/8 + * @email zhongzhuocheng@zh-jieli.com + * @desc 配置辅助类 + */ +open class ConfigHelper private constructor(context: Context) { + + companion object { + //download文件夹 + private const val KEY_DOWNLOAD_URI = "download_uri" + + //通讯方式 + private const val KEY_COMMUNICATION_WAY = "communication_way" + + //是否使用设备认证 + private const val KEY_IS_USE_DEVICE_AUTH = "is_use_device_auth" + + //是否HID设备 + private const val KEY_IS_HID_DEVICE = "is_hid_device" + + //是否使用自定义回连方式 + private const val KEY_USE_CUSTOM_RECONNECT_WAY = "use_custom_reconnect_way" + + //BLE的MTU请求值 + private const val KEY_BLE_MTU_VALUE = "ble_mtu_value" + + //是否启用SPP多通道 + private const val KEY_SPP_MULTIPLE_CHANNEL = "spp_multiple_channel" + + //自定义SPP通道 + private const val KEY_SPP_CUSTOM_UUID = "spp_custom_uuid" + + //是否自动测试OTA + private const val KEY_AUTO_TEST_OTA = "auto_test_ota" + + //自动化测试次数 + private const val KEY_AUTO_TEST_COUNT = "auto_test_count" + + //是否自动测试OTA时,允许容错 + private const val KEY_FAULT_TOLERANT = "fault_tolerant" + + //容错次数 + private const val KEY_FAULT_TOLERANT_COUNT = "fault_tolerant_count" + //扫描过滤参数 + private const val KEY_SCAN_FILTER_STRING = "scan_filter_string" + + //开发者模式 + private const val KEY_DEVELOP_MODE = "develop_mode" + + // 广播音箱模式 + private const val KEY_BROADCAST_BOX = "broadcast_box_switch" + @Volatile + private var instance: ConfigHelper? = null + + // 双重校验锁初始化 + fun initialize(context: Context) = instance ?: synchronized(this) { + instance ?: ConfigHelper(context.applicationContext).also { + instance = it + } + } + + // 安全获取实例方法 + fun getInstance(): ConfigHelper = instance ?: throw IllegalStateException( + "Call ConfigHelper.initialize() first" + ) + } + + private val preferences = context.getSharedPreferences("ota_config_data", Context.MODE_PRIVATE) + + fun isBleWay(): Boolean = preferences.getInt( + KEY_COMMUNICATION_WAY, + OtaConstant.CURRENT_PROTOCOL + ) == OtaConstant.PROTOCOL_BLE + + fun setBleWay(isBle: Boolean) { + val way = if (isBle) OtaConstant.PROTOCOL_BLE else OtaConstant.PROTOCOL_SPP + preferences.edit().putInt(KEY_COMMUNICATION_WAY, way).apply() + } + + fun isUseDeviceAuth(): Boolean = + preferences.getBoolean(KEY_IS_USE_DEVICE_AUTH, OtaConstant.IS_NEED_DEVICE_AUTH) + + fun setUseDeviceAuth(isAuth: Boolean) { + preferences.edit().putBoolean(KEY_IS_USE_DEVICE_AUTH, isAuth).apply() + } + + fun isHidDevice(): Boolean = + preferences.getBoolean(KEY_IS_HID_DEVICE, OtaConstant.HID_DEVICE_WAY) + + fun setHidDevice(isHid: Boolean) { + preferences.edit().putBoolean(KEY_IS_HID_DEVICE, isHid).apply() + } + + fun isUseCustomReConnectWay(): Boolean = preferences.getBoolean( + KEY_USE_CUSTOM_RECONNECT_WAY, + OtaConstant.NEED_CUSTOM_RECONNECT_WAY + ) + + fun setUseCustomReConnectWay(isCustom: Boolean) { + preferences.edit().putBoolean(KEY_USE_CUSTOM_RECONNECT_WAY, isCustom).apply() + } + + fun getBleRequestMtu(): Int = + preferences.getInt(KEY_BLE_MTU_VALUE, 509) + + fun setBleRequestMtu(@IntRange(from = 20, to = 509) mtu: Int) { + preferences.edit().putInt(KEY_BLE_MTU_VALUE, mtu).apply() + } + + fun isUseMultiSppChannel(): Boolean = preferences.getBoolean( + KEY_SPP_MULTIPLE_CHANNEL, + OtaConstant.USE_SPP_MULTIPLE_CHANNEL + ) + + fun setUseMultiSppChannel(isUseMulti: Boolean) { + preferences.edit().putBoolean(KEY_SPP_MULTIPLE_CHANNEL, isUseMulti).apply() + } + + fun getCustomSppChannel(): String? = + preferences.getString(KEY_SPP_CUSTOM_UUID, OtaConstant.UUID_SPP.toString()) + + fun setCustomSppChannel(uuid: String?) { + preferences.edit().putString(KEY_SPP_CUSTOM_UUID, uuid).apply() + } + + fun isAutoTest(): Boolean = preferences.getBoolean(KEY_AUTO_TEST_OTA, OtaConstant.AUTO_TEST_OTA) + + fun setAutoTest(isAutoTest: Boolean) { + preferences.edit().putBoolean(KEY_AUTO_TEST_OTA, isAutoTest).apply() + } + + fun getAutoTestCount(): Int = preferences.getInt( + KEY_AUTO_TEST_COUNT, + OtaConstant.AUTO_TEST_COUNT + ) + + fun setAutoTestCount(count: Int) { + if (!isAutoTest()) return + preferences.edit().putInt(KEY_AUTO_TEST_COUNT, count).apply() + } + + fun isFaultTolerant(): Boolean = preferences.getBoolean(KEY_FAULT_TOLERANT, OtaConstant.AUTO_FAULT_TOLERANT) + + fun setFaultTolerant(isFaultTolerant: Boolean) { + preferences.edit().putBoolean(KEY_FAULT_TOLERANT, isFaultTolerant).apply() + } + + fun getFaultTolerantCount(): Int = preferences.getInt( + KEY_FAULT_TOLERANT_COUNT, + OtaConstant.AUTO_FAULT_TOLERANT_COUNT + ) + + fun setFaultTolerantCount(count: Int) { + if (!isFaultTolerant()) return + preferences.edit().putInt(KEY_FAULT_TOLERANT_COUNT, count).apply() + } + + fun getScanFilter(): String? = + preferences.getString(KEY_SCAN_FILTER_STRING, "") + + fun setScanFilter(scanFilter: String?) { + preferences.edit().putString(KEY_SCAN_FILTER_STRING, scanFilter).apply() + } + + fun isDevelopMode(): Boolean = + preferences.getBoolean(KEY_DEVELOP_MODE, false) + + fun setDevelopMode(developMode: Boolean) { + preferences.edit().putBoolean(KEY_DEVELOP_MODE, developMode).apply() + } + + fun isEnableBroadcastBox(): Boolean = + preferences.getBoolean(KEY_BROADCAST_BOX, false) + + fun enableBroadcastBox(enable: Boolean) { + preferences.edit().putBoolean(KEY_BROADCAST_BOX, enable).apply() + } +} \ No newline at end of file diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/OTAManager.kt b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/OTAManager.kt new file mode 100644 index 000000000..10d86a089 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/OTAManager.kt @@ -0,0 +1,149 @@ +package com.jieli.otasdk.tool.ota + +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothGatt +import android.content.Context +import com.jieli.jl_bt_ota.constant.BluetoothConstant +import com.jieli.jl_bt_ota.constant.StateCode +import com.jieli.jl_bt_ota.impl.BluetoothOTAManager +import com.jieli.jl_bt_ota.impl.RcspAuth +import com.jieli.jl_bt_ota.model.BluetoothOTAConfigure +import com.jieli.jl_bt_ota.util.BluetoothUtil +import com.jieli.jl_bt_ota.util.CHexConver +import com.jieli.otasdk.tool.bluetooth.BluetoothHelper +import com.jieli.otasdk.tool.bluetooth.OnBTEventCallback +import com.jieli.otasdk.tool.config.ConfigHelper +import com.jieli.otasdk.tool.bluetooth.OtaConstant +import java.util.* +import android.util.Log +/** + * 用于RCSP的第三方SDK接入OTA流程 + */ +class OTAManager(context: Context) : BluetoothOTAManager(context) { + + val configHelper = ConfigHelper.getInstance() + val bluetoothHelper = BluetoothHelper.getInstance(context) + + val btEventCallback = object : OnBTEventCallback() { + + override fun onDeviceConnection(device: BluetoothDevice?, way: Int, status: Int) { + super.onDeviceConnection(device, way, status) + // val connectionState = AppUtil.changeConnectStatus(status) + // Log.i( + // TAG, "onConnection >>> device : ${printDeviceInfo(device)}, way = $way" + + // " status :$status, change status : $connectionState" + // ) + // onBtDeviceConnection(device, connectionState) + //注释掉 + Log.i( + TAG, "onConnection >>> device : ${device}, way = $way" + + " status :$status, change status : 3" + ) + onBtDeviceConnection(device, 1) + } + + override fun onReceiveData( + device: BluetoothDevice?, + way: Int, + uuid: UUID?, + data: ByteArray? + ) { + super.onReceiveData(device, way, uuid, data) + Log.d( + TAG, "onReceiveData >>> ${printDeviceInfo(device)}, way = $way,\n" + + "uuid = $uuid, data :${CHexConver.byte2HexStr(data)} " + ) + // if (way == OtaConstant.PROTOCOL_SPP && SppManager.UUID_SPP != uuid) { + // Log.d( + // TAG, "onReceiveData >>> skip spec" + // ) + // return + // } + onReceiveDeviceData(device, data) + } + + override fun onBleMtuChange(device: BluetoothDevice?, mtu: Int, status: Int) { + super.onBleMtuChange(device, mtu, status) + onMtuChanged(bluetoothHelper.getConnectedGatt(), mtu, status) + } + + } + + init { + // ConfigHelper.initialize(context) + val bluetoothOption = BluetoothOTAConfigure() + //选择通讯方式 + bluetoothOption.priority = + BluetoothOTAConfigure.PREFER_BLE + + //是否需要自定义回连方式(默认不需要,如需要自定义回连方式,需要客户自行实现) + bluetoothOption.isUseReconnect = + (configHelper.isUseCustomReConnectWay() && configHelper.isHidDevice()) + Log.d( + TAG, "是否启用设备认证流程(与固件工程师确认) >>> ${configHelper.isUseDeviceAuth()} >>> ${bluetoothOption.isUseReconnect} " + ) + //是否启用设备认证流程(与固件工程师确认) + bluetoothOption.isUseAuthDevice = configHelper.isUseDeviceAuth() + //设置BLE的MTU + bluetoothOption.mtu = BluetoothConstant.BLE_MTU_MIN + //是否需要改变BLE的MTU + bluetoothOption.isNeedChangeMtu = false + //是否启用杰理服务器(暂时不支持) + bluetoothOption.isUseJLServer = false + + //配置OTA参数 + configure(bluetoothOption) + RcspAuth.setAuthTimeout(5000) + bluetoothHelper.registerCallback(btEventCallback) + if (bluetoothHelper.isConnected()) { + onBtDeviceConnection(bluetoothHelper.getConnectedDevice(), StateCode.CONNECTION_OK) + if (configHelper.isBleWay()) { + onMtuChanged( + bluetoothHelper.getConnectedGatt(), + bluetoothHelper.getBleMtu() + 3, + BluetoothGatt.GATT_SUCCESS + ) + } + } + } + + + override fun getConnectedDevice(): BluetoothDevice? = bluetoothHelper.getConnectedDevice() + + override fun getConnectedBluetoothGatt(): BluetoothGatt? = bluetoothHelper.getConnectedGatt() + + override fun connectBluetoothDevice(bluetoothDevice: BluetoothDevice?) { + //仅仅作为回连设备,回连设备现在仅支持BLE + val result: Boolean = bluetoothHelper.connectBleDevice(bluetoothDevice) + if (!result) { + onBtDeviceConnection(bluetoothDevice, StateCode.CONNECTION_FAILED) + } + } + + override fun disconnectBluetoothDevice(bluetoothDevice: BluetoothDevice?) { + bluetoothHelper.disconnectDevice(bluetoothDevice) + } + + override fun sendDataToDevice(bluetoothDevice: BluetoothDevice?, bytes: ByteArray?): Boolean { + Log.d( + TAG, + "sendDataToDevice : device = ${printDeviceInfo(bluetoothDevice)}\n" + + "data = [${CHexConver.byte2HexStr(bytes)}]" + ) + return bluetoothHelper.writeDataToDevice(bluetoothDevice, bytes) + } + + override fun release() { + super.release() + bluetoothHelper.unregisterCallback(btEventCallback) + } + + fun setReconnectAddr(addr: String?) { +// setReconnectAddress(addr) + } + + private fun printDeviceInfo(device: BluetoothDevice?): String? { + return BluetoothUtil.printBtDeviceInfo(context, device) + } + +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleEventCallbackManager.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleEventCallbackManager.java new file mode 100644 index 000000000..60cd91506 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleEventCallbackManager.java @@ -0,0 +1,175 @@ +package com.jieli.otasdk.tool.ota.ble; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGattService; +import android.os.Handler; +import android.os.Looper; + +import com.jieli.otasdk.tool.ota.ble.interfaces.BleEventCallback; +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * Ble事件回调管理器 + * + * @author zqjasonZhong + * @since 2020/12/24 + */ +class BleEventCallbackManager extends BleEventCallback { + private final ArrayList mCallbacks = new ArrayList<>(); + private final Handler mHandler = new Handler(Looper.getMainLooper()); + + public void registerBleEventCallback(BleEventCallback callback) { + if (callback != null && !mCallbacks.contains(callback)) { + mCallbacks.add(callback); + } + } + + public void unregisterBleEventCallback(BleEventCallback callback) { + if (callback != null && !mCallbacks.isEmpty()) { + mCallbacks.remove(callback); + } + } + + public void release() { + mCallbacks.clear(); + mHandler.removeCallbacksAndMessages(null); + } + + @Override + public void onAdapterChange(final boolean bEnabled) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onAdapterChange(bEnabled); + } + }); + } + + @Override + public void onDiscoveryBleChange(final boolean bStart) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onDiscoveryBleChange(bStart); + } + }); + } + + @Override + public void onDiscoveryBle(final BluetoothDevice device, final BleScanInfo bleScanMessage) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onDiscoveryBle(device, bleScanMessage); + } + }); + } + + @Override + public void onBleConnection(final BluetoothDevice device, final int status) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onBleConnection(device, status); + } + }); + } + + @Override + public void onBleServiceDiscovery(final BluetoothDevice device, final int status, final List services) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onBleServiceDiscovery(device, status, services); + } + }); + } + + @Override + public void onBleNotificationStatus(final BluetoothDevice device, final UUID serviceUuid, final UUID characteristicUuid, final int status) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onBleNotificationStatus(device, serviceUuid, characteristicUuid, status); + } + }); + } + + @Override + public void onBleDataBlockChanged(final BluetoothDevice device, final int block, final int status) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onBleDataBlockChanged(device, block, status); + } + }); + } + + @Override + public void onBleDataNotification(final BluetoothDevice device, final UUID serviceUuid, final UUID characteristicsUuid, final byte[] data) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onBleDataNotification(device, serviceUuid, characteristicsUuid, data); + } + }); + } + + @Override + public void onBleWriteStatus(final BluetoothDevice device, final UUID serviceUuid, final UUID characteristicsUuid, final byte[] data, final int status) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onBleWriteStatus(device, serviceUuid, characteristicsUuid, data, status); + } + }); + } + + @Override + public void onConnectionUpdated(final BluetoothDevice device, final int interval, final int latency, final int timeout, final int status) { + callbackBleEvent(new BleEventCallbackImpl() { + @Override + public void onCallback(BleEventCallback callback) { + callback.onConnectionUpdated(device, interval, latency, timeout, status); + } + }); + } + + private void callbackBleEvent(BleEventCallbackImpl impl) { + if (null == impl) return; + OnBleEventRunnable runnable = new OnBleEventRunnable(impl); + if (Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId()) { + runnable.run(); + } else { + mHandler.post(runnable); + } + } + + private static abstract class BleEventCallbackImpl { + + public abstract void onCallback(BleEventCallback callback); + } + + private class OnBleEventRunnable implements Runnable { + private final BleEventCallbackImpl mImpl; + + public OnBleEventRunnable(BleEventCallbackImpl impl) { + mImpl = impl; + } + + @Override + public void run() { + if (!mCallbacks.isEmpty() && mImpl != null) { + for (BleEventCallback callback : new ArrayList<>(mCallbacks)) { + if (callback != null) { + mImpl.onCallback(callback); + } + } + } + } + } +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleManager.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleManager.java new file mode 100644 index 000000000..feec079de --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleManager.java @@ -0,0 +1,1194 @@ +package com.jieli.otasdk.tool.ota.ble; + +import static android.bluetooth.BluetoothProfile.STATE_CONNECTED; +import static android.os.Build.VERSION_CODES.LOLLIPOP; + +import android.annotation.SuppressLint; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanResult; +import android.bluetooth.le.ScanSettings; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.SystemClock; +import android.text.TextUtils; + +import androidx.annotation.NonNull; + +//import com.jieli.broadcastbox.multidevice.ReConnectHelper; +import com.jieli.jl_bt_ota.constant.BluetoothConstant; +import com.jieli.jl_bt_ota.util.BluetoothUtil; +import com.jieli.jl_bt_ota.util.CHexConver; +import com.jieli.jl_bt_ota.util.CommonUtil; +//import com.jieli.jl_bt_ota.util.Log; +//import com.jieli.otasdk.MainApplication; +import com.jieli.otasdk.tool.config.ConfigHelper; +import com.jieli.otasdk.tool.ota.ble.interfaces.BleEventCallback; +import com.jieli.otasdk.tool.ota.ble.interfaces.OnWriteDataCallback; +import com.jieli.otasdk.tool.ota.ble.model.BleDevice; +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo; +//import com.jieli.otasdk.util.AppUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import android.util.Log; + + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.Manifest; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.provider.Settings; +/** + * Ble连接管理类 + * + * @author zqjasonZhong + * @since 2020/7/16 + */ +public class BleManager { + private final static String TAG = BleManager.class.getSimpleName(); + private final Context mContext; + @SuppressLint("StaticFieldLeak") + private volatile static BleManager instance; + private final ConfigHelper configHelper = ConfigHelper.Companion.getInstance(); + + private BaseBtAdapterReceiver mAdapterReceiver; + private final BluetoothAdapter mBluetoothAdapter; + private BluetoothLeScanner mBluetoothLeScanner; + // private final ReConnectHelper mReConnectHelper; + + private volatile BluetoothDevice mConnectingBtDevice; //连接中的设备 + private volatile BluetoothDevice mUsingDevice; //正在通讯的设备 + + private final Map mConnectedGattMap = new HashMap<>(); + private final List mDiscoveredBleDevices = new ArrayList<>(); + private final BleEventCallbackManager mCallbackManager = new BleEventCallbackManager(); + + private volatile boolean isBleScanning; + private NotifyCharacteristicRunnable mNotifyCharacteristicRunnable; + + private BluetoothDevice deviced;//需要连接手机设备信息 + private long timeout = 15000;//扫描设备时间 + private int mRetryConnectCount = 0;//连接失败后尝试连接次数 + private long startConnectTime = 0; //开始连接时间戳 + private final static int MAX_RETRY_CONNECT_COUNT = 1;//最大尝试连接次数 + private final static int MIN_CONNECT_TIME = 5 * 1000; //连接最小时间超时 + //BLE服务UUID + public final static UUID BLE_UUID_SERVICE = BluetoothConstant.UUID_SERVICE; + //BLE的写特征UUID + public final static UUID BLE_UUID_WRITE = BluetoothConstant.UUID_WRITE; + //BLE的通知特征UUID + public final static UUID BLE_UUID_NOTIFICATION = BluetoothConstant.UUID_NOTIFICATION; + //BLE的通知特征的描述符UUID + public final static UUID BLE_UUID_NOTIFICATION_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805F9B34FB"); + + /** + * 发送数据最大超时 - 8 秒 + */ + public final static int SEND_DATA_MAX_TIMEOUT = 8000; //8 s + private final static int SCAN_BLE_TIMEOUT = 12 * 1000; //建议搜索BLE最小时间 + private final static int CONNECT_BLE_TIMEOUT = 40 * 1000; + + private final static int CALLBACK_TIMEOUT = 6000; + private final static int RECONNECT_BLE_DELAY = 2000; + + private final static int MSG_SCAN_BLE_TIMEOUT = 0x1010; + private final static int MSG_CONNECT_BLE_TIMEOUT = 0x1011; + private final static int MSG_SCAN_HID_DEVICE = 0X1012; + private final static int MSG_NOTIFY_BLE_TIMEOUT = 0x1013; + private final static int MSG_CHANGE_BLE_MTU_TIMEOUT = 0x1014; + private final static int MSG_BLE_DISCOVER_SERVICES_CALLBACK_TIMEOUT = 0x1015; + private final Handler mHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() { + @Override + public boolean handleMessage(@NonNull Message msg) { + switch (msg.what) { + case MSG_SCAN_BLE_TIMEOUT: + if (isBleScanning) { + stopLeScan(); + } + break; + case MSG_CONNECT_BLE_TIMEOUT: { + if (msg.obj instanceof BluetoothDevice) { + BluetoothDevice device = (BluetoothDevice) msg.obj; + BleDevice bleDevice = getConnectedBle(device); + if (null == bleDevice) { + handleBleConnection(device, BluetoothProfile.STATE_DISCONNECTED); + } + setConnectingBtDevice(null); + } + break; + } + case MSG_SCAN_HID_DEVICE: { + List lists = BluetoothUtil.getSystemConnectedBtDeviceList(mContext); + if (null != lists ) { + //&& AppUtil.checkHasConnectPermission(mContext) + for (BluetoothDevice device : lists) { + if (device.getType() != BluetoothDevice.DEVICE_TYPE_CLASSIC && + device.getBondState() == BluetoothDevice.BOND_BONDED) { + handleDiscoveryBle(device, null); + } + } + } + mHandler.sendEmptyMessageDelayed(MSG_SCAN_HID_DEVICE, 1000); + break; + } + case MSG_NOTIFY_BLE_TIMEOUT: { + if (msg.obj instanceof BluetoothDevice) { + BluetoothDevice device = (BluetoothDevice) msg.obj; + disconnectBleDevice(device); + } + break; + } + case MSG_CHANGE_BLE_MTU_TIMEOUT: { + BluetoothDevice device = (BluetoothDevice) msg.obj; + BleDevice bleDevice = getConnectedBle(device); + Log.i(TAG, "-MSG_CHANGE_BLE_MTU_TIMEOUT- request mtu timeout, device : " + printDeviceInfo(device) + ", " + bleDevice); + if (bleDevice != null) { + handleBleConnectedEvent(device); + } else { + handleBleConnection(device, BluetoothProfile.STATE_DISCONNECTED); + } + break; + } + case MSG_BLE_DISCOVER_SERVICES_CALLBACK_TIMEOUT: + if (msg.obj instanceof BluetoothDevice) { + BluetoothDevice connectedBleDev = (BluetoothDevice) msg.obj; + if (BluetoothUtil.deviceEquals(connectedBleDev, mUsingDevice)) { + boolean isNeedDisconnect = true; + BleDevice bleDevice = getConnectedBle(connectedBleDev); + if (bleDevice != null) { + List services = bleDevice.getGatt().getServices(); + if (services != null && services.size() > 0) { + mBluetoothGattCallback.onServicesDiscovered(bleDevice.getGatt(), BluetoothGatt.GATT_SUCCESS); + isNeedDisconnect = false; + } + } + if (isNeedDisconnect) { + Log.d(TAG, "discover services timeout."); + disconnectBleDevice(connectedBleDev); + reconnectDevice(connectedBleDev.getAddress(), false); + } + } + } + break; + } + return false; + } + }); + + + private BleManager(Context context) { + mContext = CommonUtil.checkNotNull(context); + if (CommonUtil.getMainContext() == null) { + CommonUtil.setMainContext(context); + } + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (Build.VERSION.SDK_INT >= LOLLIPOP && mBluetoothAdapter != null) { + mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); + } + //mReConnectHelper = new ReConnectHelper(context, this); + registerReceiver(); + } + + public static BleManager getInstance(Context context) { + if (instance == null) { + synchronized (BleManager.class) { + if (instance == null) { + instance = new BleManager(context.getApplicationContext()); + Log.w(TAG, "init BleManager.. " + instance); + } + } + } + return instance; + } + /** + * 获取已连接的BLE设备列表 + * + * @param context 上下文 + * @return 已连接的BLE设备列表 + */ + @SuppressLint("MissingPermission") + public static List getConnectedBleDeviceList(Context context) { + if (context == null ) return null; + //|| !AppUtil.checkHasConnectPermission(context) + BluetoothManager mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); + if (mBluetoothManager != null) { + return mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT); + } + return null; + } + + public void destroy() { + Log.w(TAG, ">>>>>>>>>>>>>>destroy >>>>>>>>>>>>>>> "); + unregisterReceiver(); + stopConnectTimeout(); + clearConnectedBleDevices(); + + if (isBleScanning()) stopLeScan(); + isBleScanning(false); + mDiscoveredBleDevices.clear(); + //mReConnectHelper.release(); + + mCallbackManager.release(); + mHandler.removeCallbacksAndMessages(null); + instance = null; + } + + public void registerBleEventCallback(BleEventCallback callback) { + mCallbackManager.registerBleEventCallback(callback); + } + + public void unregisterBleEventCallback(BleEventCallback callback) { + mCallbackManager.unregisterBleEventCallback(callback); + } + + public boolean isBluetoothEnable() { + return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled(); + } + + public boolean isBleScanning() { + return isBleScanning; + } + public void checkPermissionsAndRequest(Context context) { + if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { + // 蓝牙未开启,弹窗提示用户开启蓝牙 + new AlertDialog.Builder(context) + .setTitle("蓝牙未开启") + .setMessage("请开启蓝牙以继续使用此功能。") + .setPositiveButton("开启蓝牙", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + context.startActivity(intent); + } + }) + .setNegativeButton("取消", null) + .show(); + } else if (!isLocationPermissionGranted(context)) { + // 定位权限未授权,弹窗提示用户授权定位权限 + new AlertDialog.Builder(context) + .setTitle("定位权限未授权") + .setMessage("请授权定位权限以继续使用此功能。") + .setPositiveButton("授权定位权限", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setData(Uri.parse("package:" + context.getPackageName())); + context.startActivity(intent); + } + }) + .setNegativeButton("取消", null) + .show(); + } + } + + /** + * 检查定位权限是否已授权 + */ + private boolean isLocationPermissionGranted(Context context) { + return context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; + } + @SuppressLint("MissingPermission") + public boolean startLeScan(BluetoothDevice deviced) { + Log.i(TAG, ", timeout = " + timeout); + if (!isBluetoothEnable() || !isLocationPermissionGranted(mContext)) { + checkPermissionsAndRequest(mContext); + return false; + } + if (null == mBluetoothAdapter + // || !AppUtil.checkHasScanPermission(mContext) + ) return false; + Log.i(TAG, ", timeout1 = " + timeout); + if (!isBluetoothEnable() + // || !AppUtil.isHasLocationPermission(mContext) + ) return false; + Log.i(TAG, ", timeout2 = " + timeout); + if (timeout <= 0) timeout = SCAN_BLE_TIMEOUT; + if (isBleScanning) { + Log.i(TAG, "scanning ble ....."); + if (mBluetoothLeScanner != null) { + mBluetoothLeScanner.flushPendingScanResults(mScanCallback); + } + mDiscoveredBleDevices.clear(); + mHandler.removeMessages(MSG_SCAN_BLE_TIMEOUT); + mHandler.sendEmptyMessageDelayed(MSG_SCAN_BLE_TIMEOUT, timeout); + syncSystemBleDevice(); + return true; + } + boolean ret; + if (Build.VERSION.SDK_INT >= LOLLIPOP && mBluetoothLeScanner != null) { + ScanSettings scanSettings; + int scanMode = ScanSettings.SCAN_MODE_BALANCED; //修改搜索BLE模式 -- 均衡模式 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + scanSettings = new ScanSettings.Builder() + .setScanMode(scanMode) + .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE) + .build(); + } else { + scanSettings = new ScanSettings.Builder() + .setScanMode(scanMode) + .build(); + } + mBluetoothLeScanner.startScan(null, scanSettings, mScanCallback); + ret = true; + } else { + ret = mBluetoothAdapter.startLeScan(mLeScanCallback); + } + Log.i(TAG, "startLeScan : " + ret + ", timeout = " + timeout); + isBleScanning(ret); + if (ret) { + mDiscoveredBleDevices.clear(); + mHandler.removeMessages(MSG_SCAN_BLE_TIMEOUT); + mHandler.sendEmptyMessageDelayed(MSG_SCAN_BLE_TIMEOUT, timeout); + syncSystemBleDevice(); + } + return ret; + } + + @SuppressLint("MissingPermission") + public void stopLeScan() { + if (null == mBluetoothAdapter || !isBluetoothEnable() + // || !AppUtil.checkHasScanPermission(mContext) + ) + return; + if (!isBleScanning()) return; + try { + if (Build.VERSION.SDK_INT >= LOLLIPOP && mBluetoothLeScanner != null) { + mBluetoothLeScanner.stopScan(mScanCallback); + } else { + mBluetoothAdapter.stopLeScan(mLeScanCallback); + } + } catch (Exception e) { + e.printStackTrace(); + } + mHandler.removeMessages(MSG_SCAN_BLE_TIMEOUT); + mHandler.removeMessages(MSG_SCAN_HID_DEVICE); + isBleScanning(false); + } + + public BluetoothDevice getConnectedBtDevice() { + return mUsingDevice; + } + + public BluetoothGatt getConnectedBtGatt(BluetoothDevice device) { + BleDevice bleDevice = getConnectedBle(device); + if (null == bleDevice) return null; + return bleDevice.getGatt(); + } + + public BluetoothDevice getConnectedBLEDevice(String address) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) return null; + List devices = getConnectedDeviceList(); + if (devices.isEmpty()) return null; + for (BluetoothDevice device : devices) { + if (device.getAddress().equals(address)) { + return device; + } + } + return null; + } + + /** + * 获取已连接设备列表 + *

+ * 按照连接时间倒序 + *

+ * + * @return 设备列表 + */ + public List getConnectedDeviceList() { + if (mConnectedGattMap.isEmpty()) return new ArrayList<>(); + List bleDevices = getSortList(); + List devices = new ArrayList<>(); + for (BleDevice bleDevice : bleDevices) { + if (null == bleDevice || null == bleDevice.getGatt().getDevice()) continue; + devices.add(bleDevice.getGatt().getDevice()); + } + return devices; + } + + public void reconnectDevice(String address, boolean isUseAdv) { + Log.d(TAG, "reconnectDevice : address = " + address + ", isUseAdv = " + isUseAdv); + //boolean ret = mReConnectHelper.putParam(new ReConnectHelper.ReconnectParam(address, isUseAdv)); + //注释掉的 + // Log.d(TAG, "reconnectDevice : ret = " + ret); + } + + // public boolean isMatchReConnectDevice(String address, String matchAddress) { + // return mReConnectHelper.isMatchAddress(address, matchAddress); + // } + + public int getBleMtu(BluetoothDevice device) { + BleDevice bleDevice = getConnectedBle(device); + if (null == bleDevice) return 0; + return bleDevice.getMtu(); + } + + public boolean isConnecting() { + return mConnectingBtDevice != null; + } + + public boolean isConnectingDevice(BluetoothDevice device) { + return BluetoothUtil.deviceEquals(mConnectingBtDevice, device); + } + + public boolean isConnectedDevice(BluetoothDevice device) { + if (null == device) return false; + return isConnectedDevice(device.getAddress()); + } + + public boolean isConnectedDevice(String address) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) return false; + List devices = getConnectedDeviceList(); + if (devices.isEmpty()) return false; + for (BluetoothDevice device : devices) { + if (device.getAddress().equals(address)) { + return true; + } + } + return false; + } + + @SuppressLint("MissingPermission") + public boolean connectBleDevice(BluetoothDevice device) { + if (null == device + // || !AppUtil.checkHasConnectPermission(mContext) + ) return false; + /* if (mUsingDevice != null) { + Log.e(TAG, "BleDevice is connected, please call disconnectBleDevice method at first."); + setReconnectDevAddr(null); + return false; + }*/ + if (mConnectingBtDevice != null) { + Log.e(TAG, "BleDevice is connecting, please wait."); + return isConnectingDevice(device); + } + if (isBleScanning()) { + stopLeScan(); + } + BluetoothGatt gatt = null; + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + gatt = device.connectGatt( + mContext, + false, + mBluetoothGattCallback, + BluetoothDevice.TRANSPORT_LE + ); + } else { + gatt = device.connectGatt( + mContext, + false, + mBluetoothGattCallback + ); + } + } catch (Exception e) { + e.printStackTrace(); + } + boolean ret = gatt != null; + if (ret) { +// putConnectedGattInMap(device.getAddress(), gatt); + setConnectingBtDevice(device); + handleBleConnection(device, BluetoothProfile.STATE_CONNECTING); + startConnectTimeout(device); + Log.d(TAG, "connect start...." + printDeviceInfo(device)); + } + return ret; + } + + @SuppressLint("MissingPermission") + public void disconnectBleDevice(BluetoothDevice device) { + if (null == device + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BleDevice bleDevice = removeConnectedBle(device); + Log.i(TAG, "disconnectBleDevice : " + printDeviceInfo(device) + ", " + bleDevice); + if (bleDevice != null) { + if (BluetoothUtil.isBluetoothEnable()) { + bleDevice.getGatt().disconnect(); +// bleDevice.getGatt().close(); + } + } else { + Log.i(TAG, "disconnectBleDevice : It is not a connected device."); + } + } + + public void writeDataByBleAsync(BluetoothDevice device, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) { + addSendTask(device, serviceUUID, characteristicUUID, data, callback); + } + + private void isBleScanning(boolean isScanning) { + isBleScanning = isScanning; + mCallbackManager.onDiscoveryBleChange(isScanning); + if (isBleScanning && configHelper.isHidDevice()) { + mHandler.sendEmptyMessage(MSG_SCAN_HID_DEVICE); + } + } + + private BleDevice getConnectedBle(BluetoothDevice device) { + if (null == device) return null; + return mConnectedGattMap.get(device.getAddress()); + } + + private void putConnectedGattInMap(String address, BluetoothGatt gatt) { + if (!BluetoothAdapter.checkBluetoothAddress(address) || null == gatt) return; + BleDevice bleDevice = new BleDevice(mContext, gatt); + bleDevice.setConnectedTime(System.currentTimeMillis()); + mConnectedGattMap.put(address, bleDevice); + if (mUsingDevice == null) { + mUsingDevice = gatt.getDevice(); + } + + Log.i(TAG, "putConnectedGattInMap >>>>>>>>>>>>> start"); + for (String addr : mConnectedGattMap.keySet()) { + Log.d(TAG, "putConnectedGattInMap >>>>>>>>>>>>> " + addr); + } + Log.i(TAG, "putConnectedGattInMap >>>>>>>>>>>>> end"); + } + + private BleDevice removeConnectedBle(BluetoothDevice device) { + if (null == device) return null; + return removeConnectedBle(device.getAddress()); + } + + private BleDevice removeConnectedBle(String address) { + if (!BluetoothAdapter.checkBluetoothAddress(address)) return null; + BleDevice bleDevice = mConnectedGattMap.remove(address); + if (null != bleDevice) { + bleDevice.stopSendDataThread(); + if (mConnectedGattMap.isEmpty()) { + setConnectedBtDevice(null); + } else if (bleDevice.getGatt().getDevice() != null && BluetoothUtil.deviceEquals(bleDevice.getGatt().getDevice(), + getConnectedBtDevice())) { + List values = getSortList(); + setConnectedBtDevice(values.get(0).getGatt().getDevice()); + } + } + return bleDevice; + } + + @NonNull + private List getSortList() { + if (mConnectedGattMap.isEmpty()) return new ArrayList<>(); + List bleDevices = new ArrayList<>(mConnectedGattMap.values()); + Collections.sort(bleDevices, (o1, o2) -> { + if (null == o1 && null == o2) return 0; + if (null == o1) return 1; + if (null == o2) return -1; + return Long.compare(o2.getConnectedTime(), o1.getConnectedTime()); + }); + return bleDevices; + } + + private void clearConnectedBleDevices() { + // if (!AppUtil.checkHasConnectPermission(mContext)) return; + if (!mConnectedGattMap.isEmpty()) { + Map clone = new HashMap<>(mConnectedGattMap); + for (String key : clone.keySet()) { + BleDevice bleDevice = clone.get(key); + if (null == bleDevice) continue; + bleDevice.getGatt().disconnect(); + bleDevice.getGatt().close(); + } + mConnectedGattMap.clear(); + } + } + + private void setConnectingBtDevice(BluetoothDevice mConnectingBtDevice) { + this.mConnectingBtDevice = mConnectingBtDevice; + } + + private void setConnectedBtDevice(BluetoothDevice mConnectedBtDevice) { + this.mUsingDevice = mConnectedBtDevice; + } + + @SuppressLint("MissingPermission") + private void filterDevice(BluetoothDevice device, int rssi, byte[] scanRecord, + boolean isBleEnableConnect) { + if ( + // AppUtil.checkHasConnectPermission(mContext) && + isBluetoothEnable() && !TextUtils.isEmpty(device.getName()) + && !mDiscoveredBleDevices.contains(device)) { + Log.d(TAG, "notify device : " + printDeviceInfo(device)); + Log.d(TAG, "device.getAddress : " + device.getAddress()); + if ("4D:9B:09:38:22:F5".equals(device.getAddress())) { + // 匹配成功 + + Log.i(TAG, "filterDevice找到了DeapSound设备"); + + // 直接连接设备 + boolean connected = connectBleDevice(device); + if (connected) { + Log.i(TAG, "成功开始连接设备: ${device.name} (${device.address})"); + } else { + Log.e(TAG, "连接设备失败: ${device.name} (${device.address})"); + } + } + mDiscoveredBleDevices.add(device); + handleDiscoveryBle(device, new BleScanInfo().setRawData(scanRecord).setRssi(rssi).setEnableConnect(isBleEnableConnect)); + } + } + + private void startConnectTimeout(BluetoothDevice device) { + if (!mHandler.hasMessages(MSG_CONNECT_BLE_TIMEOUT)) { + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CONNECT_BLE_TIMEOUT, device), CONNECT_BLE_TIMEOUT); + } + } + + private void stopConnectTimeout() { + if (mHandler.hasMessages(MSG_CONNECT_BLE_TIMEOUT)) { + mHandler.removeMessages(MSG_CONNECT_BLE_TIMEOUT); + } + } + + private void syncSystemBleDevice() { + List mSysConnectedBleList = getConnectedBleDeviceList(mContext); + if (mSysConnectedBleList != null && !mSysConnectedBleList.isEmpty()) { + for (BluetoothDevice bleDev : mSysConnectedBleList) { + if (!BluetoothUtil.deviceEquals(bleDev, mUsingDevice)) { + if (!mDiscoveredBleDevices.contains(bleDev)) { + mDiscoveredBleDevices.add(bleDev); + handleDiscoveryBle(bleDev, new BleScanInfo().setEnableConnect(true)); + } + } + } + } + } + + private void addSendTask(BluetoothDevice device, UUID serviceUUID, UUID characteristicUUID, + byte[] data, OnWriteDataCallback callback) { + boolean ret = false; + BleDevice bleDevice = getConnectedBle(device); + if (bleDevice != null) { + ret = bleDevice.addSendTask(serviceUUID, characteristicUUID, data, callback); + } + if (!ret && callback != null) { + callback.onBleResult(device, serviceUUID, characteristicUUID, false, data); + } + } + + private void wakeupSendThread(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, + int status, byte[] data) { + final BleDevice bleDevice = getConnectedBle(gatt.getDevice()); + if (bleDevice != null) { + SendBleDataThread.BleSendTask task = new SendBleDataThread.BleSendTask(gatt, serviceUUID, characteristicUUID, data, null); + task.setStatus(status); + bleDevice.wakeupSendThread(task); + } + } + + private void handleDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanInfo) { + mCallbackManager.onDiscoveryBle(device, bleScanInfo); + } + + private void handleBleConnection(final BluetoothDevice device, final int status) { + if (status == BluetoothProfile.STATE_DISCONNECTED || status == STATE_CONNECTED) { + mHandler.removeMessages(MSG_NOTIFY_BLE_TIMEOUT); + startConnectTime = 0; + } else if (status == BluetoothProfile.STATE_CONNECTING) { + startConnectTime = System.currentTimeMillis(); + } + Log.i(TAG, "handleBleConnection >> device : " + printDeviceInfo(device) + ", status : " + status); + mCallbackManager.onBleConnection(device, status); + } + + /* ---- BroadcastReceiver Handler ---- */ + private void registerReceiver() { + if (mAdapterReceiver == null) { + mAdapterReceiver = new BaseBtAdapterReceiver(); + IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); + intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); + intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); + mContext.registerReceiver(mAdapterReceiver, intentFilter); + } + } + + private void unregisterReceiver() { + if (mAdapterReceiver != null) { + mContext.unregisterReceiver(mAdapterReceiver); + mAdapterReceiver = null; + } + } + + /** + * 用于开启蓝牙BLE设备Notification服务 + * + * @param gatt 被连接的ble Gatt服务对象 + * @param serviceUUID 服务UUID + * @param characteristicUUID characteristic UUID + * @return 结果 true 则等待系统回调BLE服务 + */ + @SuppressLint("MissingPermission") + private boolean enableBLEDeviceNotification(BluetoothGatt gatt, UUID serviceUUID, UUID + characteristicUUID) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) { + Log.w(TAG, "Bluetooth gatt is null."); + return false; + } + BluetoothGattService gattService = gatt.getService(serviceUUID); + if (null == gattService) { + Log.w(TAG, "BluetoothGattService is null. uuid = " + serviceUUID); + return false; + } + BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(characteristicUUID); + if (null == characteristic) { + Log.w(TAG, "BluetoothGattCharacteristic is null. uuid = " + characteristicUUID); + return false; + } + boolean bRet = gatt.setCharacteristicNotification(characteristic, true); + if (bRet) { + bRet = false; //重置标识 + List descriptors = characteristic.getDescriptors(); + for (BluetoothGattDescriptor descriptor : descriptors) { + if (!BLE_UUID_NOTIFICATION_DESCRIPTOR.equals(descriptor.getUuid())) + continue; //跳过不相关描述符 + bRet = tryToWriteDescriptor(gatt, descriptor, 0, false); + if (!bRet) { + Log.w(TAG, "tryToWriteDescriptor failed...."); + } else { //正常只有一个描述符,使能即可 + break; + } + } + } else { + Log.w(TAG, "setCharacteristicNotification is failed...."); + } + Log.w(TAG, "enableBLEDeviceNotification ret : " + bRet + ", serviceUUID : " + serviceUUID + ", characteristicUUID : " + characteristicUUID); + return bRet; + } + + @SuppressLint("MissingPermission") + private boolean tryToWriteDescriptor(BluetoothGatt bluetoothGatt, BluetoothGattDescriptor + descriptor, int retryCount, boolean isSkipSetValue) { + // if (!AppUtil.checkHasConnectPermission(mContext)) return false; + boolean ret = isSkipSetValue; + if (!ret) { + ret = descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + Log.i(TAG, "..descriptor : .setValue ret : " + ret); + if (!ret) { + retryCount++; + if (retryCount >= 3) { + return false; + } else { + Log.i(TAG, "-tryToWriteDescriptor- : retryCount : " + retryCount + ", isSkipSetValue : false"); + SystemClock.sleep(50); + tryToWriteDescriptor(bluetoothGatt, descriptor, retryCount, false); + } + } else { + retryCount = 0; + } + } + if (ret) { + ret = bluetoothGatt.writeDescriptor(descriptor); + Log.i(TAG, "..bluetoothGatt : .writeDescriptor ret : " + ret); + if (!ret) { + retryCount++; + if (retryCount >= 3) { + return false; + } else { + Log.i(TAG, "-tryToWriteDescriptor- 2222 : retryCount : " + retryCount + ", isSkipSetValue : true"); + SystemClock.sleep(50); + tryToWriteDescriptor(bluetoothGatt, descriptor, retryCount, true); + } + } + } + return ret; + } + + + //开始调整BLE协议MTU + @SuppressLint("MissingPermission") + private void startChangeMtu(BluetoothGatt gatt, int mtu) { + if (gatt == null + // || !AppUtil.checkHasConnectPermission(mContext) + ) { + Log.w(TAG, "-startChangeMtu- param is error."); + return; + } + BluetoothDevice device = gatt.getDevice(); + if (device == null) { + Log.w(TAG, "-startChangeMtu- device is null."); + return; + } + if (mHandler.hasMessages(MSG_CHANGE_BLE_MTU_TIMEOUT)) { + Log.w(TAG, "-startChangeMtu- Adjusting the MTU for BLE"); + return; + } + boolean ret = false; + if (mtu > BluetoothConstant.BLE_MTU_MIN) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + ret = gatt.requestMtu(mtu + 3); + } else { + ret = true; + } + } + Log.d(TAG, "-startChangeMtu- ret = " + ret); + if (ret) { //调整成功,开始超时任务 + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHANGE_BLE_MTU_TIMEOUT, device), CALLBACK_TIMEOUT); + } else { + handleBleConnectedEvent(device); + } + } + + //回收调整MTU的超时任务 + private void stopChangeMtu() { + mHandler.removeMessages(MSG_CHANGE_BLE_MTU_TIMEOUT); + } + + private void handleBleConnectedEvent(final BluetoothDevice device) { + if (device == null) { + Log.e(TAG, "-handleBleConnectedEvent- device is null."); + return; + } + stopChangeMtu(); + BleDevice bleDevice = getConnectedBle(device); + bleDevice.startSendDataThread(); + handleBleConnection(device, STATE_CONNECTED); + } + + private String printDeviceInfo(BluetoothDevice device) { + return BluetoothUtil.printBtDeviceInfo(mContext, device); + } + + private final BluetoothAdapter.LeScanCallback mLeScanCallback = (device, rssi, scanRecord) -> filterDevice(device, rssi, scanRecord, true); + + private final ScanCallback mScanCallback = new ScanCallback() { + @Override + public void onScanResult(int callbackType, ScanResult result) { + if (result != null && result.getScanRecord() != null) { + BluetoothDevice device = result.getDevice(); + boolean isBleEnableConnect = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + isBleEnableConnect = result.isConnectable(); + } +// Log.i("onScanResult", printDeviceInfo(device)); + filterDevice(device, result.getRssi(), result.getScanRecord().getBytes(), isBleEnableConnect); + } + } + + @Override + public void onBatchScanResults(List results) { + + } + + @Override + public void onScanFailed(int errorCode) { + Log.d(TAG, "onScanFailed : " + errorCode); + stopLeScan(); + } + }; + + private final BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() { + + public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout, int status) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BluetoothDevice device = gatt.getDevice(); + if (null == device) return; + Log.e(TAG, "onConnectionUpdated >> device : " + printDeviceInfo(device) + ", interval : " + + interval + ", latency : " + latency + ", timeout : " + timeout + ", status : " + status); + mCallbackManager.onConnectionUpdated(device, interval, latency, timeout, status); + } + + @SuppressLint("MissingPermission") + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + final BluetoothDevice device = gatt.getDevice(); + if (null == device) return; + Log.i(TAG, String.format(Locale.getDefault(), "onConnectionStateChange : device : %s, status = %d, newState = %d.", + printDeviceInfo(device), status, newState)); + if (newState == BluetoothProfile.STATE_DISCONNECTED || newState == BluetoothProfile.STATE_DISCONNECTING + || newState == STATE_CONNECTED) { + stopConnectTimeout(); + setConnectingBtDevice(null); + if (newState == STATE_CONNECTED) { //BLE连接成功 + mRetryConnectCount = 0; + boolean ret = gatt.discoverServices(); + Log.d(TAG, "onConnectionStateChange >> discoverServices : " + ret); + putConnectedGattInMap(device.getAddress(), gatt); +// setConnectedBtDevice(device); + if (ret) { + mHandler.removeMessages(MSG_BLE_DISCOVER_SERVICES_CALLBACK_TIMEOUT); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BLE_DISCOVER_SERVICES_CALLBACK_TIMEOUT, device), CALLBACK_TIMEOUT); + } else { + disconnectBleDevice(device); + } + return; + } else { + removeConnectedBle(device); + // AppUtil.refreshBleDeviceCache(mContext, gatt); //强制更新缓存 + gatt.close(); + + long usedConnectTime = System.currentTimeMillis() - startConnectTime; //连接已耗费时间 + Log.d(TAG, "onConnectionStateChange >> usedConnectTime = " + usedConnectTime + ", limit time = " + MIN_CONNECT_TIME); + if (status == 133 && usedConnectTime < MIN_CONNECT_TIME) { //Todo: 遇到了异常断开情况, 尝试重连设备 + if (mRetryConnectCount < MAX_RETRY_CONNECT_COUNT) { + mRetryConnectCount++; + connectBleDevice(device); + return; + } else { + mRetryConnectCount = 0; + } + } + } + } + handleBleConnection(device, newState); + } + + @SuppressLint("MissingPermission") + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BluetoothDevice device = gatt.getDevice(); + if (null == device) return; + mHandler.removeMessages(MSG_BLE_DISCOVER_SERVICES_CALLBACK_TIMEOUT); + mCallbackManager.onBleServiceDiscovery(device, status, gatt.getServices()); + boolean ret = false; + if (status == BluetoothGatt.GATT_SUCCESS) { + // AppUtil.printBleGattServices(mContext, device, gatt, status); + for (BluetoothGattService service : gatt.getServices()) { + if (BLE_UUID_SERVICE.equals(service.getUuid()) && null != service.getCharacteristic(BLE_UUID_WRITE) + && null != service.getCharacteristic(BLE_UUID_NOTIFICATION)) { + Log.i(TAG, "start NotifyCharacteristicRunnable..."); + mNotifyCharacteristicRunnable = new NotifyCharacteristicRunnable(gatt, BLE_UUID_SERVICE, BLE_UUID_NOTIFICATION); + mHandler.post(mNotifyCharacteristicRunnable); + ret = true; + break; + } + } + } + Log.i(TAG, "onServicesDiscovered : " + ret); + if (!ret) { + disconnectBleDevice(device); + } + } + + @SuppressLint("MissingPermission") + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BluetoothDevice device = gatt.getDevice(); + if (null == device || null == characteristic) return; + UUID serviceUUID = null; + UUID characteristicUUID = characteristic.getUuid(); + byte[] data = characteristic.getValue(); + BluetoothGattService gattService = characteristic.getService(); + if (gattService != null) { + serviceUUID = gattService.getUuid(); + } + Log.d(TAG, String.format(Locale.getDefault(), "onCharacteristicChanged : deice : %s, serviceUuid = %s, characteristicUuid = %s, \ndata : [%s]", + printDeviceInfo(device), serviceUUID, characteristicUUID, CHexConver.byte2HexStr(data))); + mCallbackManager.onBleDataNotification(device, serviceUUID, characteristicUUID, data); + } + + @SuppressLint("MissingPermission") + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + if (null == gatt || null == gatt.getDevice() || null == characteristic + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BluetoothDevice device = gatt.getDevice(); + UUID serviceUUID = null; + UUID characteristicUUID = characteristic.getUuid(); + BluetoothGattService gattService = characteristic.getService(); + if (gattService != null) serviceUUID = gattService.getUuid(); + byte[] data = characteristic.getValue(); + Log.d(TAG, String.format(Locale.getDefault(), "onCharacteristicWrite : device : %s, serviceUuid = %s, characteristicUuid = %s, status = %d, \ndata : [%s]", + printDeviceInfo(device), serviceUUID, characteristicUUID, status, CHexConver.byte2HexStr(data))); + wakeupSendThread(gatt, serviceUUID, characteristicUUID, status, data); + mCallbackManager.onBleWriteStatus(device, serviceUUID, characteristicUUID, data, status); + } + + @SuppressLint("MissingPermission") + @Override + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BluetoothDevice device = gatt.getDevice(); + if (null == device || null == descriptor) return; + UUID serviceUuid = null; + UUID characteristicUuid = null; + BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic(); + if (null != characteristic) { + characteristicUuid = characteristic.getUuid(); + BluetoothGattService bluetoothGattService = characteristic.getService(); + if (null != bluetoothGattService) { + serviceUuid = bluetoothGattService.getUuid(); + } + } + Log.i(TAG, String.format(Locale.getDefault(), "onDescriptorWrite : device : %s, serviceUuid = %s, characteristicUuid = %s, descriptor = %s, status = %d", + printDeviceInfo(device), serviceUuid, characteristicUuid, descriptor.getUuid(), status)); + mCallbackManager.onBleNotificationStatus(device, serviceUuid, characteristicUuid, status); + if (mNotifyCharacteristicRunnable != null && BluetoothUtil.deviceEquals(device, mNotifyCharacteristicRunnable.getBleDevice()) + && serviceUuid != null && serviceUuid.equals(mNotifyCharacteristicRunnable.getServiceUUID()) + && characteristicUuid != null && characteristicUuid.equals(mNotifyCharacteristicRunnable.getCharacteristicUUID()) + && descriptor.getUuid() != null && descriptor.getUuid().equals(mNotifyCharacteristicRunnable.mDescriptorUUID)) { + if (status == BluetoothGatt.GATT_SUCCESS) { + mNotifyCharacteristicRunnable = null; + // TODO: 2022/6/28 由于部分手机(小米11 Lite)的兼容性问题,MTU不能调整到最大,建议适当减小MTU +// startChangeMtu(gatt, 128); //调整MTU最大为128 + int requestMTU = configHelper.getBleRequestMtu(); + if (requestMTU > 509) { + requestMTU = 509; + } + startChangeMtu(gatt, requestMTU); +// handleBleConnectedEvent(device); + } else { + int num = mNotifyCharacteristicRunnable.getRetryNum(); + if (num < 3) { + mNotifyCharacteristicRunnable.setRetryNum(++num); + mHandler.postDelayed(mNotifyCharacteristicRunnable, 100); + } else { + disconnectBleDevice(device); + } + } + } + } + + @SuppressLint("MissingPermission") + @Override + public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { + if (null == gatt + // || !AppUtil.checkHasConnectPermission(mContext) + ) return; + BluetoothDevice device = gatt.getDevice(); + if (null == device) return; + Log.d(TAG, String.format(Locale.getDefault(), "onMtuChanged : device : %s, mtu = %d, status = %d", printDeviceInfo(device), mtu, status)); + mCallbackManager.onBleDataBlockChanged(device, mtu, status); + BleDevice bleDevice = getConnectedBle(device); + if (BluetoothGatt.GATT_SUCCESS == status) { + // 需要减去3个字节的数据包头部信息 + int bleMtu = mtu - 3; + if (bleDevice != null && mHandler.hasMessages(MSG_CHANGE_BLE_MTU_TIMEOUT)) { //调整MTU的回调 + stopChangeMtu(); + bleDevice.setMtu(bleMtu); + Log.i(TAG, "-onMtuChanged- handleBleConnectedEvent"); + handleBleConnectedEvent(device); + } + } + } + }; + + private class BaseBtAdapterReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (intent != null) { + String action = intent.getAction(); + if (action == null) return; + switch (action) { + case BluetoothAdapter.ACTION_STATE_CHANGED: { + int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, -1); + if (mBluetoothAdapter != null && state == -1) { + state = mBluetoothAdapter.getState(); + } + if (state == BluetoothAdapter.STATE_OFF) { + isBleScanning(false); + mDiscoveredBleDevices.clear(); + mCallbackManager.onDiscoveryBleChange(false); + disconnectBleDevice(getConnectedBtDevice()); + mCallbackManager.onAdapterChange(false); + } else if (state == BluetoothAdapter.STATE_ON) { + mCallbackManager.onAdapterChange(true); + } + break; + } + case BluetoothDevice.ACTION_ACL_CONNECTED: { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + Log.i(TAG, "BaseBtAdapterReceiver: ACTION_ACL_CONNECTED, device : " + + printDeviceInfo(device)); + break; + } + case BluetoothDevice.ACTION_ACL_DISCONNECTED: { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + Log.i(TAG, "BaseBtAdapterReceiver: ACTION_ACL_DISCONNECTED, device : " + + printDeviceInfo(device)); + break; + } + + } + } + } + } + + private class NotifyCharacteristicRunnable implements Runnable { + private final BluetoothGatt mGatt; + private final UUID mServiceUUID; + private final UUID mCharacteristicUUID; + public final UUID mDescriptorUUID = BLE_UUID_NOTIFICATION_DESCRIPTOR; + private int retryNum = 0; + + private NotifyCharacteristicRunnable(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID) { + this.mGatt = gatt; + this.mServiceUUID = serviceUUID; + this.mCharacteristicUUID = characteristicUUID; + } + + private void setRetryNum(int retryNum) { + this.retryNum = retryNum; + } + + private int getRetryNum() { + return retryNum; + } + + private BluetoothDevice getBleDevice() { + if (mGatt == null) return null; + return mGatt.getDevice(); + } + + private UUID getServiceUUID() { + return mServiceUUID; + } + + private UUID getCharacteristicUUID() { + return mCharacteristicUUID; + } + + @Override + public void run() { + boolean ret = enableBLEDeviceNotification(mGatt, mServiceUUID, mCharacteristicUUID); + Log.w(TAG, String.format(Locale.getDefault(), "enableBLEDeviceNotification ===> %s, service uuid = %s, characteristic uuid = %s", + ret, mServiceUUID, mCharacteristicUUID)); + if (!ret) { + if (mGatt != null) { + disconnectBleDevice(mGatt.getDevice()); + } + } else { + mHandler.removeMessages(MSG_NOTIFY_BLE_TIMEOUT); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_NOTIFY_BLE_TIMEOUT, mGatt.getDevice()), CALLBACK_TIMEOUT); + } + } + } +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/SendBleDataThread.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/SendBleDataThread.java new file mode 100644 index 000000000..c095bdddd --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/SendBleDataThread.java @@ -0,0 +1,295 @@ +package com.jieli.otasdk.tool.ota.ble; + +import android.bluetooth.BluetoothGatt; + +import com.jieli.jl_bt_ota.util.JL_Log; +import com.jieli.otasdk.tool.ota.ble.interfaces.IBleOp; +import com.jieli.otasdk.tool.ota.ble.interfaces.OnThreadStateListener; +import com.jieli.otasdk.tool.ota.ble.interfaces.OnWriteDataCallback; + +import java.util.Arrays; +import java.util.UUID; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * 发送BLE数据线程 + * + * @author zqjasonZhong + * @date 2019/10/8 + */ +public class SendBleDataThread extends Thread { + private final static String TAG = "SendBleDataThread"; + private final LinkedBlockingQueue mQueue = new LinkedBlockingQueue<>(); + private volatile boolean isDataSend = false; + private volatile boolean isThreadWaiting = false; + private volatile boolean isWaitingForCallback = false; + private volatile int retryNum = 0; + private final IBleOp mBleManager; + private final OnThreadStateListener mListener; + + private BleSendTask mCurrentTask; + + public SendBleDataThread(IBleOp manager, OnThreadStateListener listener) { + super(TAG); + mBleManager = manager; + mListener = listener; + } + + public boolean isRunning() { + return isDataSend; + } + + public boolean addSendTask(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) { + if (null == mBleManager || null == gatt || null == serviceUUID || null == characteristicUUID || null == data || data.length == 0) { + return false; + } + int mtu = mBleManager.getBleMtu(); + JL_Log.d(TAG, "addSendTask : " + mtu); + int dataLen = data.length; + int blockCount = dataLen / mtu; + boolean ret = false; + for (int i = 0; i < blockCount; i++) { + byte[] mBlockData = new byte[mtu]; + System.arraycopy(data, i * mtu, mBlockData, 0, mBlockData.length); + ret = addSendData(gatt, serviceUUID, characteristicUUID, mBlockData, callback); + } + + if (0 != dataLen % mtu) { + JL_Log.d(TAG, "addSendTask : " + mtu); + byte[] noBlockData = new byte[dataLen % mtu]; + System.arraycopy(data, dataLen - dataLen % mtu, noBlockData, 0, noBlockData.length); + ret = addSendData(gatt, serviceUUID, characteristicUUID, noBlockData, callback); + } + return ret; + } + + public void wakeupSendThread(BleSendTask sendTask) { + if (null == sendTask || mCurrentTask != null && mCurrentTask.equals(sendTask)) { + if (sendTask != null) { + sendTask.setCallback(mCurrentTask.getCallback()); + mCurrentTask = sendTask; + } + synchronized (mQueue) { + if (isThreadWaiting) { + if (isWaitingForCallback) { + mQueue.notifyAll(); + } else { + mQueue.notify(); + } + } else if (isWaitingForCallback) { + mQueue.notify(); + } + } + } + } + + private boolean addSendData(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) { + boolean ret = false; + if (isDataSend) { + BleSendTask sendTask = new BleSendTask(gatt, serviceUUID, characteristicUUID, data, callback); + try { + mQueue.put(sendTask); + ret = true; + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (ret && isThreadWaiting && !isWaitingForCallback) { + isThreadWaiting = false; + synchronized (mQueue) { + mQueue.notify(); + } + } + } + return ret; + } + + @Override + public synchronized void start() { + isDataSend = true; + super.start(); + } + + public synchronized void stopThread() { + isDataSend = false; + wakeupSendThread(null); + } + + private void callbackResult(BleSendTask task, boolean result) { + if (task != null && task.getCallback() != null) { + if (task.getBleGatt() == null) return; + task.getCallback().onBleResult(task.getBleGatt().getDevice(), task.getServiceUUID(), + task.getCharacteristicUUID(), result, task.getData()); + } else { + JL_Log.i(TAG, "getCallback is null."); + } + } + + @Override + public void run() { + JL_Log.d(TAG, "send ble data thread is started."); + if (mListener != null) { + mListener.onStart(getId(), getName()); + } + if (mBleManager != null) { + synchronized (mQueue) { + while (isDataSend) { + mCurrentTask = null; + isThreadWaiting = false; + isWaitingForCallback = false; + if (mQueue.isEmpty()) { + isThreadWaiting = true; + JL_Log.d(TAG, "queue is empty, so waiting for data"); + try { + mQueue.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + mCurrentTask = mQueue.peek(); + if (mCurrentTask != null) { + isWaitingForCallback = mBleManager.writeDataByBle(mCurrentTask.mGatt, mCurrentTask.getServiceUUID(), + mCurrentTask.getCharacteristicUUID(), mCurrentTask.getData()); + if (isWaitingForCallback) { + try { + mQueue.wait(BleManager.SEND_DATA_MAX_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + mCurrentTask.setStatus(-1); + } + JL_Log.d(TAG, "data send ret :" + mCurrentTask.getStatus()); + if (mCurrentTask.getStatus() != BluetoothGatt.GATT_SUCCESS) { //发送失败 + retryNum++; + if (retryNum >= 3) { //重发次数超过限制 + callbackResult(mCurrentTask, false); + mQueue.clear(); + } else { + if (mCurrentTask.getStatus() != -1) { + mCurrentTask.setStatus(-1); + try { + sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + continue; + } + } else { //发送成功 + callbackResult(mCurrentTask, true); + } + } + retryNum = 0; + if (!mQueue.isEmpty()) mQueue.poll(); + } + } + } + + isWaitingForCallback = false; + isThreadWaiting = false; + mQueue.clear(); + if (mListener != null) { + mListener.onEnd(getId(), getName()); + } + JL_Log.d(TAG, "send ble data thread exit."); + } + } + + + public static class BleSendTask { + private BluetoothGatt mGatt; + private UUID serviceUUID; + private UUID characteristicUUID; + private byte[] data; + private int status = -1; + private OnWriteDataCallback mCallback; + + public BleSendTask(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) { + this.mGatt = gatt; + this.serviceUUID = serviceUUID; + this.characteristicUUID = characteristicUUID; + this.data = data; + this.mCallback = callback; + } + + public BluetoothGatt getBleGatt() { + return mGatt; + } + + public void setDevice(BluetoothGatt gatt) { + mGatt = gatt; + } + + public UUID getServiceUUID() { + return serviceUUID; + } + + public void setServiceUUID(UUID serviceUUID) { + this.serviceUUID = serviceUUID; + } + + public UUID getCharacteristicUUID() { + return characteristicUUID; + } + + public void setCharacteristicUUID(UUID characteristicUUID) { + this.characteristicUUID = characteristicUUID; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + public OnWriteDataCallback getCallback() { + return mCallback; + } + + public void setCallback(OnWriteDataCallback callback) { + mCallback = callback; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + @Override + public String toString() { + return "BleSendTask{" + + "mGatt=" + mGatt + + ", serviceUUID=" + serviceUUID + + ", characteristicUUID=" + characteristicUUID + + ", data=" + Arrays.toString(data) + + ", status=" + status + + ", mCallback=" + mCallback + + '}'; + } + + @Override + public int hashCode() { + if (mGatt != null && serviceUUID != null && characteristicUUID != null) { + return mGatt.hashCode() + serviceUUID.hashCode() + characteristicUUID.hashCode(); + } + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof BleSendTask) { + BleSendTask other = (BleSendTask) obj; + if (mGatt != null && serviceUUID != null && characteristicUUID != null) { + return mGatt.equals(other.getBleGatt()) && serviceUUID.equals(other.getServiceUUID()) + && characteristicUUID.equals(other.getCharacteristicUUID()); + } + } + return false; + } + } +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/BleEventCallback.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/BleEventCallback.java new file mode 100644 index 000000000..99569b3b7 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/BleEventCallback.java @@ -0,0 +1,68 @@ +package com.jieli.otasdk.tool.ota.ble.interfaces; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGattService; + +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo; + +import java.util.List; +import java.util.UUID; + +/** + * Ble事件回调抽象类 + * + * @author zqjasonZhong + * @since 2020/7/16 + */ +public abstract class BleEventCallback implements IBleEventCallback { + + @Override + public void onAdapterChange(boolean bEnabled) { + + } + + @Override + public void onDiscoveryBleChange(boolean bStart) { + + } + + @Override + public void onDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanMessage) { + + } + + @Override + public void onBleConnection(BluetoothDevice device, int status) { + + } + + @Override + public void onBleServiceDiscovery(BluetoothDevice device, int status, List services) { + + } + + @Override + public void onBleNotificationStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid, int status) { + + } + + @Override + public void onBleDataBlockChanged(BluetoothDevice device, int block, int status) { + + } + + @Override + public void onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data) { + + } + + @Override + public void onBleWriteStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data, int status) { + + } + + @Override + public void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status) { + + } +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleEventCallback.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleEventCallback.java new file mode 100644 index 000000000..b001e61f3 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleEventCallback.java @@ -0,0 +1,108 @@ +package com.jieli.otasdk.tool.ota.ble.interfaces; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGattService; + +import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo; + +import java.util.List; +import java.util.UUID; + +/** + * Ble事件回调 + * + * @author zqjasonZhong + * @since 2020/7/16 + */ +public interface IBleEventCallback { + + /** + * 蓝牙适配器开关回调 + * + * @param bEnabled 开关 + */ + void onAdapterChange(boolean bEnabled); + + /** + * 搜索蓝牙设备的状态回调 + * + * @param bStart 搜索状态 + */ + void onDiscoveryBleChange(boolean bStart); + + /** + * 发现蓝牙设备的回调 + * + * @param device 蓝牙设备对象 + * @param bleScanInfo BLE扫描数据 + */ + void onDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanInfo); + + /** + * BLE连接状态回调 + * + * @param device 蓝牙设备对象 + * @param status 连接状态 + */ + void onBleConnection(BluetoothDevice device, int status); + + /** + * BLE服务发现回调 + * + * @param device 蓝牙设备对象 + * @param status 状态 + * @param services 服务列表 + */ + void onBleServiceDiscovery(BluetoothDevice device, int status, List services); + + /** + * BLE特征状态回调 + * + * @param device 蓝牙设备对象 + * @param serviceUuid 服务UUID + * @param characteristicUuid 特征值UUID + * @param status 状态 + */ + void onBleNotificationStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid, int status); + + /** + * BLE MTU改变回调 + * + * @param device 蓝牙设备对象 + * @param block 协商后的MTU + * @param status 状态 + */ + void onBleDataBlockChanged(BluetoothDevice device, int block, int status); + + /** + * BLE数据回调 + * + * @param device 蓝牙设备对象 + * @param serviceUuid 服务UUID + * @param characteristicsUuid 特征值UUID + * @param data 数据 + */ + void onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data); + + /** + * BLE 写数据回调 + * + * @param device 蓝牙设备对象 + * @param serviceUuid 服务UUID + * @param characteristicsUuid 特征值UUID + * @param data 数据 + * @param status 状态 + */ + void onBleWriteStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data, int status); + + /** + * BLE 连接参数回调 + * + * @param device 蓝牙设备对象 + * @param interval 发数间隔 + * @param latency 延时参数 + * @param timeout 超时时间 + * @param status 状态 + */ + void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status); +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleOp.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleOp.java new file mode 100644 index 000000000..212910aba --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleOp.java @@ -0,0 +1,16 @@ +package com.jieli.otasdk.tool.ota.ble.interfaces; + +import android.bluetooth.BluetoothGatt; + +import java.util.UUID; + +/** + * @author zqjasonZhong + * @since 2020/12/24 + */ +public interface IBleOp { + + int getBleMtu(); + + boolean writeDataByBle(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data); +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnThreadStateListener.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnThreadStateListener.java new file mode 100644 index 000000000..87ba5326a --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnThreadStateListener.java @@ -0,0 +1,14 @@ +package com.jieli.otasdk.tool.ota.ble.interfaces; + +/** + * 线程生命周期监听器 + * + * @author zqjasonZhong + * @date 2019/9/20 + */ +public interface OnThreadStateListener { + + void onStart(long id, String name); + + void onEnd(long id, String name); +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnWriteDataCallback.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnWriteDataCallback.java new file mode 100644 index 000000000..2d0f716b0 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnWriteDataCallback.java @@ -0,0 +1,25 @@ +package com.jieli.otasdk.tool.ota.ble.interfaces; + +import android.bluetooth.BluetoothDevice; + +import java.util.UUID; + +/** + * 写数据的结果回调 + * + * @author zqjasonZhong + * @date 2019/9/25 + */ +public interface OnWriteDataCallback { + + /** + * 回调BLE发送结果 + * + * @param device 蓝牙设备 + * @param serviceUUID 服务UUID + * @param characteristicUUID 特征值UUID + * @param result 发送结果 + * @param data 发送数据 + */ + void onBleResult(BluetoothDevice device, UUID serviceUUID, UUID characteristicUUID, boolean result, byte[] data); +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleDevice.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleDevice.java new file mode 100644 index 000000000..894cb07da --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleDevice.java @@ -0,0 +1,155 @@ +package com.jieli.otasdk.tool.ota.ble.model; + +import android.annotation.SuppressLint; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.jieli.jl_bt_ota.constant.BluetoothConstant; +import com.jieli.jl_bt_ota.util.CHexConver; + +import com.jieli.otasdk.tool.ota.ble.SendBleDataThread; +import com.jieli.otasdk.tool.ota.ble.interfaces.IBleOp; +import com.jieli.otasdk.tool.ota.ble.interfaces.OnThreadStateListener; +import com.jieli.otasdk.tool.ota.ble.interfaces.OnWriteDataCallback; +//import com.jieli.otasdk.util.AppUtil; + +import java.util.UUID; +import android.util.Log; +/** + * @author zqjasonZhong + * @email zhongzhuocheng@zh-jieli.com + * @desc BLE设备 + * @since 2022/12/5 + */ +public class BleDevice { + private final String tag = "BleManager"; + private final Context context; //上下文 + private final BluetoothGatt gatt; //BleGatt控制对象 + private int mtu = BluetoothConstant.BLE_MTU_MIN; //MTU + private long connectedTime; //连接的时间戳 + + private SendBleDataThread sendDataThread; //发送数据线程 + + public BleDevice(@NonNull Context context, @NonNull BluetoothGatt gatt) { + this.context = context; + this.gatt = gatt; + } + + @NonNull + public BluetoothGatt getGatt() { + return gatt; + } + + public int getMtu() { + if (mtu > 128) { + mtu -= 6; + } + return mtu; + } + + public void setMtu(int mtu) { + this.mtu = mtu; + } + + public long getConnectedTime() { + return connectedTime; + } + + public void setConnectedTime(long connectedTime) { + this.connectedTime = connectedTime; + } + + public void startSendDataThread() { + if (sendDataThread == null || !sendDataThread.isRunning()) { + sendDataThread = new SendBleDataThread(new IBleOp() { + @Override + public int getBleMtu() { + return getMtu(); + } + + @Override + public boolean writeDataByBle(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data) { + Log.d(tag, "writeDataByBle " + gatt +"serviceUUID "+ serviceUUID + "characteristicUUID "+ characteristicUUID + data ); + return writeDataToDeviceByBle(gatt, serviceUUID, characteristicUUID, data); + } + }, new OnThreadStateListener() { + @Override + public void onStart(long id, String name) { + + } + + @Override + public void onEnd(long id, String name) { + if (sendDataThread != null && sendDataThread.getId() == id) { + sendDataThread = null; + } + } + }); + sendDataThread.start(); + } + } + + public void stopSendDataThread() { + if (sendDataThread != null) { + sendDataThread.stopThread(); + } + } + + public void wakeupSendThread(SendBleDataThread.BleSendTask task) { + if (sendDataThread != null && task != null && gatt.equals(task.getBleGatt())) { + sendDataThread.wakeupSendThread(task); + } + } + + public boolean addSendTask(UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) { + boolean ret = false; + if (sendDataThread != null && sendDataThread.isRunning()) { + ret = sendDataThread.addSendTask(gatt, serviceUUID, characteristicUUID, data, callback); + } + return ret; + } + + @SuppressLint("MissingPermission") + private boolean writeDataToDeviceByBle(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data) { + if (gatt == null || null == serviceUUID || null == characteristicUUID || null == data || data.length == 0 + // || !AppUtil.checkHasConnectPermission(this.context) + ) { + Log.d(tag, "writeDataByBle : param is invalid."); + return false; + } + BluetoothGattService gattService = gatt.getService(serviceUUID); + if (null == gattService) { + Log.d(tag, "writeDataByBle : service is null."); + return false; + } + BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(characteristicUUID); + if (null == gattCharacteristic) { + Log.d(tag, "writeDataByBle : characteristic is null"); + return false; + } + boolean ret = false; + try { + gattCharacteristic.setValue(data); + ret = gatt.writeCharacteristic(gattCharacteristic); + } catch (Exception e) { + e.printStackTrace(); + } + Log.d(tag, "writeDataByBle : send ret : " + ret + ", data = " + CHexConver.byte2HexStr(data)); + return ret; + } + + @Override + public String toString() { + return "BleDevice{" + + "context=" + context + + ", gatt=" + gatt + + ", mtu=" + mtu + + ", connectedTime=" + connectedTime + + ", sendDataThread=" + sendDataThread + + '}'; + } +} diff --git a/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleScanInfo.java b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleScanInfo.java new file mode 100644 index 000000000..863e28594 --- /dev/null +++ b/local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleScanInfo.java @@ -0,0 +1,99 @@ +package com.jieli.otasdk.tool.ota.ble.model; + + +import android.os.Parcel; +import android.os.Parcelable; + +import com.jieli.jl_bt_ota.util.CHexConver; + +/** + * BLE 设备扫描信息 + *

+ * Created by zqjasonzhong on 2018/10/17. + */ + +public class BleScanInfo implements Parcelable { + /** + * 原始数据 + */ + private byte[] rawData; + /** + * 信号强度 + */ + private int rssi; + /** + * 是否允许连接 + *

说明: 默认允许连接,特殊情况不允许

+ */ + private boolean isEnableConnect = true; + + public BleScanInfo() { + + } + + protected BleScanInfo(Parcel in) { + rawData = in.createByteArray(); + rssi = in.readInt(); + isEnableConnect = in.readByte() != 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public BleScanInfo createFromParcel(Parcel in) { + return new BleScanInfo(in); + } + + @Override + public BleScanInfo[] newArray(int size) { + return new BleScanInfo[size]; + } + }; + + public byte[] getRawData() { + return rawData; + } + + public BleScanInfo setRawData(byte[] rawData) { + this.rawData = rawData; + return this; + } + + public int getRssi() { + return rssi; + } + + public BleScanInfo setRssi(int rssi) { + this.rssi = rssi; + return this; + } + + public boolean isEnableConnect() { + return isEnableConnect; + } + + public BleScanInfo setEnableConnect(boolean enableConnect) { + isEnableConnect = enableConnect; + return this; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByteArray(rawData); + dest.writeInt(rssi); + dest.writeByte((byte) (isEnableConnect ? 1 : 0)); + } + + @Override + public String toString() { + return "BleScanMessage{" + + "rawData=" + CHexConver.byte2HexStr(rawData) + + ", rssi=" + rssi + + ", isEnableConnect=" + isEnableConnect + + '}'; + } +} diff --git a/local_plugins/ota/ios/.gitignore b/local_plugins/ota/ios/.gitignore new file mode 100644 index 000000000..034771fc9 --- /dev/null +++ b/local_plugins/ota/ios/.gitignore @@ -0,0 +1,38 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/ephemeral/ +/Flutter/flutter_export_environment.sh diff --git a/local_plugins/ota/ios/Assets/.gitkeep b/local_plugins/ota/ios/Assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/local_plugins/ota/ios/Classes/OtaPlugin.swift b/local_plugins/ota/ios/Classes/OtaPlugin.swift new file mode 100644 index 000000000..8b67367c7 --- /dev/null +++ b/local_plugins/ota/ios/Classes/OtaPlugin.swift @@ -0,0 +1,19 @@ +import Flutter +import UIKit + +public class OtaPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "ota", binaryMessenger: registrar.messenger()) + let instance = OtaPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getPlatformVersion": + result("iOS " + UIDevice.current.systemVersion) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/local_plugins/ota/ios/Resources/PrivacyInfo.xcprivacy b/local_plugins/ota/ios/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..a34b7e2e6 --- /dev/null +++ b/local_plugins/ota/ios/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/local_plugins/ota/ios/ota.podspec b/local_plugins/ota/ios/ota.podspec new file mode 100644 index 000000000..ecbf38449 --- /dev/null +++ b/local_plugins/ota/ios/ota.podspec @@ -0,0 +1,29 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint ota.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'ota' + s.version = '0.0.1' + s.summary = 'A new Flutter project.' + s.description = <<-DESC +A new Flutter project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '12.0' + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' + + # If your plugin requires a privacy manifest, for example if it uses any + # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your + # plugin's privacy impact, and then uncomment this line. For more information, + # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files + # s.resource_bundles = {'ota_privacy' => ['Resources/PrivacyInfo.xcprivacy']} +end diff --git a/local_plugins/ota/lib/ota.dart b/local_plugins/ota/lib/ota.dart new file mode 100644 index 000000000..d3d2606f1 --- /dev/null +++ b/local_plugins/ota/lib/ota.dart @@ -0,0 +1,19 @@ +import 'ota_platform_interface.dart'; + +class Ota { + Future getPlatformVersion() { + return OtaPlatform.instance.getPlatformVersion(); + } + + Future searchDevices() { + return OtaPlatform.instance.searchDevices(); + } + + Future connectDevice() { + return OtaPlatform.instance.connectDevice(); + } + + Future startUpgrade() { + return OtaPlatform.instance.startUpgrade(); + } +} diff --git a/local_plugins/ota/lib/ota_method_channel.dart b/local_plugins/ota/lib/ota_method_channel.dart new file mode 100644 index 000000000..56e8fde86 --- /dev/null +++ b/local_plugins/ota/lib/ota_method_channel.dart @@ -0,0 +1,34 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'ota_platform_interface.dart'; + +/// An implementation of [OtaPlatform] that uses method channels. +class MethodChannelOta extends OtaPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('ota'); + + @override + Future getPlatformVersion() async { + final version = await methodChannel.invokeMethod( + 'getPlatformVersion', + ); + return version; + } + + Future searchDevices() async { + final version = await methodChannel.invokeMethod('searchDevices'); + return version; + } + + Future connectDevice() async { + final version = await methodChannel.invokeMethod('connectDevice'); + return version; + } + + Future startUpgrade() async { + final version = await methodChannel.invokeMethod('startUpgrade'); + return version; + } +} diff --git a/local_plugins/ota/lib/ota_platform_interface.dart b/local_plugins/ota/lib/ota_platform_interface.dart new file mode 100644 index 000000000..77ade98ad --- /dev/null +++ b/local_plugins/ota/lib/ota_platform_interface.dart @@ -0,0 +1,41 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'ota_method_channel.dart'; + +abstract class OtaPlatform extends PlatformInterface { + /// Constructs a OtaPlatform. + OtaPlatform() : super(token: _token); + + static final Object _token = Object(); + + static OtaPlatform _instance = MethodChannelOta(); + + /// The default instance of [OtaPlatform] to use. + /// + /// Defaults to [MethodChannelOta]. + static OtaPlatform get instance => _instance; + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [OtaPlatform] when + /// they register themselves. + static set instance(OtaPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + Future getPlatformVersion() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } + + Future searchDevices() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } + + Future connectDevice() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } + + Future startUpgrade() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } +} diff --git a/local_plugins/ota/pubspec.yaml b/local_plugins/ota/pubspec.yaml new file mode 100644 index 000000000..cb281e3be --- /dev/null +++ b/local_plugins/ota/pubspec.yaml @@ -0,0 +1,72 @@ +name: ota +description: "A new Flutter project." +version: 0.0.1 +homepage: + +environment: + sdk: ^3.7.2 + flutter: '>=3.3.0' + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # which should be registered in the plugin registry. This is required for + # using method channels. + # The Android 'package' specifies package in which the registered class is. + # This is required for using method channels on Android. + # The 'ffiPlugin' specifies that native code should be built and bundled. + # This is required for using `dart:ffi`. + # All these are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.example.ota + pluginClass: OtaPlugin + ios: + pluginClass: OtaPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/to/asset-from-package + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/to/font-from-package diff --git a/pubspec.yaml b/pubspec.yaml index 55f6887b5..8c59349d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -75,7 +75,8 @@ dependencies: path: local_plugins/chat_storage spotify_sdk: path: local_plugins/spotify_sdk - + ota: + path: local_plugins/ota jl_ota: path: local_plugins/jl_ota ble_service: