10 changed files with 578 additions and 424 deletions
@ -1,116 +0,0 @@ |
|||||
package com.yunqiinnovation.ble_service |
|
||||
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.BluetoothDevice |
|
||||
import android.bluetooth.BluetoothGatt |
|
||||
import android.bluetooth.BluetoothProfile |
|
||||
import android.content.Context |
|
||||
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 android.util.Log |
|
||||
import java.util.* |
|
||||
class CustomUpdateCallback( |
|
||||
val context: Context, |
|
||||
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"}") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class OTAManager(context: Context) : BluetoothOTAManager(context) { |
|
||||
|
|
||||
|
|
||||
// 定义回调接口 |
|
||||
interface DataCallback { |
|
||||
fun onDataReceived(device: BluetoothDevice?, data: ByteArray?) |
|
||||
} |
|
||||
// 保存回调的实例 |
|
||||
private var dataCallback: DataCallback? = null |
|
||||
|
|
||||
// 设置回调的方法 |
|
||||
fun setDataCallback(callback: DataCallback) { |
|
||||
this.dataCallback = callback |
|
||||
} |
|
||||
override fun getConnectedDevice(): BluetoothDevice? { |
|
||||
// 这里可以添加空实现的注释说明 |
|
||||
Log.i(TAG, "ota数据发送getConnectedDevice") |
|
||||
return null |
|
||||
} |
|
||||
|
|
||||
override fun getConnectedBluetoothGatt(): BluetoothGatt? { |
|
||||
// 这里可以添加空实现的注释说明 |
|
||||
Log.i(TAG, "ota数据发送getConnectedBluetoothGatt") |
|
||||
return null |
|
||||
} |
|
||||
|
|
||||
override fun connectBluetoothDevice(bluetoothDevice: BluetoothDevice?) { |
|
||||
// 这里可以添加空实现的注释说明 |
|
||||
Log.i(TAG, "ota数据发送connectBluetoothDevice") |
|
||||
} |
|
||||
|
|
||||
override fun disconnectBluetoothDevice(bluetoothDevice: BluetoothDevice?) { |
|
||||
// 这里可以添加空实现的注释说明 |
|
||||
Log.i(TAG, "ota数据发送disconnectBluetoothDevice") |
|
||||
} |
|
||||
|
|
||||
/** 数据发送方法(协议无关) */ |
|
||||
override fun sendDataToDevice( |
|
||||
bluetoothDevice: BluetoothDevice?, |
|
||||
bytes: ByteArray? |
|
||||
): Boolean { |
|
||||
Log.i(TAG, "ota数据发送${bluetoothDevice},${bytes?.size}") |
|
||||
// 触发回调,将数据回传给调用者 |
|
||||
dataCallback?.onDataReceived(bluetoothDevice, bytes) |
|
||||
// context.onReceiveDeviceData(device, data); |
|
||||
return true |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,19 +1,148 @@ |
|||||
import 'ota_platform_interface.dart'; |
import 'ota_platform_interface.dart'; |
||||
|
import 'dart:async'; |
||||
|
import 'dart:typed_data'; |
||||
|
import 'package:flutter/services.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
class OtaEvent { |
||||
|
static final int NOT_STARTED = -1; // 未开始 |
||||
|
static final int VALIDATION_FILE = 0; // 验证文件 |
||||
|
static final int ONUPGRADE = 1; // 升级中 |
||||
|
static final int START_UPGRADING = 2; // 开始升级 |
||||
|
static final int UPGRADE_SUCCESS = 3; // 升级成功 |
||||
|
static final int UPGRADE_FAILED = 4; // 升级失败 |
||||
|
static final int CONNECTION_DISCONNECTION = 5; // 连接断开 |
||||
|
static final int CONNECTION_SUCCESS = 6; // 连接成功 |
||||
|
|
||||
|
/// 事件类型 |
||||
|
final String event; |
||||
|
|
||||
|
/// 输出升级状态 |
||||
|
final int? type; |
||||
|
|
||||
|
/// 输出升级进度 |
||||
|
final double? progress; |
||||
|
|
||||
|
/// 错误码 (仅在发生错误时有效) |
||||
|
final int? code; |
||||
|
|
||||
|
/// 错误信息 (仅在发生错误时有效) |
||||
|
final String? message; |
||||
|
|
||||
|
/// 构造函数 |
||||
|
OtaEvent({ |
||||
|
required this.event, |
||||
|
this.type, |
||||
|
this.progress, |
||||
|
this.code, |
||||
|
this.message, |
||||
|
}); |
||||
|
|
||||
|
/// 从Map构造对象 |
||||
|
factory OtaEvent.fromMap(Map<dynamic, dynamic> map) { |
||||
|
return OtaEvent( |
||||
|
event: map['event'], |
||||
|
type: map['type'], |
||||
|
progress: map['progress'], |
||||
|
code: map['code'], |
||||
|
message: map['message'], |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
class Ota { |
class Ota { |
||||
Future<String?> getPlatformVersion() { |
// 单例实例 |
||||
return OtaPlatform.instance.getPlatformVersion(); |
static final Ota _instance = Ota._internal(); |
||||
|
|
||||
|
// 私有构造函数 |
||||
|
Ota._internal() { |
||||
|
// 初始化时设置事件监听 |
||||
|
_setupEventListener(); |
||||
|
} |
||||
|
|
||||
|
// 公共访问点 |
||||
|
static Ota get instance => _instance; |
||||
|
|
||||
|
static const EventChannel _eventChannel = EventChannel( |
||||
|
'com.example.ota/events', |
||||
|
); |
||||
|
final RxDouble progress = 0.0.obs; |
||||
|
final RxInt type = OtaEvent.NOT_STARTED.obs; |
||||
|
final RxBool isUpgrade = false.obs; |
||||
|
|
||||
|
/// 事件流 |
||||
|
Stream<OtaEvent>? _eventStream; |
||||
|
bool _isEventListenerSet = false; // 防止重复监听 |
||||
|
|
||||
|
/// 获取事件流 |
||||
|
Stream<OtaEvent> get eventStream { |
||||
|
_eventStream ??= _eventChannel.receiveBroadcastStream().map((event) { |
||||
|
if (event is Map) { |
||||
|
return OtaEvent.fromMap(event); |
||||
|
} |
||||
|
throw PlatformException(code: 'INVALID_EVENT', message: '无效的事件数据'); |
||||
|
}); |
||||
|
return _eventStream!; |
||||
|
} |
||||
|
|
||||
|
/// 释放资源 |
||||
|
void onClose() { |
||||
|
onOtaClose(); |
||||
|
// 停止事件监听 |
||||
|
_eventStream = null; |
||||
|
_isEventListenerSet = false; |
||||
|
|
||||
|
// 清理 Rx 对象 |
||||
|
progress.close(); |
||||
|
type.close(); |
||||
|
isUpgrade.value = false; |
||||
|
print("Ota 对象资源已释放"); |
||||
|
} |
||||
|
|
||||
|
/// 内部设置事件监听(只执行一次) |
||||
|
void _setupEventListener() { |
||||
|
if (_isEventListenerSet) return; |
||||
|
|
||||
|
eventStream.listen((event) { |
||||
|
if (event.event == 'onProgress' && |
||||
|
event.type != null && |
||||
|
event.progress != null) { |
||||
|
print("flutter 收到数据${event.progress}type=${type.value}"); |
||||
|
progress.value = event.progress!; |
||||
|
type.value = event.type!; |
||||
|
} |
||||
|
if (event.event == 'onStartOTA') { |
||||
|
type.value = OtaEvent.START_UPGRADING; |
||||
|
isUpgrade.value = true; // 开始升级 |
||||
|
} |
||||
|
if (event.event == 'onStopOTA') { |
||||
|
type.value = OtaEvent.UPGRADE_SUCCESS; |
||||
|
isUpgrade.value = false; |
||||
|
} |
||||
|
if (event.event == 'onError' && |
||||
|
event.code != null && |
||||
|
event.message != null) { |
||||
|
print("flutter onError${event.code}type=${event.message}"); |
||||
|
type.value = OtaEvent.UPGRADE_FAILED; |
||||
|
isUpgrade.value = false; |
||||
|
} |
||||
|
if (event.event == 'NOCONNECTION') { |
||||
|
type.value = OtaEvent.CONNECTION_DISCONNECTION; |
||||
|
isUpgrade.value = false; |
||||
|
} |
||||
|
if (event.event == 'CONNECTION_SUCCESS') { |
||||
|
type.value = OtaEvent.CONNECTION_SUCCESS; |
||||
} |
} |
||||
|
}); |
||||
|
|
||||
Future<String?> searchDevices() { |
_isEventListenerSet = true; |
||||
return OtaPlatform.instance.searchDevices(); |
|
||||
} |
} |
||||
|
|
||||
Future<String?> connectDevice() { |
Future<String?> searchDevices(String? filePath) { |
||||
return OtaPlatform.instance.connectDevice(); |
return OtaPlatform.instance.searchDevices(filePath); |
||||
} |
} |
||||
|
|
||||
Future<String?> startUpgrade() { |
Future<String?> onOtaClose() { |
||||
return OtaPlatform.instance.startUpgrade(); |
return OtaPlatform.instance.onOtaClose(); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue