Browse Source

加入ota升级demo,待测试

newdev_shunjiawei
fdp 1 year ago
parent
commit
4c88268340
  1. 1
      android/app/build.gradle.kts
  2. 1
      lib/core/translations/language/zh_cn.dart
  3. 2
      lib/data/services/ble_manager.dart
  4. 4
      lib/modules/login/controllers/login_controller.dart
  5. 104
      lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart
  6. 3
      lib/modules/translation/controllers/translation_controller.dart
  7. 6
      lib/modules/translation/views/translation_view.dart
  8. 1
      local_plugins/jieli/android/build.gradle.kts
  9. 33
      local_plugins/jl_ota/.gitignore
  10. 33
      local_plugins/jl_ota/.metadata
  11. 3
      local_plugins/jl_ota/CHANGELOG.md
  12. 1
      local_plugins/jl_ota/LICENSE
  13. 15
      local_plugins/jl_ota/README.md
  14. 4
      local_plugins/jl_ota/analysis_options.yaml
  15. 9
      local_plugins/jl_ota/android/.gitignore
  16. 71
      local_plugins/jl_ota/android/build.gradle
  17. BIN
      local_plugins/jl_ota/android/libs/jl_bt_ota_V1.9.0-release.aar
  18. BIN
      local_plugins/jl_ota/android/libs/jl_bt_ota_V1.9.2-release.aar
  19. 1
      local_plugins/jl_ota/android/settings.gradle
  20. 3
      local_plugins/jl_ota/android/src/main/AndroidManifest.xml
  21. 279
      local_plugins/jl_ota/android/src/main/kotlin/com/yunqiinnovation/jl_ota/JlOtaPlugin.kt
  22. 38
      local_plugins/jl_ota/ios/.gitignore
  23. 0
      local_plugins/jl_ota/ios/Assets/.gitkeep
  24. 19
      local_plugins/jl_ota/ios/Classes/JlOtaPlugin.swift
  25. 14
      local_plugins/jl_ota/ios/Resources/PrivacyInfo.xcprivacy
  26. 29
      local_plugins/jl_ota/ios/jl_ota.podspec
  27. 8
      local_plugins/jl_ota/lib/jl_ota.dart
  28. 17
      local_plugins/jl_ota/lib/jl_ota_method_channel.dart
  29. 29
      local_plugins/jl_ota/lib/jl_ota_platform_interface.dart
  30. 72
      local_plugins/jl_ota/pubspec.yaml
  31. 2
      pubspec.yaml

1
android/app/build.gradle.kts

@ -5,6 +5,7 @@ repositories {
mavenCentral()
flatDir {
dirs(project(":spotify_sdk").projectDir.resolve("libs"))
dirs(project(":jl_ota").projectDir.resolve("libs"))
}
}

1
lib/core/translations/language/zh_cn.dart

@ -123,6 +123,7 @@ const Map<String, String> zhCN = {
"allRoundAssistant": "全能助理",
"allRoundAssistantInfo": "帮你解决各类问题",
"simultaneousTranslation": "同声翻译",
"faceToFaceTranslation": "面对面翻译",
'audioVideoTranslation': '音视频翻译',
'callTranslation': '通话翻译',
"simultaneousTranslationInfo": "实时翻译80+种语言",

2
lib/data/services/ble_manager.dart

@ -54,7 +54,7 @@ class DeviceInfo {
this.rightEarCharging = false,
this.caseCharging = false,
this.firmwareVersion = '',
this.firmwareProductId = '',
this.firmwareProductId = 's3',
this.firmwareProductColor = '',
DateTime? lastUpdated,
}) : lastUpdated = lastUpdated ?? DateTime.now();

4
lib/modules/login/controllers/login_controller.dart

@ -695,8 +695,8 @@ class LoginController extends GetxController {
await _storage.write("logintoken", response['token'].toString());
// 存储到 SharedPreferences (仅存储用户数据)
//final prefs = await GetStorage();
await _storage.write(
'user', jsonEncode(user.toJson())); // 使用 user.toJson()
await _storage.write('user_info', user.toJson());
//获取app的配置信息
await getAppConfig();
Get.offAllNamed(Routes.pairing);

104
lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart

@ -7,6 +7,7 @@ import '../model/ota_upgrade_model.dart';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:jl_ota/jl_ota.dart';
import '../../../data/services/ble_manager.dart';
class OtaUpgradeController extends GetxController {
@ -40,6 +41,8 @@ class OtaUpgradeController extends GetxController {
Future<void> startUpdate() async {
try {
isUpdating.value = true;
checkUpdate();
// 实现更新逻辑...
} catch (e) {
errorMessage.value = e.toString();
@ -50,64 +53,68 @@ class OtaUpgradeController extends GetxController {
}
Future<void> _getCurrentVersion() async {
try {
// 添加获取设备信息的重试机制
DeviceInfo? deviceInfo = _bleManager.deviceInfo.value;
JlOta().getPlatformVersion();
//try {
// 第一次检查设备信息
if (deviceInfo == null) {
// 显示加载提示
isFetchingDeviceInfo.value = true;
// // 添加获取设备信息的重试机制
// DeviceInfo? deviceInfo = _bleManager.deviceInfo.value;
// 尝试重新获取设备信息
await _bleManager.fetchDeviceInfo();
// // 第一次检查设备信息
// if (deviceInfo == null) {
// // 显示加载提示
// isFetchingDeviceInfo.value = true;
// 等待后再次获取设备信息
deviceInfo = _bleManager.deviceInfo.value;
isFetchingDeviceInfo.value = false;
// // 尝试重新获取设备信息
// await _bleManager.fetchDeviceInfo();
// 仍然为空则抛出异常
if (deviceInfo == null) {
throw const FormatException('无法获取设备信息,请检查设备连接');
}
}
// // 等待后再次获取设备信息
// deviceInfo = _bleManager.deviceInfo.value;
// isFetchingDeviceInfo.value = false;
// 检查固件信息有效性
if (deviceInfo.firmwareVersion.isEmpty ||
deviceInfo.firmwareProductId.isEmpty) {
throw const FormatException('设备固件信息不完整');
}
// // 仍然为空则抛出异常
// if (deviceInfo == null) {
// throw const FormatException('无法获取设备信息,请检查设备连接');
// }
// }
// 正常流程
currentVersion.value = deviceInfo.firmwareVersion;
// // 检查固件信息有效性
// if (deviceInfo.firmwareVersion.isEmpty
// // ||
// // deviceInfo.firmwareProductId.isEmpty
// ) {
// throw const FormatException('设备固件信息不完整');
// }
// API请求
final response = await Api.getequipmentinfo({
"id": deviceInfo.firmwareProductId,
});
// // 正常流程
// currentVersion.value = "0"; //deviceInfo.firmwareVersion;
// 处理API响应
if (response['info'] == null) {
throw const FormatException('API 响应格式错误');
}
// // API请求
// final response = await Api.getequipmentinfo({
// "id": "s3",
// });
final resp = OtaConfigResp.fromJson(response);
latestVersion.value = resp.systemversion!;
updatepackageaddress = resp.updatepackageaddress!;
// // 处理API响应
// if (response['info'] == null) {
// throw const FormatException('API 响应格式错误');
// }
// 版本检查
isUpdateAvailable.value = _isNewVersionAvailable(resp.systemversion!);
} catch (e) {
// 统一错误处理
errorMessage.value = e.toString();
Get.snackbar('错误', e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white);
// 重要:重新抛出异常以便上层处理(可选)
} finally {
isFetchingDeviceInfo.value = false;
}
// final resp = OtaConfigResp.fromJson(response);
// latestVersion.value = resp.systemversion!;
// updatepackageaddress = resp.updatepackageaddress!;
// // 版本检查
// isUpdateAvailable.value = _isNewVersionAvailable(resp.systemversion!);
// } catch (e) {
// // 统一错误处理
// errorMessage.value = e.toString();
// Get.snackbar('错误', e.toString(),
// snackPosition: SnackPosition.BOTTOM,
// backgroundColor: Colors.red,
// colorText: Colors.white);
// // 重要:重新抛出异常以便上层处理(可选)
// } finally {
// isFetchingDeviceInfo.value = false;
// }
}
// 版本比较方法优化
@ -288,6 +295,7 @@ class OtaUpgradeController extends GetxController {
// 开始升级
void _installApp(String path) async {
// JlOtaPlugin()
// final File file = File(path);
// if (await file.exists()) {
// // OpenResult result = await OpenFile.open(path);

3
lib/modules/translation/controllers/translation_controller.dart

@ -59,6 +59,9 @@ class TranslationController extends GetxController {
return 'audioVideoTranslation';
case 'call':
return 'callTranslation';
case 'faceToFace':
return 'faceToFaceTranslation';
default:
return 'simultaneousTranslation';
}

6
lib/modules/translation/views/translation_view.dart

@ -57,6 +57,7 @@ class TranslationView extends GetView<TranslationController> {
color: isDarkMode ? AppColors.cardBackground : Colors.white,
itemBuilder: (BuildContext context) => [
_buildPopupMenuItem('simultaneous', 'simultaneousTranslation'.tr),
_buildPopupMenuItem('faceToFace', 'faceToFaceTranslation'.tr),
_buildPopupMenuItem('audioVideo', 'audioVideoTranslation'.tr),
_buildPopupMenuItem('call', 'callTranslation'.tr),
],
@ -86,12 +87,11 @@ class TranslationView extends GetView<TranslationController> {
// TTS toggle button
Obx(() => IconButton(
icon: Icon(
controller.isTtsEnabled.value
? Icons.volume_up
: Icons.volume_off,
controller.isTtsEnabled.value ? Icons.mic : Icons.mic_off,
color: isDarkMode ? Colors.white : Colors.black,
size: 24.sp,
),
// onPressed: controller.toggleTts,默认播放
onPressed: controller.toggleTts,
tooltip: '自动播放翻译结果',
)),

1
local_plugins/jieli/android/build.gradle.kts

@ -54,5 +54,4 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
implementation(project(":azure_speech"))
implementation(project(":jl_opus"))
implementation(project(":jl_opus"))
}

33
local_plugins/jl_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/

33
local_plugins/jl_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'

3
local_plugins/jl_ota/CHANGELOG.md

@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.

1
local_plugins/jl_ota/LICENSE

@ -0,0 +1 @@
TODO: Add your license here.

15
local_plugins/jl_ota/README.md

@ -0,0 +1,15 @@
# jl_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.

4
local_plugins/jl_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

9
local_plugins/jl_ota/android/.gitignore

@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx

71
local_plugins/jl_ota/android/build.gradle

@ -0,0 +1,71 @@
group = "com.yunqiinnovation.jl_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()
flatDir {
dirs 'libs'
}
}
}
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
android {
namespace = "com.yunqiinnovation.jl_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(name: 'jl_bt_ota_V1.9.0-release', ext: 'aar')
implementation(project(":ble_service"))
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.mockito:mockito-core:5.0.0")
}
testOptions {
unitTests.all {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}

BIN
local_plugins/jl_ota/android/libs/jl_bt_ota_V1.9.0-release.aar

Binary file not shown.

BIN
local_plugins/jl_ota/android/libs/jl_bt_ota_V1.9.2-release.aar

Binary file not shown.

1
local_plugins/jl_ota/android/settings.gradle

@ -0,0 +1 @@
rootProject.name = 'jl_ota'

3
local_plugins/jl_ota/android/src/main/AndroidManifest.xml

@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yunqiinnovation.jl_ota">
</manifest>

279
local_plugins/jl_ota/android/src/main/kotlin/com/yunqiinnovation/jl_ota/JlOtaPlugin.kt

@ -0,0 +1,279 @@
package com.yunqiinnovation.jl_ota
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel
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.BluetoothGatt;
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.annotation.NonNull
import com.jieli.jl_bt_ota.constant.ErrorCode;
import com.jieli.jl_bt_ota.constant.StateCode;
import com.jieli.jl_bt_ota.impl.BluetoothOTAManager;
import com.jieli.jl_bt_ota.interfaces.BtEventCallback;
import com.jieli.jl_bt_ota.interfaces.IActionCallback;
import com.jieli.jl_bt_ota.interfaces.IUpgradeCallback;
import com.jieli.jl_bt_ota.model.BluetoothOTAConfigure;
import com.jieli.jl_bt_ota.model.base.BaseError;
import com.jieli.jl_bt_ota.model.response.TargetInfoResponse;
import com.yunqiinnovation.ble_service.BleService
/** JlOtaPlugin */
class JlOtaPlugin(): 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 eventChannel: EventChannel
private var streamSink: EventChannel.EventSink? = null
/// BLE服务实例
private var otaManager: OTAManager? = null
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 onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "jl_ota")
channel.setMethodCallHandler(this)
eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, EVENT_CHANNEL_NAME)
eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
streamSink = events
}
override fun onCancel(arguments: Any?) {
streamSink = null
}
})
otaManager = OTAManager(context)
// otaManager.getBluetoothOption().setFirmwareFilePath(filePath);
// otaManager.startOTA(new IUpgradeCallback() {
// }
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
val bluetoothOption = BluetoothOTAConfigure()
//选择通讯方式
bluetoothOption.priority = BluetoothOTAConfigure.PREFER_BLE
//是否需要自定义回连方式(默认不需要,如需要自定义回连方式,需要客户自行实现)
bluetoothOption.isUseReconnect = true
//是否启用设备认证流程(与固件工程师确认)
bluetoothOption.isUseAuthDevice = true
//设置BLE的MTU
bluetoothOption.mtu = 500
//是否需要改变BLE的MTU
bluetoothOption.isNeedChangeMtu = false
//是否启用杰理服务器(暂时不支持)
bluetoothOption.isUseJLServer = false
Log.d(TAG, "bluetoothOTAManager初始化成功")
//配置OTA参数
otaManager?.configure(bluetoothOption)
var filePath= "/storage/emulated/0/Android/data/com.yunqiinnovation.deepsound/files/downloads/ota_upgrades/1.ufw"
otaManager?.bluetoothOption?.firmwareFilePath = filePath
Log.d(TAG, "OpusManager路径成功${filePath}")
// Add ?. after bluetoothOption ^
otaManager?.startOTA(
CustomUpdateCallback(
context, null, this
)
)
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
}
class OTAManager(context: Context) : BluetoothOTAManager(context) {
override fun getConnectedDevice(): BluetoothDevice? {
// 这里可以添加空实现的注释说明
return null
}
override fun getConnectedBluetoothGatt(): BluetoothGatt? {
// 这里可以添加空实现的注释说明
return null
}
override fun connectBluetoothDevice(bluetoothDevice: BluetoothDevice?) {
// 这里可以添加空实现的注释说明
}
override fun disconnectBluetoothDevice
(bluetoothDevice: BluetoothDevice?) {
// 这里可以添加空实现的注释说明
}
/** 数据发送方法(协议无关) */
override fun sendDataToDevice(
bluetoothDevice: BluetoothDevice?,
bytes: ByteArray?
): Boolean {return true}
}
private class CustomUpdateCallback(
val context: Context,
val device: BluetoothDevice?,
val viewModel: JlOtaPlugin
) : 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需要重新链接")
// viewModel.otaStateMLD.value = OTAReconnect(device, addr, isNewReconnectWay)
// if (viewModel.isUseReconnectWay()) {
// viewModel.reconnectDev(addr, isNewReconnectWay)
// }
}
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停止升级")
// viewModel.otaStateMLD.value =
// OTAEnd(device, ErrorCode.ERR_NONE, context.getString(R.string.ota_complete))
// val handler = Handler(Looper.getMainLooper())
// handler.postDelayed({
// // Log.d("ZHM", "onStopOTA: disconnectDevice connected : "+viewModel.bluetoothHelper.isConnected()+ " getConnectedDevice: "+viewModel.bluetoothHelper.getConnectedDevice())
// //变地址导致无法判断device是否一致
// if (viewModel.bluetoothHelper.isConnected()/* && BluetoothUtil.deviceEquals(
// device,
// viewModel.bluetoothHelper.getConnectedDevice()
// )*/
// ) {
// Log.d("ZHM", "onStopOTA: disconnectDevice")
// viewModel.bluetoothHelper.disconnectDevice(viewModel.otaManager.connectedDevice)
// }
// }, 500)
}
override fun onCancelOTA() {
Log.d(TAG, "onCancelOTA取消升级")
// viewModel.otaStateMLD.value =
// OTAEnd(
// device,
// ErrorCode.ERR_UNKNOWN,
// context.getString(R.string.ota_upgrade_cancel)
// )
}
override fun onError(error: BaseError?) {
Log.d(TAG, "onError升级错误")
// error?.let {
// viewModel.otaStateMLD.value = OTAEnd(device, it.subCode, it.message)
// }
// viewModel.bluetoothHelper.disconnectDevice(viewModel.otaManager.connectedDevice)//升级失败,断开设备,方便自动化继续升级
}
}
// class OtaDemo {
// private val otaManager = OTAManager(MainApplication.getInstance())
// fun initOTA(context: Context, firmwarePath: String) {
// val otaManager = JlOtaPlugin()
// val bluetoothOption = BluetoothOTAConfigure.createDefault().apply {
// priority = BluetoothOTAConfigure.PREFER_BLE
// useAuthDevice = true
// bleIntervalMs = 500
// timeoutMs = 3000
// mtu = 500
// needChangeMtu = false
// useReconnect = false
// setFirmwareFilePath(firmwarePath)
// }
// otaManager.configure(bluetoothOption)
// }
// fun otaFirmware(filePath: String) { // 方法名改为小写开头
// val otaManager = JlOtaPlugin()
// otaManager.registerBluetoothCallback(object : BtEventCallback {
// override fun onConnection(device: BluetoothDevice, status: Int) {
// if (status == StateCode.CONNECTION_OK) {
// if (otaManager.isOTA) return
// otaManager.queryMandatoryUpdate(object : IActionCallback<TargetInfoResponse> {
// override fun onSuccess(deviceInfo: TargetInfoResponse) {
// // 处理设备信息
// deviceInfo.versionCode
// deviceInfo.versionName
// deviceInfo.projectCode
// deviceInfo.uid
// deviceInfo.pid
// }
// override fun onError(baseError: BaseError) {
// if (baseError.code == ErrorCode.ERR_NONE &&
// baseError.subCode == ErrorCode.ERR_NONE) {
// val deviceInfo = otaManager.deviceInfo
// deviceInfo?.let {
// it.versionCode
// it.versionName
// it.projectCode
// it.uid
// it.pid
// }
// }
// }
// })
// }
// }
// })
// otaManager.bluetoothOption?.setFirmwareFilePath(filePath)
// otaManager.startOTA(object : IUpgradeCallback {
// override fun onStartOTA() = Unit
// override fun onNeedReconnect(addr: String, isNewReconnectWay: Boolean) {
// if (otaManager.bluetoothOption?.useReconnect == true) {
// // 处理自定义回连
// }
// }
// override fun onProgress(type: Int, progress: Float) = Unit
// override fun onStopOTA() = Unit
// override fun onCancelOTA() = Unit
// override fun onError(error: BaseError) = Unit
// })
// otaManager.release()
// }
//}

38
local_plugins/jl_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

0
local_plugins/jl_ota/ios/Assets/.gitkeep

19
local_plugins/jl_ota/ios/Classes/JlOtaPlugin.swift

@ -0,0 +1,19 @@
import Flutter
import UIKit
public class JlOtaPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "jl_ota", binaryMessenger: registrar.messenger())
let instance = JlOtaPlugin()
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)
}
}
}

14
local_plugins/jl_ota/ios/Resources/PrivacyInfo.xcprivacy

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

29
local_plugins/jl_ota/ios/jl_ota.podspec

@ -0,0 +1,29 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint jl_ota.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'jl_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 = {'jl_ota_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
end

8
local_plugins/jl_ota/lib/jl_ota.dart

@ -0,0 +1,8 @@
import 'jl_ota_platform_interface.dart';
class JlOta {
Future<String?> getPlatformVersion() {
return JlOtaPlatform.instance.getPlatformVersion();
}
}

17
local_plugins/jl_ota/lib/jl_ota_method_channel.dart

@ -0,0 +1,17 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'jl_ota_platform_interface.dart';
/// An implementation of [JlOtaPlatform] that uses method channels.
class MethodChannelJlOta extends JlOtaPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('jl_ota');
@override
Future<String?> getPlatformVersion() async {
final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
return version;
}
}

