diff --git a/lib/pages/battery_health_page.dart b/lib/pages/battery_health_page.dart index e1b0628..e63d7e5 100644 --- a/lib/pages/battery_health_page.dart +++ b/lib/pages/battery_health_page.dart @@ -8,7 +8,6 @@ import 'package:sqflite/sqflite.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as path; import 'package:device_info_plus/device_info_plus.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import '../models/device_matching.dart'; import '../utils/charge_utils.dart'; @@ -251,10 +250,6 @@ class _BatteryHealthPageState extends State // ---------- SAF 授权引导 ---------- void _showSafAuthorizationDialog() { -<<<<<<< HEAD -======= - // 避免重复弹窗 ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd if (!mounted) return; showDialog( @@ -280,10 +275,6 @@ class _BatteryHealthPageState extends State TextButton( onPressed: () { Navigator.pop(context); -<<<<<<< HEAD -======= - // 用户取消后,保持当前状态,但不阻塞后续操作 ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd setState(() { _safState = SafPermissionState.denied; }); @@ -292,19 +283,11 @@ class _BatteryHealthPageState extends State ), ElevatedButton( onPressed: () async { -<<<<<<< HEAD final ctx = context; Navigator.pop(ctx); final result = await _safService.requestPermission(); if (result.success) { if (!mounted) return; -======= - final ctx = context; // 保存引用 - Navigator.pop(ctx); - final result = await _safService.requestPermission(); - if (result.success) { - if (!mounted) return; // 先检查 State 是否还在 ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd setState(() { _safState = SafPermissionState.authorized; }); @@ -317,17 +300,10 @@ class _BatteryHealthPageState extends State backgroundColor: Colors.red, ), ); -<<<<<<< HEAD _showSafAuthorizationDialog(); } }, child: const Text('选择文件夹'), // 🟢 加这行 -======= - // 重新弹窗 - _showSafAuthorizationDialog(); - } - }, ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd ), ], ), diff --git a/lib/services/saf_storage_service.dart b/lib/services/saf_storage_service.dart index 0d763ac..4044751 100644 --- a/lib/services/saf_storage_service.dart +++ b/lib/services/saf_storage_service.dart @@ -1,24 +1,15 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; -<<<<<<< HEAD import 'package:file_picker/file_picker.dart'; import '../models/saf_permission_state.dart'; /// 使用 file_picker 实现文件夹访问 -======= -import 'package:flutter_saf/flutter_saf.dart'; -import '../models/saf_permission_state.dart'; - -/// SAF 存储服务 -/// 负责管理通过 SAF 授权的文件夹访问 ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd class SafStorageService { static final SafStorageService _instance = SafStorageService._internal(); factory SafStorageService() => _instance; SafStorageService._internal(); -<<<<<<< HEAD static const String _prefKeySafPath = 'saf_storage_path'; String? _cachedPath; @@ -37,34 +28,6 @@ class SafStorageService { try { final dir = Directory(_cachedPath!); if (!await dir.exists()) { -======= - static const String _prefKeySafUri = 'saf_storage_uri'; - static const String _prefKeySafPermission = 'saf_permission_uri'; - - /// 存储的授权 URI - String? _cachedUriString; - - /// 初始化,从 SharedPreferences 恢复授权状态 - Future init() async { - final prefs = await SharedPreferences.getInstance(); - _cachedUriString = prefs.getString(_prefKeySafUri); - if (kDebugMode) { - print('[SAF] 初始化,缓存 URI: $_cachedUriString'); - } - } - - /// 获取当前授权状态 - Future getPermissionState() async { - if (_cachedUriString == null || _cachedUriString!.isEmpty) { - return SafPermissionState.unauthorized; - } - - try { - final uri = Uri.parse(_cachedUriString!); - // 检查 Uri 是否仍然有效 - final isValid = await FlutterSaf.isDirectory(uri); - if (!isValid) { ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd _clearCache(); return SafPermissionState.expired; } @@ -75,7 +38,6 @@ class SafStorageService { } } -<<<<<<< HEAD Future requestPermission() async { try { // 使用 file_picker 选择文件夹 @@ -98,40 +60,6 @@ class SafStorageService { } return SafAuthorizationResult.success(selectedPath); -======= - /// 请求 SAF 授权(引导用户选择文件夹) - /// 返回授权结果 - Future requestPermission() async { - try { - // 调用系统文件夹选择器 - // 引导用户选择 /storage/emulated/0/mbattery_charger/ - // 或者用户可以选择任何目录,但我们建议选择具体路径 - final uri = await FlutterSaf.openDocumentTree(); - - if (uri == null) { - return SafAuthorizationResult.denied(); - } - - // 获取持久化 URI 权限 - await FlutterSaf.takePersistableUriPermission(uri); - - // 验证是否为目录 - final isValid = await FlutterSaf.isDirectory(uri); - if (!isValid) { - return SafAuthorizationResult.error('选择的路径不是有效目录'); - } - - // 保存 URI - final uriString = uri.toString(); - _cachedUriString = uriString; - await _saveUri(uriString); - - if (kDebugMode) { - print('[SAF] 授权成功,URI: $uriString'); - } - - return SafAuthorizationResult.success(uriString); ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd } catch (e) { if (kDebugMode) { print('[SAF] 授权失败: $e'); @@ -140,32 +68,17 @@ class SafStorageService { } } -<<<<<<< HEAD Future logFileExists(String fileName) async { final state = await getPermissionState(); if (state != SafPermissionState.authorized) return false; try { final file = File('${_cachedPath!}/$fileName'); return await file.exists(); -======= - /// 检查指定日期的日志文件是否存在 - Future logFileExists(String fileName) async { - final state = await getPermissionState(); - if (state != SafPermissionState.authorized) { - return false; - } - - try { - final uri = Uri.parse(_cachedUriString!); - final fileUri = await FlutterSaf.getFile(uri, fileName); - return fileUri != null && await FlutterSaf.isFile(fileUri); ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd } catch (e) { return false; } } -<<<<<<< HEAD Future> readLogFile(String fileName) async { final state = await getPermissionState(); if (state != SafPermissionState.authorized) return []; @@ -173,25 +86,6 @@ class SafStorageService { final file = File('${_cachedPath!}/$fileName'); if (!await file.exists()) return []; return await file.readAsLines(); -======= - /// 读取日志文件内容 - /// 返回文件行列表,如果文件不存在或读取失败返回空列表 - Future> readLogFile(String fileName) async { - final state = await getPermissionState(); - if (state != SafPermissionState.authorized) { - return []; - } - - try { - final uri = Uri.parse(_cachedUriString!); - final fileUri = await FlutterSaf.getFile(uri, fileName); - if (fileUri == null || !await FlutterSaf.isFile(fileUri)) { - return []; - } - - final content = await FlutterSaf.readTextFile(fileUri); - return content.split('\n'); ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd } catch (e) { if (kDebugMode) { print('[SAF] 读取文件失败: $e'); @@ -200,7 +94,6 @@ class SafStorageService { } } -<<<<<<< HEAD Future> listFiles() async { final state = await getPermissionState(); if (state != SafPermissionState.authorized) return []; @@ -209,41 +102,22 @@ class SafStorageService { if (!await dir.exists()) return []; final entities = await dir.list().toList(); return entities - .where((e) => e is File) + .whereType() .map((e) => e.path.split(Platform.pathSeparator).last) .toList(); } catch (e) { if (kDebugMode) { print('[SAF] 列出文件失败: $e'); } -======= - /// 获取文件夹中的文件列表 - Future> listFiles() async { - final state = await getPermissionState(); - if (state != SafPermissionState.authorized) { - return []; - } - - try { - final uri = Uri.parse(_cachedUriString!); - final files = await FlutterSaf.listFiles(uri); - return files.where((f) => f.isFile).map((f) => f.name).toList(); - } catch (e) { ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd return []; } } -<<<<<<< HEAD -======= - /// 检查授权是否有效,如果失效则清除缓存 ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd Future validatePermission() async { final state = await getPermissionState(); return state == SafPermissionState.authorized; } -<<<<<<< HEAD void _clearCache() { _cachedPath = null; _savePath(null); @@ -259,24 +133,4 @@ class SafStorageService { } String? get cachedPath => _cachedPath; -======= - /// 清除授权缓存 - void _clearCache() { - _cachedUriString = null; - _saveUri(null); - } - - /// 保存 URI 到 SharedPreferences - Future _saveUri(String? uriString) async { - final prefs = await SharedPreferences.getInstance(); - if (uriString != null && uriString.isNotEmpty) { - await prefs.setString(_prefKeySafUri, uriString); - } else { - await prefs.remove(_prefKeySafUri); - } - } - - /// 获取缓存的 URI(用于调试) - String? get cachedUri => _cachedUriString; ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 649d2d5..852819c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,19 +6,11 @@ import FlutterMacOS import Foundation import device_info_plus -<<<<<<< HEAD -======= -import path_provider_foundation ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd import shared_preferences_foundation import sqflite_darwin func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) -<<<<<<< HEAD -======= - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 247e167..a51ba58 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -416,7 +416,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.8" -<<<<<<< HEAD pub_semver: dependency: transitive description: @@ -433,45 +432,28 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.6.0" -======= ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd shared_preferences: dependency: "direct main" description: name: shared_preferences sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf -<<<<<<< HEAD url: "https://pub.flutter-io.cn" -======= - url: "https://pub.dev" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd source: hosted version: "2.5.5" shared_preferences_android: dependency: transitive description: name: shared_preferences_android -<<<<<<< HEAD sha256: "93ae5884a9df5d3bb696825bceb3a17590754548b5d740eba51500afc8d088f5" url: "https://pub.flutter-io.cn" source: hosted version: "2.4.26" -======= - sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 - url: "https://pub.dev" - source: hosted - version: "2.4.23" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" -<<<<<<< HEAD url: "https://pub.flutter-io.cn" -======= - url: "https://pub.dev" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd source: hosted version: "2.5.6" shared_preferences_linux: @@ -479,11 +461,7 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" -<<<<<<< HEAD url: "https://pub.flutter-io.cn" -======= - url: "https://pub.dev" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd source: hosted version: "2.4.1" shared_preferences_platform_interface: @@ -491,11 +469,7 @@ packages: description: name: shared_preferences_platform_interface sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" -<<<<<<< HEAD url: "https://pub.flutter-io.cn" -======= - url: "https://pub.dev" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd source: hosted version: "2.4.2" shared_preferences_web: @@ -503,11 +477,7 @@ packages: description: name: shared_preferences_web sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 -<<<<<<< HEAD url: "https://pub.flutter-io.cn" -======= - url: "https://pub.dev" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd source: hosted version: "2.4.3" shared_preferences_windows: @@ -515,11 +485,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" -<<<<<<< HEAD url: "https://pub.flutter-io.cn" -======= - url: "https://pub.dev" ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd source: hosted version: "2.4.1" sky_engine: diff --git a/pubspec.yaml b/pubspec.yaml index c8ac953..5aec786 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,12 +38,8 @@ dependencies: path: ^1.9.0 flutter_svg: ^2.0.10+1 shared_preferences: ^2.2.0 -<<<<<<< HEAD file_picker: ^6.0.0 -======= - flutter_saf: ^0.1.0 ->>>>>>> c5a85e05a3bb50cd4ea7de0da2db94c867eb7ddd # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.