fix:完善对讲流程、增加监控功能
This commit is contained in:
parent
7943aef0c2
commit
323c99b27e
@ -1,5 +1,6 @@
|
||||
// 网关配网
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
|
||||
@ -49,12 +50,19 @@ class GatewayConfiguringWifiCommand extends SenderProtocol {
|
||||
|
||||
//gatewayConfigurationStr
|
||||
final int clientIdLength = utf8.encode(gatewayConfigurationStr!).length;
|
||||
final double clientIdLengthDouble = clientIdLength / 256;
|
||||
final int clientIdLengthDoubleType1 = clientIdLengthDouble.toInt();
|
||||
final int clientIdLengthDoubleType2 = clientIdLength % 256;
|
||||
// AppLog.log('gatewayConfigurationStr!:$gatewayConfigurationStr! clientIdLength:$clientIdLength clientIdLengthDouble:$clientIdLengthDouble clientIdLengthDoubleType1:$clientIdLengthDoubleType1 clientIdLengthDoubleType2:$clientIdLengthDoubleType2');
|
||||
data.add(clientIdLengthDoubleType1);
|
||||
data.add(clientIdLengthDoubleType2);
|
||||
Uint8List lengthBytes = Uint8List(2);
|
||||
ByteData byteData = ByteData.view(lengthBytes.buffer);
|
||||
byteData.setUint16(0, clientIdLength, Endian.little); // 使用大端序(big-endian)
|
||||
|
||||
// 将两个字节添加到 subData
|
||||
subData.addAll(lengthBytes);
|
||||
// subData.add(clientIdLength);
|
||||
// final double clientIdLengthDouble = clientIdLength / 256;
|
||||
// final int clientIdLengthDoubleType1 = clientIdLengthDouble.toInt();
|
||||
// final int clientIdLengthDoubleType2 = clientIdLength % 256;
|
||||
// // AppLog.log('gatewayConfigurationStr!:$gatewayConfigurationStr! clientIdLength:$clientIdLength clientIdLengthDouble:$clientIdLengthDouble clientIdLengthDoubleType1:$clientIdLengthDoubleType1 clientIdLengthDoubleType2:$clientIdLengthDoubleType2');
|
||||
// data.add(clientIdLengthDoubleType1);
|
||||
// data.add(clientIdLengthDoubleType2);
|
||||
subData.addAll(utf8.encode(gatewayConfigurationStr!));
|
||||
// subData = getFixedLengthList(subData, 20 - clientIdLength);
|
||||
|
||||
|
||||
64
lib/main/lockDetail/lockDetail/device_network_info.dart
Normal file
64
lib/main/lockDetail/lockDetail/device_network_info.dart
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
class DeviceNetwork {
|
||||
DeviceNetwork({
|
||||
this.description,
|
||||
this.errorCode,
|
||||
this.data,
|
||||
this.errorMsg,});
|
||||
|
||||
DeviceNetwork.fromJson(dynamic json) {
|
||||
description = json['description'];
|
||||
errorCode = json['errorCode'];
|
||||
data = json['data'] != null ? DeviceNetworkInfo.fromJson(json['data']) : null;
|
||||
errorMsg = json['errorMsg'];
|
||||
}
|
||||
String? description;
|
||||
int? errorCode;
|
||||
DeviceNetworkInfo? data;
|
||||
String? errorMsg;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['description'] = description;
|
||||
map['errorCode'] = errorCode;
|
||||
if (data != null) {
|
||||
map['data'] = data!.toJson();
|
||||
}
|
||||
map['errorMsg'] = errorMsg;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DeviceNetworkInfo {
|
||||
DeviceNetworkInfo({
|
||||
this.wifiName,
|
||||
this.networkMac,
|
||||
this.secretKey,
|
||||
this.peerId,
|
||||
});
|
||||
|
||||
DeviceNetworkInfo.fromJson(dynamic json) {
|
||||
wifiName = json['wifiName'];
|
||||
networkMac = json['networkMac'];
|
||||
secretKey = json['secretKey'];
|
||||
peerId = json['peerId'];
|
||||
}
|
||||
|
||||
String? wifiName;
|
||||
String? networkMac;
|
||||
String? secretKey;
|
||||
String? peerId;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['wifiName'] = wifiName;
|
||||
map['networkMac'] = networkMac;
|
||||
map['secretKey'] = secretKey;
|
||||
map['peerId'] = peerId;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -7,12 +7,19 @@ import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'package:star_lock/app_settings/app_colors.dart';
|
||||
import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_state.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
||||
import 'package:star_lock/main/lockMian/lockMain/lockMain_logic.dart';
|
||||
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/getGatewayConfiguration_entity.dart';
|
||||
import 'package:star_lock/network/api_repository.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
||||
import 'package:star_lock/tools/aliyunRealNameAuth/aliyunRealNameAuthHandle.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import 'package:star_lock/tools/bugly/bugly_tool.dart';
|
||||
import 'package:star_lock/tools/showCupertinoAlertView.dart';
|
||||
import 'package:star_lock/tools/showTipView.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
import 'package:star_lock/widget/flavors_img.dart';
|
||||
|
||||
import '../../../appRouters.dart';
|
||||
@ -1154,11 +1161,26 @@ class _LockDetailPageState extends State<LockDetailPage>
|
||||
if (state.keyInfos.value.lockFeature!.videoIntercom == 1) {
|
||||
showWidgetArr.add(
|
||||
bottomItem('images/main/icon_catEyes.png', '监控'.tr,
|
||||
state.bottomBtnisEable.value, () {
|
||||
Get.toNamed(Routers.realTimePicturePage, arguments: <String, Object?>{
|
||||
'lockName': state.keyInfos.value.lockName,
|
||||
'isMonitoring': true
|
||||
});
|
||||
state.bottomBtnisEable.value, () async {
|
||||
final lockId = state.keyInfos.value.lockId;
|
||||
final LockSetInfoEntity entity =
|
||||
await ApiRepository.to.getLockSettingInfoData(
|
||||
lockId: lockId.toString(),
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
final LockSetInfoData data = entity.data!;
|
||||
final mac = data.lockBasicInfo?.mac;
|
||||
if (mac != null && mac.isNotEmpty) {
|
||||
final DeviceNetwork deviceNetworkInfo = await ApiRepository.to
|
||||
.getDeviceNetwork(deviceType: 2, deviceMac: mac);
|
||||
final peerId = deviceNetworkInfo?.data?.peerId;
|
||||
if (peerId == null || peerId.isEmpty) {
|
||||
throw Exception('设备peerId为空');
|
||||
}
|
||||
StartChartManage()
|
||||
.startCallRequestMessageTimer(ToPeerId: peerId ?? '');
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,13 +1,19 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:network_info_plus/network_info_plus.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart';
|
||||
import 'package:star_lock/login/login/entity/LoginEntity.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifiEntity.dart';
|
||||
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/getGatewayConfiguration_entity.dart';
|
||||
import 'package:star_lock/talk/startChart/entity/star_chart_register_node_entity.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
|
||||
import '../../../../../blue/blue_manage.dart';
|
||||
@ -32,10 +38,20 @@ class ConfiguringWifiLogic extends BaseGetXController {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateNetworkInfo() async {
|
||||
final LoginEntity entity = await ApiRepository.to.updateNetworkInfo(
|
||||
lockId: state.lockSetInfoData.value.lockId!,
|
||||
network: state.wifiNameController.text,
|
||||
Future<void> updateNetworkInfo({
|
||||
required String peerId,
|
||||
required String wifiName,
|
||||
required String secretKey,
|
||||
required String deviceMac,
|
||||
required String networkMac,
|
||||
}) async {
|
||||
final LoginEntity entity = await ApiRepository.to.settingDeviceNetwork(
|
||||
deviceType: 2,
|
||||
deviceMac: deviceMac,
|
||||
wifiName: wifiName,
|
||||
networkMac: networkMac,
|
||||
secretKey: secretKey,
|
||||
peerId: peerId,
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
showToast('配网成功'.tr, something: () {
|
||||
@ -53,92 +69,64 @@ class ConfiguringWifiLogic extends BaseGetXController {
|
||||
_replySubscription =
|
||||
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||
// WIFI配网结果
|
||||
if (reply is SenderConfiguringWifiReply) {
|
||||
_replySenderConfiguringWifi(reply);
|
||||
if (reply is GatewayConfiguringWifiResultReply) {
|
||||
_replySenderConfiguringWifiResult(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// WIFI配网结果
|
||||
Future<void> _replySenderConfiguringWifi(Reply reply) async {
|
||||
final int status = reply.data[5];
|
||||
|
||||
Future<void> _replySenderConfiguringWifiResult(Reply reply) async {
|
||||
final int status = reply.data[2];
|
||||
state.sureBtnState.value = 0;
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
state.sureBtnState.value = 0;
|
||||
cancelBlueConnetctToastTimer();
|
||||
dismissEasyLoading();
|
||||
updateNetworkInfo();
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
final List<String>? privateKey =
|
||||
await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList =
|
||||
changeStringListToIntList(privateKey!);
|
||||
final int secretKeyJsonLength = (reply.data[4] << 8) + reply.data[3];
|
||||
|
||||
final List<String>? publicKey =
|
||||
await Storage.getStringList(saveBluePublicKey);
|
||||
final List<int> publicKeyDataList =
|
||||
changeStringListToIntList(publicKey!);
|
||||
final List<int> secretKeyList =
|
||||
reply.data.sublist(5, 5 + secretKeyJsonLength);
|
||||
String result = utf8String(secretKeyList);
|
||||
// 解析 JSON 字符串为 Map
|
||||
Map<String, dynamic> jsonMap = json.decode(result);
|
||||
|
||||
final List<int> tokenData = reply.data.sublist(7, 10);
|
||||
final List<String> saveStrList = changeIntListToStringList(tokenData);
|
||||
Storage.setStringList(saveBlueToken, saveStrList);
|
||||
// 提取 peerId
|
||||
String? peerId = jsonMap['peerId'];
|
||||
String? wifiName = jsonMap['wifiName'];
|
||||
String? secretKey = jsonMap['secretKey'];
|
||||
String? deviceMac = jsonMap['deviceMac'];
|
||||
String? networkMac = jsonMap['networkMac'];
|
||||
|
||||
final List<int> serversList = <int>[];
|
||||
for (int i = 0;
|
||||
i < state.configuringWifiEntity.value.data!.serviceList!.length;
|
||||
i++) {
|
||||
final ServiceList item =
|
||||
state.configuringWifiEntity.value.data!.serviceList![i];
|
||||
final List<String> itemList = item.serviceIp!.split('.');
|
||||
for (String element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
/// 配网成功后,赋值锁的peerId
|
||||
StartChartManage().lockPeerId = peerId ?? '';
|
||||
|
||||
final double typeDouble = int.parse(item.port!) / 256;
|
||||
final int type1 = typeDouble.toInt();
|
||||
final int type2 = int.parse(item.port!) % 256;
|
||||
serversList.add(type1);
|
||||
serversList.add(type2);
|
||||
}
|
||||
|
||||
// 判断是否登录账户
|
||||
final loginData = await Storage.getLoginData();
|
||||
|
||||
// 获取app用户的peerId
|
||||
String appPeerId = loginData?.starchart?.starchartId ?? '';
|
||||
|
||||
final List<String> uidList = <String>[Storage.getUid().toString()];
|
||||
IoSenderManage.senderConfiguringWifiCommand(
|
||||
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
ssid: state.wifiNameController.text,
|
||||
password: state.wifiPWDController.text,
|
||||
numberOfServers: state.configuringWifiEntity.value.data!.serviceNum,
|
||||
listOfServers: serversList,
|
||||
numberOfPhone: uidList.length,
|
||||
listOfPhone: uidList,
|
||||
token: tokenData,
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
peerId: appPeerId,
|
||||
);
|
||||
|
||||
break;
|
||||
case 0xff:
|
||||
//成功
|
||||
showToast('配网失败'.tr);
|
||||
// 保存到缓存
|
||||
await Storage.saveLockNetWorkInfo(jsonMap);
|
||||
// 上报服务器
|
||||
updateNetworkInfo(
|
||||
peerId: peerId ?? '',
|
||||
wifiName: wifiName ?? '',
|
||||
secretKey: secretKey ?? '',
|
||||
deviceMac: deviceMac ?? '',
|
||||
networkMac: networkMac ?? '');
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
dismissEasyLoading();
|
||||
cancelBlueConnetctToastTimer();
|
||||
showToast('配网失败'.tr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助函数:美化 JSON 输出
|
||||
String prettyPrintJson(String jsonString) {
|
||||
var jsonObject = json.decode(jsonString);
|
||||
return JsonEncoder.withIndent(' ').convert(jsonObject);
|
||||
}
|
||||
|
||||
// 点击配置wifi
|
||||
Future<void> senderConfiguringWifiAction() async {
|
||||
if (state.wifiNameController.text.isEmpty) {
|
||||
@ -146,6 +134,10 @@ class ConfiguringWifiLogic extends BaseGetXController {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.wifiPWDController.text.isEmpty) {
|
||||
showToast('请输入WiFi密码'.tr);
|
||||
return;
|
||||
}
|
||||
if (state.sureBtnState.value == 1) {
|
||||
return;
|
||||
}
|
||||
@ -156,71 +148,61 @@ class ConfiguringWifiLogic extends BaseGetXController {
|
||||
dismissEasyLoading();
|
||||
state.sureBtnState.value = 0;
|
||||
});
|
||||
|
||||
final GetGatewayConfigurationEntity entity =
|
||||
await ApiRepository.to.getGatewayConfiguration(timeout: 60);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
state.getGatewayConfigurationStr = entity.data ?? '';
|
||||
}
|
||||
|
||||
// 判断是否登录账户
|
||||
final loginData = await Storage.getLoginData();
|
||||
|
||||
// 获取app用户的peerId
|
||||
String appPeerId = loginData?.starchart?.starchartId ?? '';
|
||||
// 如果已有值,则追加
|
||||
if (state.getGatewayConfigurationStr.isNotEmpty) {
|
||||
// 解析 JSON 字符串为 Map
|
||||
Map<String, dynamic> jsonMap =
|
||||
json.decode(state.getGatewayConfigurationStr);
|
||||
|
||||
// 移除指定的键
|
||||
jsonMap.remove("starCloudUrl");
|
||||
jsonMap.remove("starLockPeerId");
|
||||
|
||||
// 追加新的键值对
|
||||
jsonMap['userPeerld'] = appPeerId;
|
||||
|
||||
// 将 Map 转换回 JSON 字符串
|
||||
state.getGatewayConfigurationStr =
|
||||
json.encode(jsonMap).replaceAll(',', ',\n');
|
||||
|
||||
// 确保格式化输出
|
||||
state.getGatewayConfigurationStr =
|
||||
prettyPrintJson(state.getGatewayConfigurationStr);
|
||||
} else {
|
||||
// 如果为空,则直接赋值
|
||||
state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
|
||||
}
|
||||
// 追加新的 JSON 字符串
|
||||
// if (state.getGatewayConfigurationStr.isNotEmpty) {
|
||||
// // 如果已有值,则追加
|
||||
// state.getGatewayConfigurationStr =
|
||||
// state.getGatewayConfigurationStr.replaceAll(
|
||||
// RegExp(r'}\s*$'),
|
||||
// ',\n{\"userPeerld\": \"$appPeerId\"}',
|
||||
// );
|
||||
// } else {
|
||||
// // 如果为空,则直接赋值
|
||||
// state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
|
||||
// }
|
||||
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected) {
|
||||
final List<String>? privateKey =
|
||||
await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList =
|
||||
changeStringListToIntList(privateKey!);
|
||||
|
||||
final List<String>? publicKey =
|
||||
await Storage.getStringList(saveBluePublicKey);
|
||||
final List<int> publicKeyDataList =
|
||||
changeStringListToIntList(publicKey!);
|
||||
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
final List<int> serversList = <int>[];
|
||||
for (int i = 0;
|
||||
i < state.configuringWifiEntity.value.data!.serviceList!.length;
|
||||
i++) {
|
||||
final ServiceList item =
|
||||
state.configuringWifiEntity.value.data!.serviceList![i];
|
||||
if (item.serviceIp!.contains('192')) {
|
||||
final List<String> itemList = item.serviceIp!.split('.');
|
||||
for (String element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
} else {
|
||||
final List<InternetAddress> addresses =
|
||||
await InternetAddress.lookup(item.serviceIp!);
|
||||
final List<String> itemList = addresses.first.address.split('.');
|
||||
for (String element in itemList) {
|
||||
serversList.add(int.parse(element));
|
||||
}
|
||||
}
|
||||
|
||||
final double typeDouble = int.parse(item.port!) / 256;
|
||||
final int type1 = typeDouble.toInt();
|
||||
final int type2 = int.parse(item.port!) % 256;
|
||||
serversList.add(type1);
|
||||
serversList.add(type2);
|
||||
}
|
||||
|
||||
final String? uidStr = await Storage.getUid();
|
||||
final List<String> uidList = <String>[uidStr.toString()];
|
||||
|
||||
// 判断是否登录账户
|
||||
final loginData = await Storage.getLoginData();
|
||||
|
||||
// 获取app用户的peerId
|
||||
String appPeerId = loginData?.starchart?.starchartId ?? '';
|
||||
IoSenderManage.senderConfiguringWifiCommand(
|
||||
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
|
||||
userID: await Storage.getUid(),
|
||||
IoSenderManage.gatewayConfiguringWifiCommand(
|
||||
ssid: state.wifiNameController.text,
|
||||
password: state.wifiPWDController.text,
|
||||
peerId: appPeerId,
|
||||
numberOfServers: state.configuringWifiEntity.value.data!.serviceNum,
|
||||
listOfServers: serversList,
|
||||
numberOfPhone: uidList.length,
|
||||
listOfPhone: uidList,
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
gatewayConfigurationStr: state.getGatewayConfigurationStr,
|
||||
);
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
@ -230,7 +212,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
|
||||
showBlueConnetctToast();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, isAddEquipment: true);
|
||||
}
|
||||
|
||||
final NetworkInfo _networkInfo = NetworkInfo();
|
||||
|
||||
@ -25,5 +25,5 @@ class ConfiguringWifiState{
|
||||
|
||||
TextEditingController wifiNameController = TextEditingController();
|
||||
TextEditingController wifiPWDController = TextEditingController();
|
||||
|
||||
String getGatewayConfigurationStr = '';
|
||||
}
|
||||
@ -1,9 +1,10 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/blue/io_gateway/io_gateway_getWifiList.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_getWifiList.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
|
||||
import '../../../../../blue/blue_manage.dart';
|
||||
@ -19,13 +20,15 @@ class WifiListLogic extends BaseGetXController {
|
||||
|
||||
// 获取解析后的数据
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
|
||||
void _initReplySubscription() {
|
||||
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
|
||||
if(reply is SenderGetWifiReply) {
|
||||
_replySubscription =
|
||||
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
|
||||
if (reply is GatewayGetWifiReply) {
|
||||
_replySendGetWifiParameters(reply);
|
||||
}
|
||||
|
||||
if(reply is SenderGetWifiListReply) {
|
||||
if (reply is GatewayGetWifiListReply) {
|
||||
_replyGetWifiListParameters(reply);
|
||||
}
|
||||
});
|
||||
@ -34,7 +37,7 @@ class WifiListLogic extends BaseGetXController {
|
||||
// 发送获取wifi列表数据解析
|
||||
Future<void> _replySendGetWifiParameters(Reply reply) async {
|
||||
final int status = reply.data[2];
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
showEasyLoading();
|
||||
@ -43,42 +46,24 @@ class WifiListLogic extends BaseGetXController {
|
||||
break;
|
||||
case 0x06:
|
||||
// 需要鉴权
|
||||
|
||||
// var token = await Storage.getStringList(saveBlueToken);
|
||||
// List<int> getTokenList = changeStringListToIntList(token!);
|
||||
//
|
||||
// var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
// List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
//
|
||||
// var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
// List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||
//
|
||||
// IoSenderManage.getWifiListCommand(
|
||||
// keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
|
||||
// userID: await Storage.getUid(),
|
||||
// token: getTokenList,
|
||||
// needAuthor: 1,
|
||||
// publicKey: publicKeyDataList,
|
||||
// privateKey: getPrivateKeyList,
|
||||
// );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置自动落锁数据解析
|
||||
// 获取WiFi数据解析
|
||||
Future<void> _replyGetWifiListParameters(Reply reply) async {
|
||||
final int status = reply.data[2];
|
||||
switch(status){
|
||||
switch (status) {
|
||||
case 0x00:
|
||||
//成功
|
||||
// showEasyLoading();
|
||||
dismissEasyLoading();
|
||||
state.sureBtnState.value = 0;
|
||||
|
||||
if (reply.data[6] > 0) {
|
||||
reply.data.removeRange(0, 7);
|
||||
if (reply.data[3] > 0) {
|
||||
reply.data.removeRange(0, 4);
|
||||
// 把得到的数据按33位分割成数组 然后塞进一个新的数组里面
|
||||
final List<List<int>> getList = splitList(reply.data, 33);
|
||||
final List<Map<String, String>> uploadList = <Map<String, String>>[];
|
||||
@ -92,7 +77,6 @@ class WifiListLogic extends BaseGetXController {
|
||||
state.wifiNameDataList.value = uploadList;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -101,44 +85,31 @@ class WifiListLogic extends BaseGetXController {
|
||||
|
||||
// 获取wifi列表
|
||||
Future<void> senderGetWifiListWifiAction() async {
|
||||
if(state.sureBtnState.value == 1){
|
||||
if (state.sureBtnState.value == 1) {
|
||||
return;
|
||||
}
|
||||
state.sureBtnState.value = 1;
|
||||
|
||||
showEasyLoading();
|
||||
showBlueConnetctToastTimer(action: (){
|
||||
showBlueConnetctToastTimer(action: () {
|
||||
dismissEasyLoading();
|
||||
state.sureBtnState.value = 0;
|
||||
});
|
||||
BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected){
|
||||
final List<String>? token = await Storage.getStringList(saveBlueToken);
|
||||
final List<int> getTokenList = changeStringListToIntList(token!);
|
||||
|
||||
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
final List<String>? publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
final List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.getWifiListCommand(
|
||||
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
|
||||
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
||||
(BluetoothConnectionState connectionState) async {
|
||||
if (connectionState == BluetoothConnectionState.connected) {
|
||||
IoSenderManage.gatewayGetWifiCommand(
|
||||
userID: await Storage.getUid(),
|
||||
token: getTokenList,
|
||||
needAuthor: 1,
|
||||
publicKey: publicKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||
dismissEasyLoading();
|
||||
state.sureBtnState.value = 0;
|
||||
cancelBlueConnetctToastTimer();
|
||||
if(state.ifCurrentScreen.value == true){
|
||||
if (state.ifCurrentScreen.value == true) {
|
||||
showBlueConnetctToast();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, isAddEquipment: true);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -160,5 +131,4 @@ class WifiListLogic extends BaseGetXController {
|
||||
super.onClose();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
@ -28,31 +27,39 @@ class _WifiListPageState extends State<WifiListPage> {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: TitleAppBar(
|
||||
barTitle: 'WIFI列表'.tr,
|
||||
haveBack: true,
|
||||
actionsList: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
'刷新'.tr, style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||
),
|
||||
onPressed: logic.senderGetWifiListWifiAction,
|
||||
),
|
||||
],
|
||||
backgroundColor: AppColors.mainColor),
|
||||
barTitle: 'WIFI列表'.tr,
|
||||
haveBack: true,
|
||||
actionsList: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
'刷新'.tr,
|
||||
style: TextStyle(color: Colors.white, fontSize: 24.sp),
|
||||
),
|
||||
onPressed: logic.senderGetWifiListWifiAction,
|
||||
),
|
||||
],
|
||||
backgroundColor: AppColors.mainColor),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Obx(() => state.wifiNameDataList.value.isNotEmpty ? ListView.builder(
|
||||
itemCount: state.wifiNameDataList.value.length,
|
||||
itemBuilder: (BuildContext c, int index) {
|
||||
Map wifiNameStr = state.wifiNameDataList.value[index];
|
||||
return _messageListItem(wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
|
||||
Get.toNamed(Routers.configuringWifiPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value,
|
||||
'wifiName': wifiNameStr['wifiName'],
|
||||
});
|
||||
});
|
||||
}) : NoData(noDataHeight: 1.sh - ScreenUtil().statusBarHeight - ScreenUtil().bottomBarHeight - 64.h)),
|
||||
child: Obx(() => state.wifiNameDataList.value.isNotEmpty
|
||||
? ListView.builder(
|
||||
itemCount: state.wifiNameDataList.value.length,
|
||||
itemBuilder: (BuildContext c, int index) {
|
||||
Map wifiNameStr = state.wifiNameDataList.value[index];
|
||||
return _messageListItem(
|
||||
wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
|
||||
Get.toNamed(Routers.configuringWifiPage, arguments: {
|
||||
'lockSetInfoData': state.lockSetInfoData.value,
|
||||
'wifiName': wifiNameStr['wifiName'],
|
||||
});
|
||||
});
|
||||
})
|
||||
: NoData(
|
||||
noDataHeight: 1.sh -
|
||||
ScreenUtil().statusBarHeight -
|
||||
ScreenUtil().bottomBarHeight -
|
||||
64.h)),
|
||||
),
|
||||
SubmitBtn(
|
||||
btnName: '手动配网'.tr,
|
||||
@ -60,16 +67,16 @@ class _WifiListPageState extends State<WifiListPage> {
|
||||
borderRadius: 20.w,
|
||||
padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
|
||||
onClick: () {
|
||||
Get.toNamed(Routers.configuringWifiPage, arguments: <String, LockSetInfoData>{
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
Get.toNamed(Routers.configuringWifiPage,
|
||||
arguments: <String, LockSetInfoData>{
|
||||
'lockSetInfoData': state.lockSetInfoData.value
|
||||
});
|
||||
}),
|
||||
SizedBox(
|
||||
height: 64.h,
|
||||
)
|
||||
],
|
||||
)
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
Widget _messageListItem(String wifiName, String rssi, Function() action) {
|
||||
@ -91,7 +98,7 @@ class _WifiListPageState extends State<WifiListPage> {
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 79.h,
|
||||
width: 1.sw - 20.w*2,
|
||||
width: 1.sw - 20.w * 2,
|
||||
child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:star_lock/network/api_repository.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import 'package:video_thumbnail/video_thumbnail.dart';
|
||||
import 'videoLog_state.dart';
|
||||
|
||||
class VideoLogLogic extends BaseGetXController {
|
||||
@ -11,10 +14,33 @@ class VideoLogLogic extends BaseGetXController {
|
||||
);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
state.videoLogList.value = entity.data!;
|
||||
|
||||
state.videoLogList.refresh();
|
||||
// state.videoLogList.forEach((element) {
|
||||
// final recordList = element.recordList;
|
||||
// if (recordList != null && recordList.isNotEmpty) {
|
||||
// recordList.forEach((item) {
|
||||
// if (item.videoUrl != null && item.videoUrl!.isNotEmpty) {
|
||||
// final coverImage = aw handleVideoCoverImage(item.videoUrl);
|
||||
// state.videoCoverList.add(coverImage);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List?> handleVideoCoverImage(videoUrl) async {
|
||||
final uint8list = await VideoThumbnail.thumbnailData(
|
||||
video: videoUrl,
|
||||
imageFormat: ImageFormat.JPEG,
|
||||
maxWidth: 128,
|
||||
// specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio
|
||||
quality: 25,
|
||||
);
|
||||
return uint8list;
|
||||
}
|
||||
|
||||
@override
|
||||
onReady() {
|
||||
super.onReady();
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
@ -11,7 +10,7 @@ import 'package:star_lock/tools/noData.dart';
|
||||
|
||||
import '../../../../app_settings/app_colors.dart';
|
||||
import '../../../../tools/titleAppBar.dart';
|
||||
import 'videoLog_logic.dart';
|
||||
import 'videoLog_logic.dart';import 'package:video_thumbnail/video_thumbnail.dart';
|
||||
|
||||
class VideoLogPage extends StatefulWidget {
|
||||
const VideoLogPage({Key? key}) : super(key: key);
|
||||
@ -293,11 +292,7 @@ class _VideoLogPageState extends State<VideoLogPage> {
|
||||
color: Colors.white,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.w),
|
||||
child: Image(
|
||||
fit: BoxFit.cover,
|
||||
image: Image.network(recordData.imagesUrl ??
|
||||
'images/icon_video_placeholder.jpg')
|
||||
.image),
|
||||
child: _buildImageOrVideoItem(recordData),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5.h),
|
||||
@ -310,4 +305,30 @@ class _VideoLogPageState extends State<VideoLogPage> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildImageOrVideoItem(RecordListData recordData) {
|
||||
if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) {
|
||||
return _buildVideoItem(recordData);
|
||||
} else {
|
||||
return _buildImageItem(recordData);
|
||||
}
|
||||
}
|
||||
|
||||
_buildVideoItem(RecordListData recordData) async {
|
||||
final uint8list = await VideoThumbnail.thumbnailData(
|
||||
video: recordData.videoUrl!,
|
||||
imageFormat: ImageFormat.JPEG,
|
||||
maxWidth: 128,
|
||||
// specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio
|
||||
quality: 25,
|
||||
);
|
||||
return Image.memory(uint8list!);
|
||||
}
|
||||
|
||||
_buildImageItem(RecordListData recordData) {
|
||||
return Image.network(
|
||||
recordData.imagesUrl!,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
|
||||
|
||||
@ -6,6 +8,7 @@ class VideoLogState {
|
||||
var localList = [];
|
||||
var getLockId = 0.obs;
|
||||
var videoLogList = <CloudStorageData>[].obs;
|
||||
var videoCoverList = <Uint8List>[].obs;
|
||||
|
||||
VideoLogState() {
|
||||
Map map = Get.arguments;
|
||||
|
||||
@ -67,7 +67,10 @@ abstract class Api {
|
||||
final String getWifiServiceIpURL = '/wifiLock/getWifiServiceIp'; // 获取Wifi锁服务器
|
||||
final String updateLockSettingUrl =
|
||||
'/v2/lockSetting/updateLockSetting'; // 锁设置里面所有的设置
|
||||
|
||||
final String deviceNetworkConfiguration =
|
||||
'/deviceNetwork/setting'; // 设备网络配置
|
||||
final String getDeviceNetworkConfiguration =
|
||||
'/deviceNetwork/getNetworkInfo'; // 设备网络配置
|
||||
final String roomQueryDateUrl = '/room/queryDate'; // 获取网关时间
|
||||
final String lockDiagnoseUrl = '/room/uploadLockInfo'; // 锁诊断
|
||||
final String getServerDatetimeUrl = '/check/getServerDatetime'; // 获取服务器当前时间
|
||||
|
||||
@ -2714,6 +2714,38 @@ class ApiProvider extends BaseProvider {
|
||||
}),
|
||||
isUnShowLoading: true,
|
||||
isShowNetworkErrorMsg: false);
|
||||
|
||||
/// 更新网络信息 配网之后把网络信息提交到服务器保存
|
||||
Future<Response> settingDeviceNetwork(
|
||||
int deviceType,
|
||||
String deviceMac,
|
||||
String wifiName,
|
||||
String networkMac,
|
||||
String secretKey,
|
||||
String peerId,
|
||||
) =>
|
||||
post(
|
||||
deviceNetworkConfiguration.toUrl,
|
||||
jsonEncode({
|
||||
'deviceType': deviceType,
|
||||
'deviceMac': deviceMac,
|
||||
'wifiName': wifiName,
|
||||
'networkMac': networkMac,
|
||||
'secretKey': secretKey,
|
||||
'peerId': peerId,
|
||||
}));
|
||||
|
||||
/// 获取设备配网信息
|
||||
Future<Response> getDeviceNetwork(
|
||||
int deviceType,
|
||||
String deviceMac,
|
||||
) =>
|
||||
post(
|
||||
getDeviceNetworkConfiguration.toUrl,
|
||||
jsonEncode({
|
||||
'deviceType': deviceType,
|
||||
'deviceMac': deviceMac,
|
||||
}));
|
||||
}
|
||||
|
||||
extension ExtensionString on String {
|
||||
|
||||
@ -12,6 +12,7 @@ import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/ma
|
||||
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/face/addFace/addFace_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprint_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/basicInformation/basicInformation/KeyDetailEntity.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/updateLockInfo_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/version_entity.dart';
|
||||
@ -2712,4 +2713,30 @@ class ApiRepository {
|
||||
|
||||
return LoginEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
// 设置设备配网信息
|
||||
Future<LoginEntity> settingDeviceNetwork({
|
||||
required int deviceType,
|
||||
required String deviceMac,
|
||||
required String wifiName,
|
||||
required String networkMac,
|
||||
required String secretKey,
|
||||
required String peerId,
|
||||
}) async {
|
||||
final res = await apiProvider.settingDeviceNetwork(
|
||||
deviceType, deviceMac, wifiName, networkMac, secretKey, peerId);
|
||||
return LoginEntity.fromJson(res.body);
|
||||
}
|
||||
|
||||
// 获取设备配网信息
|
||||
Future<DeviceNetwork> getDeviceNetwork({
|
||||
required int deviceType,
|
||||
required String deviceMac,
|
||||
}) async {
|
||||
final res = await apiProvider.getDeviceNetwork(
|
||||
deviceType,
|
||||
deviceMac,
|
||||
);
|
||||
return DeviceNetwork.fromJson(res.body);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
enum TalkStatus {
|
||||
none, // 无状态
|
||||
waitingAnswer, // 等待接听
|
||||
proactivelyCallWaitingAnswer, // 主动呼叫等待接听
|
||||
passiveCallWaitingAnswer, // 被动呼叫等待接听
|
||||
answeredSuccessfully, // 接听成功
|
||||
waitingData, // 等待数据
|
||||
hangingUpDuring, // 通话中挂断
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/appRouters.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/blue/reciver_data.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||
@ -25,10 +26,8 @@ class UdpBlePassThroughHandler extends ScpMessageBaseHandle
|
||||
@override
|
||||
void handleResp(ScpMessage scpMessage) {
|
||||
final BleResp bleResp = scpMessage.Payload;
|
||||
// 如果回复成功
|
||||
// if (bleResp.status == BleResp_StatusE.SUCCESS) {
|
||||
AppLog.log('收到蓝牙消息回复:${bleResp.structData}');
|
||||
// }
|
||||
AppLog.log('收到蓝牙消息回复:${bleResp.structData}');
|
||||
final data = CommandReciverManager.parseData(bleResp.structData);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -32,7 +32,7 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
|
||||
@override
|
||||
void handleRealTimeData(ScpMessage scpMessage) {
|
||||
// 收到数据后调用更新,防止定时器超时
|
||||
// talkDataOverTimeTimerManager.renew();
|
||||
talkDataOverTimeTimerManager.renew();
|
||||
if (scpMessage.Payload != null) {
|
||||
final TalkData talkData = scpMessage.Payload;
|
||||
// 处理音视频数据
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
|
||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
||||
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
||||
@ -37,10 +38,22 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
||||
// print('收到预期音视频数据回复,scpMessage:$scpMessage');
|
||||
// 停止发送预期数据的定时器
|
||||
startChartManage.stopTalkExpectMessageTimer();
|
||||
// 停止发送对讲请求
|
||||
startChartManage.stopCallRequestMessageTimer();
|
||||
talkViewState.rotateAngle.value = talkExpectResp.rotate ?? 0;
|
||||
// 收到预期数据的应答后,代表建立了连接,启动通话保持的监听
|
||||
// 启动通话保持监听定时器(用来判断如果x秒内没有收到通话保持则执行的操作);
|
||||
talkePingOverTimeTimerManager.start();
|
||||
// 启动通话数据监听
|
||||
talkDataOverTimeTimerManager.start();
|
||||
if (talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) {
|
||||
// 停止播放铃声
|
||||
stopRingtone();
|
||||
// 设置为接听成功
|
||||
talkStatus.setAnsweredSuccessfully();
|
||||
// 主动呼叫时需要启动ping
|
||||
startChartManage.startTalkPingMessageTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,20 +24,26 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle
|
||||
replySuccessMessage(scpMessage);
|
||||
talkStatus.setHangingUpDuring();
|
||||
stopRingtone();
|
||||
StartChartManage().stopTalkExpectMessageTimer();
|
||||
StartChartManage().stopTalkPingMessageTimer();
|
||||
startChartManage.stopTalkExpectMessageTimer();
|
||||
startChartManage.stopTalkPingMessageTimer();
|
||||
// 挂断之后,停止对讲请求超时监听定时器
|
||||
|
||||
talkeRequestOverTimeTimerManager.cancel();
|
||||
talkePingOverTimeTimerManager.cancel();
|
||||
talkDataOverTimeTimerManager.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
void handleResp(ScpMessage scpMessage) {
|
||||
talkStatus.setHangingUpDuring();
|
||||
stopRingtone();
|
||||
startChartManage.stopTalkExpectMessageTimer();
|
||||
startChartManage.stopTalkPingMessageTimer();
|
||||
|
||||
// 挂断之后,停止对讲请求超时监听定时器
|
||||
talkeRequestOverTimeTimerManager.renew();
|
||||
talkeRequestOverTimeTimerManager.cancel();
|
||||
talkePingOverTimeTimerManager.renew();
|
||||
talkePingOverTimeTimerManager.cancel();
|
||||
talkDataOverTimeTimerManager.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -22,10 +22,15 @@ class UdpTalkRejectHandler extends ScpMessageBaseHandle
|
||||
replySuccessMessage(scpMessage);
|
||||
// 停止铃声
|
||||
stopRingtone();
|
||||
StartChartManage().stopTalkExpectMessageTimer();
|
||||
StartChartManage().stopTalkPingMessageTimer();
|
||||
startChartManage.stopTalkPingMessageTimer();
|
||||
startChartManage.stopTalkExpectMessageTimer();
|
||||
// 收到接听拒绝回复
|
||||
talkStatus.setRejected();
|
||||
// 拒绝接听之后,停止对讲请求超时监听定时器
|
||||
|
||||
talkeRequestOverTimeTimerManager.cancel();
|
||||
talkePingOverTimeTimerManager.cancel();
|
||||
talkDataOverTimeTimerManager.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -35,10 +40,9 @@ class UdpTalkRejectHandler extends ScpMessageBaseHandle
|
||||
stopRingtone();
|
||||
|
||||
// 拒绝接听之后,停止对讲请求超时监听定时器
|
||||
talkeRequestOverTimeTimerManager.renew();
|
||||
talkeRequestOverTimeTimerManager.cancel();
|
||||
talkePingOverTimeTimerManager.renew();
|
||||
talkePingOverTimeTimerManager.cancel();
|
||||
talkDataOverTimeTimerManager.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -24,26 +24,29 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
||||
replySuccessMessage(scpMessage);
|
||||
// 判断是否登录账户
|
||||
final loginData = await Storage.getLoginData();
|
||||
if (loginData == null ||
|
||||
talkStatus.status == TalkStatus.waitingAnswer ||
|
||||
talkStatus.status == TalkStatus.answeredSuccessfully) {
|
||||
// 如果已经是等待接听了,就不在处理剩下的请求
|
||||
return;
|
||||
if (loginData != null &&
|
||||
talkStatus.status != TalkStatus.passiveCallWaitingAnswer) {
|
||||
// 收到对讲请求
|
||||
final TalkReq talkReq = scpMessage.Payload;
|
||||
startChartManage.FromPeerId = scpMessage.ToPeerId!;
|
||||
startChartManage.ToPeerId = scpMessage.FromPeerId!;
|
||||
// 处理收到接听请求后的事件
|
||||
_talkRequestEvent(talkObjectName: talkReq.callerName);
|
||||
}
|
||||
// 收到对讲请求
|
||||
final TalkReq talkReq = scpMessage.Payload;
|
||||
startChartManage.FromPeerId = scpMessage.ToPeerId!;
|
||||
startChartManage.ToPeerId = scpMessage.FromPeerId!;
|
||||
// 处理收到接听请求后的事件
|
||||
_talkRequestEvent(talkObjectName: talkReq.callerName);
|
||||
}
|
||||
|
||||
@override
|
||||
void handleResp(ScpMessage scpMessage) {
|
||||
// 收到对讲请求回复
|
||||
final GenericResp genericResp = scpMessage.Payload;
|
||||
if (genericResp.code == 0) {
|
||||
print('发送对讲成功,已经收到对方的回复');
|
||||
if (checkGenericRespSuccess(genericResp)) {
|
||||
// 收到对讲请求的应答
|
||||
startChartManage.FromPeerId = scpMessage.ToPeerId!;
|
||||
startChartManage.ToPeerId = scpMessage.FromPeerId!;
|
||||
// 发送预期数据
|
||||
startChartManage.startTalkExpectTimer();
|
||||
// 停止发送对讲请求
|
||||
startChartManage.stopCallRequestMessageTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +65,7 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
|
||||
// 显示状态栏弹窗
|
||||
_showTalkRequestNotification(talkObjectName: talkObjectName);
|
||||
// 设置为等待接听状态
|
||||
talkStatus.setWaitingAnswer();
|
||||
talkStatus.setPassiveCallWaitingAnswer();
|
||||
// 启动对讲请求超时定时器
|
||||
talkeRequestOverTimeTimerManager.start();
|
||||
// 收到呼叫请求,跳转到接听页面
|
||||
|
||||
@ -2,12 +2,12 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/talk/other/audio_player_manager.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/talk_constant.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
||||
import 'package:star_lock/talk/startChart/status/start_chart_talk_status.dart';
|
||||
|
||||
|
||||
class TalkDataOverTimeTimerManager {
|
||||
// 单例实例
|
||||
static final TalkDataOverTimeTimerManager _instance =
|
||||
@ -29,22 +29,24 @@ class TalkDataOverTimeTimerManager {
|
||||
// 超时处理函数
|
||||
static void _handleTalkeDataOverTime() {
|
||||
EasyLoading.showToast('通话连接失败', duration: 2000.milliseconds);
|
||||
// 没有通话数据,发送挂断数据
|
||||
StartChartManage().sendTalkHangupMessage();
|
||||
StartChartManage().stopTalkPingMessageTimer();
|
||||
StartChartManage().stopTalkExpectMessageTimer();
|
||||
talkStatus.setNotTalkData();
|
||||
talkStatus.setEnd();
|
||||
AudioPlayerManager().stopRingtone();
|
||||
}
|
||||
|
||||
// 启动定时器
|
||||
void start() {
|
||||
_timer = Timer(timeout, onTimeout);
|
||||
_timer ??= Timer(timeout, onTimeout);
|
||||
}
|
||||
|
||||
// 续签定时器
|
||||
void renew() {
|
||||
_timer?.cancel();
|
||||
_timer = null;
|
||||
start();
|
||||
}
|
||||
|
||||
// 取消定时器
|
||||
|
||||
@ -27,7 +27,8 @@ class TalkeRequestOverTimeTimerManager {
|
||||
|
||||
// 超时处理函数
|
||||
static void _handleTalkeRequestOverTime() {
|
||||
if (talkStatus.status == TalkStatus.waitingAnswer) {
|
||||
if (talkStatus.status == TalkStatus.passiveCallWaitingAnswer ||
|
||||
talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) {
|
||||
EasyLoading.showToast('通话未接通,以挂断', duration: 2000.milliseconds);
|
||||
// 超时未接听,发送挂断请求
|
||||
StartChartManage().sendTalkRejectMessage();
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import 'dart:async';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/appRouters.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/login/login/entity/LoginData.dart';
|
||||
@ -69,6 +72,7 @@ class StartChartManage {
|
||||
|
||||
String ToPeerId = ''; // 对端ID
|
||||
String FromPeerId = ''; // 我的ID
|
||||
String lockPeerId = '';
|
||||
|
||||
// echo测试peer对端
|
||||
final String echoPeerId = '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH';
|
||||
@ -82,6 +86,8 @@ class StartChartManage {
|
||||
int _defaultIntervalTime = 1; // 默认定时发送间隔(s)
|
||||
Timer? talkDataTimer; // 发送通话数据消息定时器
|
||||
Timer? rbcuInfoTimer; // p2p地址交换定时器
|
||||
Timer? talkRequestTimer; // 对讲请求定时器
|
||||
final int maxAttempts = 15; // 最大执行次数
|
||||
|
||||
final int _maxPayloadSize = 8 * 1024; // 分包大小
|
||||
|
||||
@ -300,12 +306,35 @@ class StartChartManage {
|
||||
await _sendMessage(message: message);
|
||||
}
|
||||
|
||||
/// 启动持续发送对讲请求
|
||||
void startCallRequestMessageTimer({required String ToPeerId}) async {
|
||||
// 如果已经处于等待接听状态就不发送
|
||||
if (talkStatus.status != TalkStatus.proactivelyCallWaitingAnswer) {
|
||||
// 停止播放铃声
|
||||
AudioPlayerManager().playRingtone();
|
||||
Get.toNamed(
|
||||
Routers.starChartTalkView,
|
||||
);
|
||||
}
|
||||
talkRequestTimer ??= Timer.periodic(
|
||||
Duration(
|
||||
seconds: _defaultIntervalTime,
|
||||
),
|
||||
(Timer timer) async {
|
||||
await sendCallRequestMessage(ToPeerId: ToPeerId);
|
||||
},
|
||||
);
|
||||
talkStatus.setProactivelyCallWaitingAnswer();
|
||||
}
|
||||
|
||||
/// 停止持续发送对讲请求
|
||||
void stopCallRequestMessageTimer() async {
|
||||
talkRequestTimer?.cancel();
|
||||
talkRequestTimer = null;
|
||||
}
|
||||
|
||||
// 发送对讲请求消息
|
||||
Future<void> sendCallRequestMessage({required String ToPeerId}) async {
|
||||
if (talkStatus.status == TalkStatus.answeredSuccessfully) {
|
||||
_log(text: '已经在通话中,请勿重复发送对讲请求');
|
||||
return;
|
||||
}
|
||||
// 组装上线消息
|
||||
final message = MessageCommand.talkRequestMessage(
|
||||
FromPeerId: FromPeerId,
|
||||
@ -432,10 +461,6 @@ class StartChartManage {
|
||||
|
||||
// 发送拒绝接听消息
|
||||
void sendTalkRejectMessage() async {
|
||||
if (talkStatus.status != TalkStatus.waitingAnswer) {
|
||||
_log(text: '当前未处于等待接听状态, 无法发送拒绝接听消息');
|
||||
return;
|
||||
}
|
||||
final message = MessageCommand.talkRejectMessage(
|
||||
ToPeerId: ToPeerId,
|
||||
FromPeerId: FromPeerId,
|
||||
@ -450,8 +475,11 @@ class StartChartManage {
|
||||
// 停止发送通话保持消息、通话预期数据请求
|
||||
stopTalkExpectMessageTimer();
|
||||
stopTalkPingMessageTimer();
|
||||
stopCallRequestMessageTimer();
|
||||
// 取消定时器
|
||||
|
||||
talkePingOverTimeTimerManager.cancel();
|
||||
talkDataOverTimeTimerManager.cancel();
|
||||
}
|
||||
|
||||
// 发送期望接受消息
|
||||
@ -508,10 +536,6 @@ class StartChartManage {
|
||||
|
||||
// 发送通话中挂断消息
|
||||
Future<void> sendTalkHangupMessage() async {
|
||||
if (talkStatus.status != TalkStatus.answeredSuccessfully) {
|
||||
_log(text: '当前未处于接听状态, 无法发送通话中挂断消息');
|
||||
return;
|
||||
}
|
||||
final message = MessageCommand.talkHangupMessage(
|
||||
ToPeerId: ToPeerId,
|
||||
FromPeerId: FromPeerId,
|
||||
@ -526,8 +550,10 @@ class StartChartManage {
|
||||
// 停止发送通话保持消息、通话预期数据请求
|
||||
stopTalkExpectMessageTimer();
|
||||
stopTalkPingMessageTimer();
|
||||
stopCallRequestMessageTimer();
|
||||
// 取消定时器
|
||||
talkePingOverTimeTimerManager.cancel();
|
||||
talkDataOverTimeTimerManager.cancel();
|
||||
}
|
||||
|
||||
// 重新上线
|
||||
|
||||
@ -38,7 +38,8 @@ class StartChartTalkStatus {
|
||||
}
|
||||
|
||||
// 提供状态设置方法
|
||||
void setWaitingAnswer() => _setStatus(TalkStatus.waitingAnswer);
|
||||
void setPassiveCallWaitingAnswer() => _setStatus(TalkStatus.passiveCallWaitingAnswer);
|
||||
void setProactivelyCallWaitingAnswer() => _setStatus(TalkStatus.proactivelyCallWaitingAnswer);
|
||||
|
||||
void setWaitingData() => _setStatus(TalkStatus.waitingData);
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ import '../../../../tools/baseGetXController.dart';
|
||||
|
||||
class TalkViewLogic extends BaseGetXController {
|
||||
final TalkViewState state = TalkViewState();
|
||||
final LockDetailState lockDetailState = Get.find<LockDetailLogic>().state;
|
||||
final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state;
|
||||
Timer? _syncTimer; // 音视频播放刷新率定时器
|
||||
int _startTime = 0; // 开始播放时间戳,用于判断帧数据中的时间戳位置
|
||||
final int bufferSize = 20; // 缓冲区大小(以帧为单位)
|
||||
|
||||
@ -280,7 +280,8 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
logic.stopProcessingAudio();
|
||||
},
|
||||
onClick: () async {
|
||||
if (state.talkStatus.value == TalkStatus.waitingAnswer) {
|
||||
if (state.talkStatus.value ==
|
||||
TalkStatus.passiveCallWaitingAnswer) {
|
||||
// 接听
|
||||
logic.initiateAnswerCommand();
|
||||
}
|
||||
@ -298,12 +299,12 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
'开锁',
|
||||
AppColors.mainColor,
|
||||
onClick: () {
|
||||
if (UDPManage().remoteUnlock == 1) {
|
||||
// if (UDPManage().remoteUnlock == 1) {
|
||||
logic.udpOpenDoorAction();
|
||||
// showDeletPasswordAlertDialog(context);
|
||||
} else {
|
||||
logic.showToast('请在锁设置中开启远程开锁'.tr);
|
||||
}
|
||||
// } else {
|
||||
// logic.showToast('请在锁设置中开启远程开锁'.tr);
|
||||
// }
|
||||
},
|
||||
)
|
||||
]);
|
||||
@ -311,9 +312,10 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
|
||||
String getAnswerBtnImg() {
|
||||
switch (state.talkStatus.value) {
|
||||
case TalkStatus.waitingAnswer:
|
||||
case TalkStatus.passiveCallWaitingAnswer:
|
||||
return 'images/main/icon_lockDetail_monitoringAnswerCalls.png';
|
||||
case TalkStatus.answeredSuccessfully:
|
||||
case TalkStatus.proactivelyCallWaitingAnswer:
|
||||
return 'images/main/icon_lockDetail_monitoringUnTalkback.png';
|
||||
default:
|
||||
return 'images/main/icon_lockDetail_monitoringAnswerCalls.png';
|
||||
@ -322,8 +324,9 @@ class _TalkViewPageState extends State<TalkViewPage>
|
||||
|
||||
String getAnswerBtnName() {
|
||||
switch (state.talkStatus.value) {
|
||||
case TalkStatus.waitingAnswer:
|
||||
case TalkStatus.passiveCallWaitingAnswer:
|
||||
return '接听'.tr;
|
||||
case TalkStatus.proactivelyCallWaitingAnswer:
|
||||
case TalkStatus.answeredSuccessfully:
|
||||
return '长按说话'.tr;
|
||||
default:
|
||||
|
||||
@ -33,6 +33,7 @@ const String automaticLockOffTime = 'automaticLockOffTime'; //自动关锁时间
|
||||
const String associationUrl = 'associationUrl'; //ios跳转微信的 url
|
||||
const String starChartRegisterNodeInfo = 'starChartRegisterNodeInfo'; //星图注册信息
|
||||
const String relayInfo = 'relayInfo'; //星图中继服务器信息
|
||||
const String lockNetWorkInfo = 'lockNetWorkInfo'; //锁板配网信息
|
||||
|
||||
class Storage {
|
||||
factory Storage() => _instance;
|
||||
@ -273,6 +274,23 @@ class Storage {
|
||||
await Storage.setString(relayInfo, jsonEncode(relayInfoEntity));
|
||||
}
|
||||
|
||||
// 保存锁板的配网信息
|
||||
static Future<void> saveLockNetWorkInfo(Map<String, dynamic> info) async {
|
||||
await Storage.setString(lockNetWorkInfo, json.encode(info));
|
||||
}
|
||||
|
||||
// 获取锁板的配网信息
|
||||
static Future<Map<String, dynamic>?> getLockNetWorkInfo() async {
|
||||
Map<String, dynamic>? info = null;
|
||||
final String? data = await Storage.getString(lockNetWorkInfo);
|
||||
if (data == null || data.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
// 解析 JSON 字符串为 Map
|
||||
info = json.decode(data);
|
||||
return info;
|
||||
}
|
||||
|
||||
// 获取星图注册节点信息
|
||||
static Future<RelayInfoEntity?> getRelayInfo() async {
|
||||
RelayInfoEntity? relayInfoEntity;
|
||||
|
||||
@ -261,6 +261,8 @@ dependencies:
|
||||
#图库保存
|
||||
gallery_saver: ^2.3.2
|
||||
fixnum: ^1.1.1
|
||||
# 获取视频封面
|
||||
video_thumbnail: ^0.5.3
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user