鸿蒙端提交
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
| 日期 | 版本 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-06-06 | v8 | 新增 `app_tracking_transparency` 差异对照条目;新增 `nearby_connections` 鸿蒙端本地stub包说明;新增 §2.10 nearby_connections鸿蒙适配说明 |
|
||||
| 2026-06-02 | v7 | **重大变更**:pubspec.yaml 拆分为双模板(pubspec.ohos.yaml + pubspec.macos.yaml),pubspec.yaml 不再提交到 Git;新增三方库变更通知机制;新增 setup_pubspec.ps1 脚本 |
|
||||
| 2026-06-02 | v6 | 鸿蒙端 pubspec.yaml 同步 bitsdojo_window → window_manager 迁移;更新 file_picker 本地包版本注释(v8.3.7→v11.0.0-ohos.1);更新 speech_to_text(^7.0.0→^7.4.0)、live_activities(^2.0.0→^2.4.9) 远程版本号;补充 dependency_overrides 中 bitsdojo_window_windows 移除说明 |
|
||||
| 2026-06-01 | v5 | 新增 §2.6 pub cache 补丁说明;标记 bitsdojo_window 迁移完成;file_picker 升级到 12.x |
|
||||
@@ -148,6 +149,7 @@ Error: The getter 'ohos' isn't defined for the class 'TargetPlatform'
|
||||
| connectivity_plus | `path: packages/connectivity_plus` | `^7.1.1` |
|
||||
| device_info_plus | `path: packages/device_info_plus` | `^13.1.0` |
|
||||
| permission_handler | `path: packages/permission_handler` | `^12.0.1` |
|
||||
| app_tracking_transparency | `^2.0.6` | `^2.0.6` |
|
||||
| flutter_local_notifications | `path: packages/flutter_local_notifications` | `^21.0.0` |
|
||||
| url_launcher | `path: packages/url_launcher` | `^6.3.2` |
|
||||
| app_links | `path: packages/app_links` | `^7.0.0` |
|
||||
@@ -174,6 +176,7 @@ Error: The getter 'ohos' isn't defined for the class 'TargetPlatform'
|
||||
| mobile_scanner | `path: packages/mobile_scanner` | `^7.1.4` |
|
||||
| wifi_iot | `path: packages/wifi_iot` | `^0.3.19` |
|
||||
| nearby_service | `path: packages/nearby_service` | `^0.2.1` |
|
||||
| nearby_connections | `path: packages/nearby_connections` (stub) | `^4.1.1` |
|
||||
| sqflite | `path: packages/sqflite` | `^2.4.1` |
|
||||
| workmanager | `path: packages/workmanager` | `^0.9.0` |
|
||||
| flutter_tts | `path: packages/flutter_tts` | `^4.2.0` |
|
||||
@@ -345,6 +348,36 @@ MacBook Pro 端使用 pub.dev 版本 `^0.9.1`,鸿蒙端的 `ohosName` 参数
|
||||
home_widget: ^0.9.1
|
||||
```
|
||||
|
||||
#### 2.8.7 nearby_connections(鸿蒙端本地stub包)
|
||||
|
||||
`nearby_connections` 仅支持 Android/iOS 平台(Google Nearby Connections API),不支持鸿蒙。
|
||||
鸿蒙端使用本地 stub 包 `packages/nearby_connections/`,提供与 4.x API 一致的类型定义和方法签名,
|
||||
但所有方法调用抛出 `UnsupportedError`。代码中通过 `isP2pSupported` 守卫,鸿蒙端不会实际调用 P2P 方法。
|
||||
|
||||
```yaml
|
||||
# 鸿蒙端使用本地 stub 包
|
||||
nearby_connections:
|
||||
path: packages/nearby_connections
|
||||
|
||||
# MacBook Pro 端使用远程版本
|
||||
nearby_connections: ^4.1.1
|
||||
```
|
||||
|
||||
> **注意**:鸿蒙端 stub 包的 Dart API 与远程版本完全一致(枚举、类型、方法签名),
|
||||
> 编译不会报错。运行时由 `NearbyServiceAdapter.isP2pSupported` 守卫,
|
||||
> 鸿蒙端 P2P 功能不可用,仅 `nearby_service` 原生引擎可用。
|
||||
|
||||
#### 2.8.8 app_tracking_transparency(两端均使用远程版本)
|
||||
|
||||
`app_tracking_transparency` 是 iOS 专属权限库(App Tracking Transparency),
|
||||
两端均使用远程版本 `^2.0.6`,无需本地适配。代码中通过 `Platform.isIOS` 条件守卫,
|
||||
非 iOS 平台直接返回授权成功,不影响鸿蒙/Android/macOS 编译。
|
||||
|
||||
```yaml
|
||||
# 两端配置相同
|
||||
app_tracking_transparency: ^2.0.6
|
||||
```
|
||||
|
||||
### 2.9 ⚠️ pub cache 补丁(MacBook Pro 端必读)
|
||||
|
||||
> **关键问题**:`dependency_overrides` 中 `win32: ^6.0.1` 导致部分依赖 `win32 ^5.x` 的三方包编译失败。
|
||||
|
||||
@@ -114,16 +114,8 @@ enum AppPermission {
|
||||
CupertinoIcons.antenna_radiowaves_left_right,
|
||||
Color(0xFF64D2FF),
|
||||
),
|
||||
microphone(
|
||||
Permission.microphone,
|
||||
CupertinoIcons.mic_fill,
|
||||
Color(0xFFFF3B30),
|
||||
),
|
||||
storage(
|
||||
Permission.storage,
|
||||
CupertinoIcons.folder_fill,
|
||||
Color(0xFFFF9500),
|
||||
),
|
||||
microphone(Permission.microphone, CupertinoIcons.mic_fill, Color(0xFFFF3B30)),
|
||||
storage(Permission.storage, CupertinoIcons.folder_fill, Color(0xFFFF9500)),
|
||||
network(
|
||||
Permission.notification,
|
||||
CupertinoIcons.wifi,
|
||||
@@ -537,37 +529,24 @@ class PermissionService {
|
||||
}
|
||||
|
||||
/// 快捷方法: 请求相机权限
|
||||
static Future<bool> requestCamera(BuildContext context) => requestPermission(
|
||||
context,
|
||||
AppPermission.camera,
|
||||
);
|
||||
static Future<bool> requestCamera(BuildContext context) =>
|
||||
requestPermission(context, AppPermission.camera);
|
||||
|
||||
/// 快捷方法: 请求相册权限
|
||||
static Future<bool> requestPhotos(BuildContext context) => requestPermission(
|
||||
context,
|
||||
AppPermission.photos,
|
||||
);
|
||||
static Future<bool> requestPhotos(BuildContext context) =>
|
||||
requestPermission(context, AppPermission.photos);
|
||||
|
||||
/// 快捷方法: 请求通知权限
|
||||
static Future<bool> requestNotification(BuildContext context) =>
|
||||
requestPermission(
|
||||
context,
|
||||
AppPermission.notification,
|
||||
);
|
||||
requestPermission(context, AppPermission.notification);
|
||||
|
||||
/// 快捷方法: 请求位置权限
|
||||
static Future<bool> requestLocation(BuildContext context) =>
|
||||
requestPermission(
|
||||
context,
|
||||
AppPermission.location,
|
||||
);
|
||||
requestPermission(context, AppPermission.location);
|
||||
|
||||
/// 快捷方法: 请求麦克风权限
|
||||
static Future<bool> requestMicrophone(BuildContext context) =>
|
||||
requestPermission(
|
||||
context,
|
||||
AppPermission.microphone,
|
||||
);
|
||||
requestPermission(context, AppPermission.microphone);
|
||||
|
||||
/// 打开系统设置
|
||||
static Future<bool> openSettings() => openAppSettings();
|
||||
@@ -584,7 +563,8 @@ class PermissionService {
|
||||
static Future<bool> requestTrackingPermission() async {
|
||||
if (!Platform.isIOS) return true;
|
||||
try {
|
||||
final status = await AppTrackingTransparency.requestTrackingAuthorization();
|
||||
final status =
|
||||
await AppTrackingTransparency.requestTrackingAuthorization();
|
||||
_log.i('ATT授权状态: $status');
|
||||
return status == TrackingStatus.authorized;
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// ============================================================
|
||||
// 闲言APP — NearbyService适配器
|
||||
// 创建时间: 2026-05-13
|
||||
// 更新时间: 2026-06-05
|
||||
// 更新时间: 2026-06-06
|
||||
// 作用: 封装nearby_service + nearby_connections三方库,适配项目传输体系
|
||||
// nearby_service: Android Wi-Fi Direct | iOS/macOS MultipeerConnectivity | 鸿蒙
|
||||
// nearby_connections: Google Nearby Connections(蓝牙发现+Wi-Fi Direct传输, 仅Android/iOS)
|
||||
// 上次更新: 集成nearby_connections实现P2P近场设备发现与文件传输
|
||||
// 上次更新: 跨平台兼容修复:鸿蒙端使用ohos属性替代android属性,P2P引擎鸿蒙端跳过
|
||||
// ============================================================
|
||||
|
||||
import 'dart:async';
|
||||
@@ -38,10 +38,13 @@ class NearbyP2pDeviceInfo {
|
||||
|
||||
/// 端点ID
|
||||
final String endpointId;
|
||||
|
||||
/// 端点名称
|
||||
final String endpointName;
|
||||
|
||||
/// 服务ID
|
||||
final String? serviceId;
|
||||
|
||||
/// 连接状态
|
||||
final NearbyP2pConnectionState state;
|
||||
|
||||
@@ -160,10 +163,10 @@ class NearbyServiceAdapter {
|
||||
bool get p2pIsDiscovering => _p2pIsDiscovering;
|
||||
List<NearbyP2pDeviceInfo> get p2pDiscoveredDevices =>
|
||||
_p2pDiscoveredDevices.values.toList();
|
||||
List<NearbyP2pDeviceInfo> get p2pConnectedDevices =>
|
||||
_p2pDiscoveredDevices.values
|
||||
.where((d) => d.state == NearbyP2pConnectionState.connected)
|
||||
.toList();
|
||||
List<NearbyP2pDeviceInfo> get p2pConnectedDevices => _p2pDiscoveredDevices
|
||||
.values
|
||||
.where((d) => d.state == NearbyP2pConnectionState.connected)
|
||||
.toList();
|
||||
|
||||
// ============================================================
|
||||
// 公共流
|
||||
@@ -578,9 +581,18 @@ class NearbyServiceAdapter {
|
||||
}
|
||||
|
||||
Future<bool> requestPermissions() async {
|
||||
if ((!Platform.isAndroid && !pu.isOhos) || _service == null) return true;
|
||||
if (!Platform.isAndroid && !pu.isOhos) return true;
|
||||
if (_service == null) return false;
|
||||
try {
|
||||
return await _service!.android!.requestPermissions();
|
||||
// Android使用android属性,鸿蒙使用ohos属性
|
||||
if (Platform.isAndroid) {
|
||||
return await _service!.android?.requestPermissions() ?? false;
|
||||
}
|
||||
if (pu.isOhos) {
|
||||
// 鸿蒙端权限通过permission_handler统一请求,nearby_service.ohos无独立权限方法
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
Log.e('NearbyService: Request permissions failed: $e');
|
||||
return false;
|
||||
@@ -588,9 +600,15 @@ class NearbyServiceAdapter {
|
||||
}
|
||||
|
||||
Future<bool> checkWifiService() async {
|
||||
if ((!Platform.isAndroid && !pu.isOhos) || _service == null) return true;
|
||||
if (!Platform.isAndroid && !pu.isOhos) return true;
|
||||
if (_service == null) return true;
|
||||
try {
|
||||
return await _service!.android!.checkWifiService();
|
||||
// 仅Android端支持Wi-Fi服务检查
|
||||
if (Platform.isAndroid) {
|
||||
return await _service!.android?.checkWifiService() ?? false;
|
||||
}
|
||||
// 鸿蒙/iOS/macOS端无需检查Wi-Fi服务
|
||||
return true;
|
||||
} catch (e) {
|
||||
Log.e('NearbyService: Check WiFi failed: $e');
|
||||
return false;
|
||||
@@ -729,12 +747,13 @@ class NearbyServiceAdapter {
|
||||
'xianyan_discoverer',
|
||||
Strategy.P2P_CLUSTER,
|
||||
serviceId: _p2pServiceId,
|
||||
onEndpointFound: (String endpointId, String endpointName, String serviceId) {
|
||||
Log.i(
|
||||
'NearbyP2p: 发现设备: $endpointName ($endpointId, service=$serviceId)',
|
||||
);
|
||||
_onP2pEndpointFound(endpointId, endpointName, serviceId);
|
||||
},
|
||||
onEndpointFound:
|
||||
(String endpointId, String endpointName, String serviceId) {
|
||||
Log.i(
|
||||
'NearbyP2p: 发现设备: $endpointName ($endpointId, service=$serviceId)',
|
||||
);
|
||||
_onP2pEndpointFound(endpointId, endpointName, serviceId);
|
||||
},
|
||||
onEndpointLost: (String? endpointId) {
|
||||
if (endpointId != null) {
|
||||
Log.i('NearbyP2p: 设备丢失: $endpointId');
|
||||
@@ -817,9 +836,10 @@ class NearbyServiceAdapter {
|
||||
onPayLoadRecieved: (String endpointId, Payload payload) {
|
||||
_onP2pPayloadReceived(endpointId, payload);
|
||||
},
|
||||
onPayloadTransferUpdate: (String endpointId, PayloadTransferUpdate payloadTransferUpdate) {
|
||||
_onP2pPayloadTransferUpdate(endpointId, payloadTransferUpdate);
|
||||
},
|
||||
onPayloadTransferUpdate:
|
||||
(String endpointId, PayloadTransferUpdate payloadTransferUpdate) {
|
||||
_onP2pPayloadTransferUpdate(endpointId, payloadTransferUpdate);
|
||||
},
|
||||
);
|
||||
Log.i('NearbyP2p: 接受连接: $endpointId');
|
||||
} catch (e) {
|
||||
@@ -883,10 +903,7 @@ class NearbyServiceAdapter {
|
||||
}
|
||||
|
||||
// 通过nearby_connections发送文件payload
|
||||
await Nearby().sendFilePayload(
|
||||
endpointId,
|
||||
filePath,
|
||||
);
|
||||
await Nearby().sendFilePayload(endpointId, filePath);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
@@ -900,10 +917,7 @@ class NearbyServiceAdapter {
|
||||
if (!isP2pSupported) return false;
|
||||
|
||||
try {
|
||||
await Nearby().sendBytesPayload(
|
||||
endpointId,
|
||||
data,
|
||||
);
|
||||
await Nearby().sendBytesPayload(endpointId, data);
|
||||
Log.i('NearbyP2p: 发送数据: ${data.length} bytes');
|
||||
return true;
|
||||
} catch (e) {
|
||||
@@ -1041,8 +1055,7 @@ class NearbyServiceAdapter {
|
||||
final filePath = payload.uri ?? payload.filePath;
|
||||
if (filePath != null) {
|
||||
final fileName = filePath.split('/').last;
|
||||
final mimeType =
|
||||
lookupMimeType(fileName) ?? 'application/octet-stream';
|
||||
final mimeType = lookupMimeType(fileName) ?? 'application/octet-stream';
|
||||
final isImage = mimeType.startsWith('image/');
|
||||
final isVideo = mimeType.startsWith('video/');
|
||||
|
||||
@@ -1168,18 +1181,21 @@ class NearbyServiceAdapter {
|
||||
/// 将P2P设备同步到nearby_service设备流(统一设备列表)
|
||||
void _notifyP2pDeviceAsTransferDevice() {
|
||||
final devices = _p2pDiscoveredDevices.values
|
||||
.map((d) => TransferDevice(
|
||||
id: d.endpointId,
|
||||
alias: d.endpointName,
|
||||
deviceType: DeviceType.mobile,
|
||||
port: 0,
|
||||
pairingMethod: PairingMethod.nearbyP2p,
|
||||
preferredTransport: TransportType.wifiDirect,
|
||||
lastSeen: DateTime.now(),
|
||||
isOnline: d.state == NearbyP2pConnectionState.connected ||
|
||||
d.state == NearbyP2pConnectionState.discovered,
|
||||
isVerified: d.state == NearbyP2pConnectionState.connected,
|
||||
))
|
||||
.map(
|
||||
(d) => TransferDevice(
|
||||
id: d.endpointId,
|
||||
alias: d.endpointName,
|
||||
deviceType: DeviceType.mobile,
|
||||
port: 0,
|
||||
pairingMethod: PairingMethod.nearbyP2p,
|
||||
preferredTransport: TransportType.wifiDirect,
|
||||
lastSeen: DateTime.now(),
|
||||
isOnline:
|
||||
d.state == NearbyP2pConnectionState.connected ||
|
||||
d.state == NearbyP2pConnectionState.discovered,
|
||||
isVerified: d.state == NearbyP2pConnectionState.connected,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
if (!_devicesController.isClosed && devices.isNotEmpty) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import '../../../../shared/widgets/containers/glass_container.dart';
|
||||
import '../../../../shared/widgets/adaptive/adaptive_back_button.dart';
|
||||
import '../../../../shared/widgets/feedback/external_link_dialog.dart';
|
||||
import '../../../../shared/widgets/feedback/app_toast.dart';
|
||||
import 'about_shared_widgets.dart';
|
||||
|
||||
class AboutPage extends ConsumerWidget {
|
||||
const AboutPage({super.key});
|
||||
@@ -464,29 +465,19 @@ class _DeveloperSection extends ConsumerWidget {
|
||||
subtitle: t.about.updateLogMenuDesc,
|
||||
ext: ext,
|
||||
onTap: () {
|
||||
// 拼接共享更新日志数据
|
||||
final logText = AppUpdateLog.entries
|
||||
.map((entry) {
|
||||
final items = entry.changes.map((c) => '• $c').join('\n');
|
||||
return '${entry.version} (${entry.date})\n$items';
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
showCupertinoDialog<void>(
|
||||
context: context,
|
||||
builder: (ctx) => CupertinoAlertDialog(
|
||||
title: Text(t.about.updateLog),
|
||||
content: Text(
|
||||
'v${AppVersion.version}\n'
|
||||
'• 修复数据管理/图片缓存页面路由\n'
|
||||
'• 修复返回主页面渲染异常\n'
|
||||
'• 修复发现/灵感页面RenderSliver报错\n'
|
||||
'• 修复工具中心溢出问题\n'
|
||||
'• 优化下拉面板即时打开\n'
|
||||
'• 增强句子列表交错动画\n'
|
||||
'• 修复壁纸按钮颜色重合\n'
|
||||
'• 修复倒计时+号无反应\n'
|
||||
'• 绑定邮箱增加验证码流程\n'
|
||||
'• 检测更新改为"无更新"\n'
|
||||
'• 修复软件权限页面跳转\n'
|
||||
'• 增加收集信息入口\n'
|
||||
'• 日志查看器增加副标题\n'
|
||||
'• 增加导出个人信息功能\n'
|
||||
'• 备案信息迁移至软件信息页\n'
|
||||
'• 统一按钮选中色动态主题',
|
||||
),
|
||||
content: Text(logText),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/// ============================================================
|
||||
/// 闲言APP — 关于页面共享组件
|
||||
/// 创建时间: 2026-05-29
|
||||
/// 更新时间: 2026-05-29
|
||||
/// 作用: 软件信息页与了解我们页共用的通用组件
|
||||
/// 上次更新: 从 app_info_page / learn_us_page 中提取共享组件
|
||||
/// 更新时间: 2026-06-05
|
||||
/// 作用: 软件信息页与了解我们页共用的通用组件及更新日志数据
|
||||
/// 上次更新: 新增 AppUpdateLog 共享更新日志数据,确保两处展示一致
|
||||
/// ============================================================
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -14,6 +14,61 @@ import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_typography.dart';
|
||||
import '../../../../core/theme/app_radius.dart';
|
||||
|
||||
// ============================================================
|
||||
// 更新日志数据 — 软件信息页 & 关于页共用
|
||||
// ============================================================
|
||||
|
||||
/// 单条更新日志
|
||||
class UpdateLogEntry {
|
||||
const UpdateLogEntry({
|
||||
required this.version,
|
||||
required this.date,
|
||||
required this.changes,
|
||||
});
|
||||
|
||||
/// 版本号
|
||||
final String version;
|
||||
|
||||
/// 发布日期
|
||||
final String date;
|
||||
|
||||
/// 更新内容列表(中文)
|
||||
final List<String> changes;
|
||||
}
|
||||
|
||||
/// 全局更新日志数据(中文)
|
||||
class AppUpdateLog {
|
||||
AppUpdateLog._();
|
||||
|
||||
static const List<UpdateLogEntry> entries = [
|
||||
UpdateLogEntry(
|
||||
version: 'v6.5.103',
|
||||
date: '2026-06-05',
|
||||
changes: [
|
||||
'🆕 新增桌面快捷方式(主题个性化、通用设置)',
|
||||
'🆕 引导页文件传输预览改为"移动设备/PC设备"',
|
||||
'🔧 修复鸿蒙 module.json5 shortcuts 配置校验报错',
|
||||
'🎨 液态玻璃风格适配优化',
|
||||
],
|
||||
),
|
||||
UpdateLogEntry(
|
||||
version: 'v6.5.1',
|
||||
date: '2026-05-29',
|
||||
changes: ['🔧 修复返回主页面渲染异常', '🎨 统一按钮选中色动态主题'],
|
||||
),
|
||||
UpdateLogEntry(
|
||||
version: 'v6.5.0',
|
||||
date: '2026-05-20',
|
||||
changes: [
|
||||
'🆕 增加收集信息入口',
|
||||
'🔧 增强句子列表交错动画',
|
||||
'🔧 修复软件权限页面跳转',
|
||||
'🔧 日志查看器增加副标题',
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
class AboutSectionTitle extends StatelessWidget {
|
||||
const AboutSectionTitle({
|
||||
super.key,
|
||||
|
||||
@@ -20,7 +20,18 @@ import '../../../../core/theme/app_typography.dart';
|
||||
import '../../../../core/theme/app_radius.dart';
|
||||
import '../../../../core/utils/platform/platform_utils.dart' as pu;
|
||||
import '../../../../core/constants/app_constants.dart';
|
||||
import '../../../../core/utils/platform/platform_utils.dart' show isOhos, isAndroid, isWindows, isIOS, isMacOS, isLinux, isWeb, isMobile, isDesktop, platformName;
|
||||
import '../../../../core/utils/platform/platform_utils.dart'
|
||||
show
|
||||
isOhos,
|
||||
isAndroid,
|
||||
isWindows,
|
||||
isIOS,
|
||||
isMacOS,
|
||||
isLinux,
|
||||
isWeb,
|
||||
isMobile,
|
||||
isDesktop,
|
||||
platformName;
|
||||
import '../../../../shared/widgets/containers/glass_container.dart';
|
||||
import '../../../../l10n/translations.dart';
|
||||
import 'about_shared_widgets.dart';
|
||||
@@ -606,15 +617,18 @@ class UpdateLogSection extends StatelessWidget {
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
child: UpdateItem(
|
||||
version: '${t.about.version} ${AppVersion.version}',
|
||||
date: '2026-05-29',
|
||||
changes: [
|
||||
t.about.updateLog1,
|
||||
t.about.updateLog2,
|
||||
t.about.updateLog3,
|
||||
],
|
||||
ext: ext,
|
||||
child: Column(
|
||||
children: AppUpdateLog.entries.map((entry) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: AppSpacing.sm),
|
||||
child: UpdateItem(
|
||||
version: entry.version,
|
||||
date: entry.date,
|
||||
changes: entry.changes,
|
||||
ext: ext,
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
@@ -650,9 +664,7 @@ class IcpSection extends StatelessWidget {
|
||||
icon: CupertinoIcons.doc_text,
|
||||
title: t.about.icpInfo,
|
||||
ext: ext,
|
||||
trailing: isChinese
|
||||
? null
|
||||
: _IcpInfoIcon(ext: ext, t: t),
|
||||
trailing: isChinese ? null : _IcpInfoIcon(ext: ext, t: t),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
@@ -808,11 +820,7 @@ class _IcpInfoIcon extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => _showIcpInfoHintDialog(context),
|
||||
child: Icon(
|
||||
CupertinoIcons.info_circle,
|
||||
size: 18,
|
||||
color: ext.textHint,
|
||||
),
|
||||
child: Icon(CupertinoIcons.info_circle, size: 18, color: ext.textHint),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:xianyan/core/router/app_nav_extension.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
import '../../../../../../core/services/accessibility/accessibility_service.dart';
|
||||
import '../../../../../../core/constants/app_constants.dart';
|
||||
import '../../../../../../core/router/app_routes.dart';
|
||||
import '../../../../../../core/services/device/app_lock_service.dart';
|
||||
@@ -138,12 +137,6 @@ class _GeneralSettingsPageState extends ConsumerState<GeneralSettingsPage>
|
||||
final t = ref.watch(translationsProvider);
|
||||
final splitState = ref.watch(splitViewProvider);
|
||||
|
||||
// 获取系统无障碍状态
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
final systemHighContrast = mediaQuery.highContrast;
|
||||
final systemReduceAnimations = mediaQuery.disableAnimations;
|
||||
final systemBoldText = mediaQuery.boldText;
|
||||
|
||||
final allSections = buildGeneralSettingSections(
|
||||
settings: settings,
|
||||
notificationEnabled: notificationEnabled,
|
||||
@@ -154,9 +147,6 @@ class _GeneralSettingsPageState extends ConsumerState<GeneralSettingsPage>
|
||||
navBarPositionIndex: splitState.navBarPosition.index,
|
||||
splitRatio: splitState.splitRatio,
|
||||
splitViewEnabled: splitState.splitViewEnabled,
|
||||
systemHighContrast: systemHighContrast,
|
||||
systemReduceAnimations: systemReduceAnimations,
|
||||
systemBoldText: systemBoldText,
|
||||
);
|
||||
return filterSettingSections(
|
||||
allSections,
|
||||
@@ -944,10 +934,6 @@ class _GeneralSettingsPageState extends ConsumerState<GeneralSettingsPage>
|
||||
notifier.setNearbyDiscovery(value);
|
||||
case 'split_view_enabled':
|
||||
ref.read(splitViewProvider.notifier).setSplitViewEnabled(value);
|
||||
case 'semantics_debug':
|
||||
notifier.setSemanticsDebugEnabled(value);
|
||||
// 同步到AccessibilityService
|
||||
AccessibilityService.instance.setSemanticsDebug(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,6 @@ List<SettingSection> buildGeneralSettingSections({
|
||||
required int navBarPositionIndex,
|
||||
required double splitRatio,
|
||||
required bool splitViewEnabled,
|
||||
bool systemHighContrast = false,
|
||||
bool systemReduceAnimations = false,
|
||||
bool systemBoldText = false,
|
||||
}) {
|
||||
return [
|
||||
// ── 交互设置 ──
|
||||
@@ -97,15 +94,15 @@ List<SettingSection> buildGeneralSettingSections({
|
||||
),
|
||||
if (settings.pageTransitionModeId == 'navigate')
|
||||
SettingItem(
|
||||
id: 'predictive_back',
|
||||
icon: CupertinoIcons.arrow_turn_down_left,
|
||||
iconColor: AppColors.iosLightBlue,
|
||||
title: t.predictiveBack,
|
||||
subtitle: t.predictiveBackSubtitle,
|
||||
type: SettingType.toggle,
|
||||
value: settings.predictiveBackEnabled,
|
||||
isLocked: true,
|
||||
),
|
||||
id: 'predictive_back',
|
||||
icon: CupertinoIcons.arrow_turn_down_left,
|
||||
iconColor: AppColors.iosLightBlue,
|
||||
title: t.predictiveBack,
|
||||
subtitle: t.predictiveBackSubtitle,
|
||||
type: SettingType.toggle,
|
||||
value: settings.predictiveBackEnabled,
|
||||
isLocked: true,
|
||||
),
|
||||
SettingItem(
|
||||
id: 'long_press_preview',
|
||||
icon: CupertinoIcons.hand_point_right_fill,
|
||||
@@ -317,51 +314,6 @@ List<SettingSection> buildGeneralSettingSections({
|
||||
],
|
||||
),
|
||||
|
||||
// ── 无障碍设置 ──
|
||||
SettingSection(
|
||||
title: '♿ 无障碍',
|
||||
icon: CupertinoIcons.person_circle_fill,
|
||||
color: AppColors.iosBlue,
|
||||
items: [
|
||||
SettingItem(
|
||||
id: 'semantics_debug',
|
||||
icon: CupertinoIcons.eye_fill,
|
||||
iconColor: AppColors.iosPurple,
|
||||
title: '语义调试',
|
||||
subtitle: '显示语义标注覆盖层,辅助开发无障碍适配',
|
||||
type: SettingType.toggle,
|
||||
value: settings.semanticsDebugEnabled,
|
||||
),
|
||||
SettingItem(
|
||||
id: 'system_high_contrast',
|
||||
icon: CupertinoIcons.circle_lefthalf_fill,
|
||||
iconColor: AppColors.iosOrange,
|
||||
title: '高对比度',
|
||||
subtitle: '跟随系统设置',
|
||||
type: SettingType.selection,
|
||||
displayValue: systemHighContrast ? '已开启' : '未开启',
|
||||
),
|
||||
SettingItem(
|
||||
id: 'system_reduce_animations',
|
||||
icon: CupertinoIcons.wand_stars_inverse,
|
||||
iconColor: AppColors.iosGray,
|
||||
title: '减少动画',
|
||||
subtitle: '跟随系统设置',
|
||||
type: SettingType.selection,
|
||||
displayValue: systemReduceAnimations ? '已开启' : '未开启',
|
||||
),
|
||||
SettingItem(
|
||||
id: 'system_bold_text',
|
||||
icon: CupertinoIcons.bold,
|
||||
iconColor: AppColors.iosGreen,
|
||||
title: '粗体文本',
|
||||
subtitle: '跟随系统设置',
|
||||
type: SettingType.selection,
|
||||
displayValue: systemBoldText ? '已开启' : '未开启',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// ── 性能设置 ──
|
||||
SettingSection(
|
||||
title: t.performance,
|
||||
|
||||
@@ -18,6 +18,7 @@ import '../../../../core/router/app_nav_extension.dart';
|
||||
import '../../../../core/services/data/data_export_service.dart';
|
||||
import '../../../../core/services/data/settings_export_service.dart';
|
||||
import '../../../../core/services/device/haptic_service.dart';
|
||||
import '../../../../core/services/accessibility/accessibility_service.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_typography.dart';
|
||||
@@ -217,6 +218,20 @@ class _OtherSettingsPageState extends ConsumerState<OtherSettingsPage> {
|
||||
ref.read(generalSettingsProvider.notifier).setBoldTextEnabled(v);
|
||||
},
|
||||
),
|
||||
SettingsSwitchTile(
|
||||
icon: CupertinoIcons.eye_fill,
|
||||
iconColor: const Color(0xFFAF52DE),
|
||||
title: '语义调试',
|
||||
subtitle: '显示语义标注覆盖层,辅助开发无障碍适配',
|
||||
value: settings.semanticsDebugEnabled,
|
||||
onChanged: (v) {
|
||||
HapticService.toggleSwitch();
|
||||
ref
|
||||
.read(generalSettingsProvider.notifier)
|
||||
.setSemanticsDebugEnabled(v);
|
||||
AccessibilityService.instance.setSemanticsDebug(v);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -444,7 +459,11 @@ class _OtherSettingsPageState extends ConsumerState<OtherSettingsPage> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(CupertinoIcons.square_arrow_up, size: 18, color: CupertinoColors.white),
|
||||
const Icon(
|
||||
CupertinoIcons.square_arrow_up,
|
||||
size: 18,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'导出设置',
|
||||
@@ -475,11 +494,17 @@ class _OtherSettingsPageState extends ConsumerState<OtherSettingsPage> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(CupertinoIcons.square_arrow_down, size: 18, color: ext.textPrimary),
|
||||
Icon(
|
||||
CupertinoIcons.square_arrow_down,
|
||||
size: 18,
|
||||
color: ext.textPrimary,
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'从文件导入',
|
||||
style: AppTypography.body.copyWith(color: ext.textPrimary),
|
||||
style: AppTypography.body.copyWith(
|
||||
color: ext.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -498,11 +523,17 @@ class _OtherSettingsPageState extends ConsumerState<OtherSettingsPage> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(CupertinoIcons.doc_on_clipboard, size: 18, color: ext.textPrimary),
|
||||
Icon(
|
||||
CupertinoIcons.doc_on_clipboard,
|
||||
size: 18,
|
||||
color: ext.textPrimary,
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'从剪贴板导入',
|
||||
style: AppTypography.body.copyWith(color: ext.textPrimary),
|
||||
style: AppTypography.body.copyWith(
|
||||
color: ext.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -537,9 +568,7 @@ class _OtherSettingsPageState extends ConsumerState<OtherSettingsPage> {
|
||||
allowedExtensions: ['json'],
|
||||
);
|
||||
} catch (_) {
|
||||
result = await FilePicker.pickFiles(
|
||||
|
||||
);
|
||||
result = await FilePicker.pickFiles();
|
||||
}
|
||||
|
||||
if (result == null || result.files.isEmpty) return;
|
||||
@@ -648,7 +677,9 @@ class _OtherSettingsPageState extends ConsumerState<OtherSettingsPage> {
|
||||
child: const Text('导入'),
|
||||
onPressed: () async {
|
||||
Navigator.pop(ctx);
|
||||
final success = await SettingsExportService.importFromJson(jsonStr);
|
||||
final success = await SettingsExportService.importFromJson(
|
||||
jsonStr,
|
||||
);
|
||||
if (mounted) {
|
||||
_showMessage(success ? '✅ 导入成功,设置已更新' : '❌ 导入失败,请检查文件格式');
|
||||
if (success) {
|
||||
|
||||
@@ -518,7 +518,7 @@ class _WelcomePageState extends ConsumerState<WelcomePage> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_buildDeviceIcon(ext, '📱', 'iPhone'),
|
||||
_buildDeviceIcon(ext, '📱', ob.mobileDevice),
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
@@ -543,7 +543,7 @@ class _WelcomePageState extends ConsumerState<WelcomePage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
_buildDeviceIcon(ext, '💻', 'MacBook'),
|
||||
_buildDeviceIcon(ext, '💻', ob.pcDevice),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
|
||||
@@ -1339,6 +1339,8 @@ const ar = T(
|
||||
templateGlass: 'زجاجي',
|
||||
transferring: 'جارٍ النقل 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'جهاز محمول',
|
||||
pcDevice: 'جهاز كمبيوتر',
|
||||
rssLabel: 'خلاصات RSS',
|
||||
addRssSource: 'إضافة خلاصة',
|
||||
welcomeNavLabel: 'ترحيب',
|
||||
|
||||
@@ -1346,6 +1346,8 @@ const bn = T(
|
||||
templateGlass: 'ফ্রস্টেড',
|
||||
transferring: 'স্থানান্তরিত হচ্ছে 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'মোবাইল ডিভাইস',
|
||||
pcDevice: 'PC ডিভাইস',
|
||||
rssLabel: 'RSS ফিড',
|
||||
addRssSource: 'ফিড যোগ করুন',
|
||||
welcomeNavLabel: 'স্বাগতম',
|
||||
|
||||
@@ -1362,6 +1362,8 @@ const de = T(
|
||||
templateGlass: 'Milchglas',
|
||||
transferring: 'Übertragung 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Mobilgerät',
|
||||
pcDevice: 'PC-Gerät',
|
||||
rssLabel: 'RSS-Feeds',
|
||||
addRssSource: 'Feed hinzufügen',
|
||||
welcomeNavLabel: 'Willkommen',
|
||||
|
||||
@@ -1356,6 +1356,8 @@ const en = T(
|
||||
templateGlass: 'Frosted',
|
||||
transferring: 'Transferring 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Mobile Device',
|
||||
pcDevice: 'PC Device',
|
||||
rssLabel: 'RSS Feeds',
|
||||
addRssSource: 'Add Feed',
|
||||
welcomeNavLabel: 'Welcome',
|
||||
|
||||
@@ -1374,6 +1374,8 @@ const es = T(
|
||||
templateGlass: 'Esmerilado',
|
||||
transferring: 'Transfiriendo 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Dispositivo móvil',
|
||||
pcDevice: 'Dispositivo PC',
|
||||
rssLabel: 'Fuentes RSS',
|
||||
addRssSource: 'Añadir fuente',
|
||||
welcomeNavLabel: 'Bienvenida',
|
||||
|
||||
@@ -1381,6 +1381,8 @@ const fr = T(
|
||||
templateGlass: 'Givré',
|
||||
transferring: 'Transfert 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Appareil mobile',
|
||||
pcDevice: 'Appareil PC',
|
||||
rssLabel: 'Flux RSS',
|
||||
addRssSource: 'Ajouter un flux',
|
||||
welcomeNavLabel: 'Bienvenue',
|
||||
|
||||
@@ -1341,6 +1341,8 @@ const hi = T(
|
||||
templateGlass: 'फ्रॉस्टेड',
|
||||
transferring: 'स्थानांतरित हो रहा है 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'मोबाइल डिवाइस',
|
||||
pcDevice: 'PC डिवाइस',
|
||||
rssLabel: 'RSS फ़ीड',
|
||||
addRssSource: 'फ़ीड जोड़ें',
|
||||
welcomeNavLabel: 'स्वागत',
|
||||
|
||||
@@ -1371,6 +1371,8 @@ const it = T(
|
||||
templateGlass: 'Satinato',
|
||||
transferring: 'Trasferimento 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Dispositivo mobile',
|
||||
pcDevice: 'Dispositivo PC',
|
||||
rssLabel: 'Feed RSS',
|
||||
addRssSource: 'Aggiungi feed',
|
||||
welcomeNavLabel: 'Benvenuto',
|
||||
|
||||
@@ -1301,6 +1301,8 @@ const ja = T(
|
||||
templateGlass: 'すりガラス',
|
||||
transferring: '転送中 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'モバイルデバイス',
|
||||
pcDevice: 'PCデバイス',
|
||||
rssLabel: 'RSSフィード',
|
||||
addRssSource: 'フィードを追加',
|
||||
welcomeNavLabel: 'ようこそ',
|
||||
|
||||
@@ -1302,6 +1302,8 @@ const ko = T(
|
||||
templateGlass: '서리유리',
|
||||
transferring: '전송 중 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: '모바일 기기',
|
||||
pcDevice: 'PC 기기',
|
||||
rssLabel: 'RSS 피드',
|
||||
addRssSource: '피드 추가',
|
||||
welcomeNavLabel: '환영',
|
||||
|
||||
@@ -1365,6 +1365,8 @@ const pt = T(
|
||||
templateGlass: 'Fosco',
|
||||
transferring: 'Transferindo 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Dispositivo móvel',
|
||||
pcDevice: 'Dispositivo PC',
|
||||
rssLabel: 'Feeds RSS',
|
||||
addRssSource: 'Adicionar feed',
|
||||
welcomeNavLabel: 'Bem-vindo',
|
||||
|
||||
@@ -1363,6 +1363,8 @@ const ru = T(
|
||||
templateGlass: 'Матовое стекло',
|
||||
transferring: 'Передача 70%',
|
||||
wifiDirect: 'WiFi Direct',
|
||||
mobileDevice: 'Мобильное устройство',
|
||||
pcDevice: 'ПК-устройство',
|
||||
rssLabel: 'RSS-каналы',
|
||||
addRssSource: 'Добавить канал',
|
||||
welcomeNavLabel: 'Приветствие',
|
||||
|
||||
@@ -1289,6 +1289,8 @@ const zhCN = T(
|
||||
templateGlass: '毛玻璃',
|
||||
transferring: '传输中 70%',
|
||||
wifiDirect: 'WiFi直连',
|
||||
mobileDevice: '移动设备',
|
||||
pcDevice: 'PC设备',
|
||||
rssLabel: 'RSS 订阅源',
|
||||
addRssSource: '添加订阅源',
|
||||
welcomeNavLabel: '欢迎与指引',
|
||||
|
||||
@@ -1288,6 +1288,8 @@ const zhTW = T(
|
||||
templateGlass: '毛玻璃',
|
||||
transferring: '傳輸中 70%',
|
||||
wifiDirect: 'WiFi直連',
|
||||
mobileDevice: '行動裝置',
|
||||
pcDevice: 'PC裝置',
|
||||
rssLabel: 'RSS 訂閱源',
|
||||
addRssSource: '添加訂閱源',
|
||||
welcomeNavLabel: '歡迎與指引',
|
||||
|
||||
@@ -36,6 +36,8 @@ class TOnboarding {
|
||||
required this.templateGlass,
|
||||
required this.transferring,
|
||||
required this.wifiDirect,
|
||||
required this.mobileDevice,
|
||||
required this.pcDevice,
|
||||
required this.rssLabel,
|
||||
required this.addRssSource,
|
||||
required this.welcomeNavLabel,
|
||||
@@ -158,6 +160,12 @@ class TOnboarding {
|
||||
/// WiFi直连
|
||||
final String wifiDirect;
|
||||
|
||||
/// 移动设备
|
||||
final String mobileDevice;
|
||||
|
||||
/// PC设备
|
||||
final String pcDevice;
|
||||
|
||||
/// RSS 订阅源
|
||||
final String rssLabel;
|
||||
|
||||
@@ -293,6 +301,8 @@ class TOnboarding {
|
||||
'templateGlass': templateGlass,
|
||||
'transferring': transferring,
|
||||
'wifiDirect': wifiDirect,
|
||||
'mobileDevice': mobileDevice,
|
||||
'pcDevice': pcDevice,
|
||||
'rssLabel': rssLabel,
|
||||
'addRssSource': addRssSource,
|
||||
'welcomeNavLabel': welcomeNavLabel,
|
||||
@@ -329,8 +339,10 @@ class TOnboarding {
|
||||
'completeSetup': completeSetup,
|
||||
};
|
||||
|
||||
static TOnboarding fromMap(Map<String, String> map, {TOnboarding? fallback}) =>
|
||||
TOnboarding(
|
||||
static TOnboarding fromMap(
|
||||
Map<String, String> map, {
|
||||
TOnboarding? fallback,
|
||||
}) => TOnboarding(
|
||||
welcomeTitle: map['welcomeTitle']?.isNotEmpty == true
|
||||
? map['welcomeTitle']!
|
||||
: (fallback?.welcomeTitle ?? ''),
|
||||
@@ -361,8 +373,8 @@ class TOnboarding {
|
||||
featureFileTransferDesc: map['featureFileTransferDesc']?.isNotEmpty == true
|
||||
? map['featureFileTransferDesc']!
|
||||
: (fallback?.featureFileTransferDesc ?? ''),
|
||||
featureFileTransferDetail: map['featureFileTransferDetail']?.isNotEmpty ==
|
||||
true
|
||||
featureFileTransferDetail:
|
||||
map['featureFileTransferDetail']?.isNotEmpty == true
|
||||
? map['featureFileTransferDetail']!
|
||||
: (fallback?.featureFileTransferDetail ?? ''),
|
||||
featureChatFlow: map['featureChatFlow']?.isNotEmpty == true
|
||||
@@ -416,6 +428,12 @@ class TOnboarding {
|
||||
wifiDirect: map['wifiDirect']?.isNotEmpty == true
|
||||
? map['wifiDirect']!
|
||||
: (fallback?.wifiDirect ?? ''),
|
||||
mobileDevice: map['mobileDevice']?.isNotEmpty == true
|
||||
? map['mobileDevice']!
|
||||
: (fallback?.mobileDevice ?? ''),
|
||||
pcDevice: map['pcDevice']?.isNotEmpty == true
|
||||
? map['pcDevice']!
|
||||
: (fallback?.pcDevice ?? ''),
|
||||
rssLabel: map['rssLabel']?.isNotEmpty == true
|
||||
? map['rssLabel']!
|
||||
: (fallback?.rssLabel ?? ''),
|
||||
|
||||
@@ -14,10 +14,11 @@ import device_info_plus
|
||||
import file_picker
|
||||
import file_selector_macos
|
||||
import flutter_app_group_directory
|
||||
import flutter_blue_plus_darwin
|
||||
import flutter_image_compress_macos
|
||||
import flutter_inappwebview_macos
|
||||
import flutter_local_notifications
|
||||
import flutter_secure_storage_darwin
|
||||
import flutter_secure_storage_macos
|
||||
import flutter_tts
|
||||
import flutter_webrtc
|
||||
import gal
|
||||
@@ -52,10 +53,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FlutterAppGroupDirectoryPlugin.register(with: registry.registrar(forPlugin: "FlutterAppGroupDirectoryPlugin"))
|
||||
FlutterBluePlusPlugin.register(with: registry.registrar(forPlugin: "FlutterBluePlusPlugin"))
|
||||
FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin"))
|
||||
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin"))
|
||||
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
||||
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
"startWindowIcon": "$media:icon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"exported": true,
|
||||
"metadata": [
|
||||
{
|
||||
"name": "ohos.shortcut.config",
|
||||
"resource": "$profile:shortcuts"
|
||||
}
|
||||
],
|
||||
"skills": [
|
||||
{
|
||||
"entities": [
|
||||
|
||||
32
ohos/entry/src/main/resources/base/profile/shortcuts.json
Normal file
32
ohos/entry/src/main/resources/base/profile/shortcuts.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"shortcuts": [
|
||||
{
|
||||
"shortcutId": "action_theme",
|
||||
"label": "$string:shortcut_theme_label",
|
||||
"icon": "$media:icon",
|
||||
"wants": [
|
||||
{
|
||||
"bundleName": "apps.xy.xianyan",
|
||||
"abilityName": "EntryAbility",
|
||||
"parameters": {
|
||||
"shortcutType": "action_theme"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"shortcutId": "action_general_settings",
|
||||
"label": "$string:shortcut_general_settings_label",
|
||||
"icon": "$media:icon",
|
||||
"wants": [
|
||||
{
|
||||
"bundleName": "apps.xy.xianyan",
|
||||
"abilityName": "EntryAbility",
|
||||
"parameters": {
|
||||
"shortcutType": "action_general_settings"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -31,6 +31,14 @@
|
||||
{
|
||||
"name": "permission_vibrate_reason",
|
||||
"value": "Used for haptic feedback during interactions"
|
||||
},
|
||||
{
|
||||
"name": "shortcut_theme_label",
|
||||
"value": "Theme"
|
||||
},
|
||||
{
|
||||
"name": "shortcut_general_settings_label",
|
||||
"value": "Settings"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -85,6 +85,7 @@ dependencies:
|
||||
# --- 权限 ---
|
||||
permission_handler: # v12.0.1 | 运行时权限请求(本地化-鸿蒙适配)
|
||||
path: packages/permission_handler
|
||||
app_tracking_transparency: ^2.0.6 # iOS App Tracking Transparency授权(鸿蒙端不调用,仅保证编译通过)
|
||||
|
||||
# --- 本地通知 ---
|
||||
flutter_local_notifications: # v21.0.0 | 本地推送通知(本地化-鸿蒙适配)
|
||||
@@ -281,7 +282,8 @@ dependencies:
|
||||
path: packages/wifi_iot
|
||||
nearby_service: # v0.2.1 | 近场设备发现+通信(本地化-鸿蒙适配)
|
||||
path: packages/nearby_service
|
||||
nearby_connections: ^4.1.1 # Google Nearby Connections(蓝牙发现+Wi-Fi Direct传输,仅Android/iOS)
|
||||
nearby_connections: # v4.1.1 | Google Nearby Connections(本地化-鸿蒙适配,仅Android/iOS)
|
||||
path: packages/nearby_connections
|
||||
|
||||
flutter_localizations:
|
||||
sdk: flutter # Flutter国际化支持
|
||||
@@ -413,6 +415,10 @@ dependency_overrides:
|
||||
path: packages/workmanager_ohos
|
||||
home_widget:
|
||||
path: packages/home_widget
|
||||
nearby_service:
|
||||
path: packages/nearby_service
|
||||
nearby_connections:
|
||||
path: packages/nearby_connections
|
||||
|
||||
# ============================================================
|
||||
# Flutter 配置
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <desktop_drop/desktop_drop_plugin.h>
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <flutter_blue_plus_winrt/flutter_blue_plus_plugin.h>
|
||||
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
|
||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||
#include <flutter_tts/flutter_tts_plugin.h>
|
||||
@@ -41,6 +42,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("DesktopDropPlugin"));
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
FlutterBluePlusPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterBluePlusPlugin"));
|
||||
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
|
||||
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
|
||||
|
||||
@@ -9,6 +9,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
connectivity_plus
|
||||
desktop_drop
|
||||
file_selector_windows
|
||||
flutter_blue_plus_winrt
|
||||
flutter_inappwebview_windows
|
||||
flutter_secure_storage_windows
|
||||
flutter_tts
|
||||
|
||||
Reference in New Issue
Block a user