29
local_plugins/jl_ota/lib/jl_ota_platform_interface.dart

@ -0,0 +1,29 @@
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'jl_ota_method_channel.dart';
abstract class JlOtaPlatform extends PlatformInterface {
/// Constructs a JlOtaPlatform.
JlOtaPlatform() : super(token: _token);
static final Object _token = Object();
static JlOtaPlatform _instance = MethodChannelJlOta();
/// The default instance of [JlOtaPlatform] to use.
///
/// Defaults to [MethodChannelJlOta].
static JlOtaPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [JlOtaPlatform] when
/// they register themselves.
static set instance(JlOtaPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<String?> getPlatformVersion() {
throw UnimplementedError('platformVersion() has not been implemented.');
}
}

72
local_plugins/jl_ota/pubspec.yaml

@ -0,0 +1,72 @@
name: jl_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.yunqiinnovation.jl_ota
pluginClass: JlOtaPlugin
ios:
pluginClass: JlOtaPlugin
# 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

2
pubspec.yaml

@ -79,6 +79,8 @@ dependencies:
path: amap_flutter
jl_opus:
path: local_plugins/jl_opus
jl_ota:
path: local_plugins/jl_ota
ble_service:
path: local_plugins/ble_service
deepvoice_utils:

Loading…
Cancel
Save