Files
MEIZU-Battery-Healthy/lib/services/saf_storage_service.dart
T
2026-07-04 22:49:48 +08:00

137 lines
3.9 KiB
Dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:file_picker/file_picker.dart';
import '../models/saf_permission_state.dart';
/// 使用 file_picker 实现文件夹访问
class SafStorageService {
static final SafStorageService _instance = SafStorageService._internal();
factory SafStorageService() => _instance;
SafStorageService._internal();
static const String _prefKeySafPath = 'saf_storage_path';
String? _cachedPath;
Future<void> init() async {
final prefs = await SharedPreferences.getInstance();
_cachedPath = prefs.getString(_prefKeySafPath);
if (kDebugMode) {
print('[SAF] 初始化,缓存路径: $_cachedPath');
}
}
Future<SafPermissionState> getPermissionState() async {
if (_cachedPath == null || _cachedPath!.isEmpty) {
return SafPermissionState.unauthorized;
}
try {
final dir = Directory(_cachedPath!);
if (!await dir.exists()) {
_clearCache();
return SafPermissionState.expired;
}
return SafPermissionState.authorized;
} catch (e) {
_clearCache();
return SafPermissionState.expired;
}
}
Future<SafAuthorizationResult> requestPermission() async {
try {
// 使用 file_picker 选择文件夹
String? selectedPath = await FilePicker.platform.getDirectoryPath();
if (selectedPath == null || selectedPath.isEmpty) {
return SafAuthorizationResult.denied();
}
// 验证路径是否包含 mbattery_charger(可选,提高容错)
if (!selectedPath.contains('mbattery_charger')) {
return SafAuthorizationResult.error('请选择 mbattery_charger 文件夹');
}
_cachedPath = selectedPath;
await _savePath(selectedPath);
if (kDebugMode) {
print('[SAF] 授权成功,路径: $selectedPath');
}
return SafAuthorizationResult.success(selectedPath);
} catch (e) {
if (kDebugMode) {
print('[SAF] 授权失败: $e');
}
return SafAuthorizationResult.error('授权失败: $e');
}
}
Future<bool> logFileExists(String fileName) async {
final state = await getPermissionState();
if (state != SafPermissionState.authorized) return false;
try {
final file = File('${_cachedPath!}/$fileName');
return await file.exists();
} catch (e) {
return false;
}
}
Future<List<String>> readLogFile(String fileName) async {
final state = await getPermissionState();
if (state != SafPermissionState.authorized) return [];
try {
final file = File('${_cachedPath!}/$fileName');
if (!await file.exists()) return [];
return await file.readAsLines();
} catch (e) {
if (kDebugMode) {
print('[SAF] 读取文件失败: $e');
}
return [];
}
}
Future<List<String>> listFiles() async {
final state = await getPermissionState();
if (state != SafPermissionState.authorized) return [];
try {
final dir = Directory(_cachedPath!);
if (!await dir.exists()) return [];
final entities = await dir.list().toList();
return entities
.whereType<File>()
.map((e) => e.path.split(Platform.pathSeparator).last)
.toList();
} catch (e) {
if (kDebugMode) {
print('[SAF] 列出文件失败: $e');
}
return [];
}
}
Future<bool> validatePermission() async {
final state = await getPermissionState();
return state == SafPermissionState.authorized;
}
void _clearCache() {
_cachedPath = null;
_savePath(null);
}
Future<void> _savePath(String? path) async {
final prefs = await SharedPreferences.getInstance();
if (path != null && path.isNotEmpty) {
await prefs.setString(_prefKeySafPath, path);
} else {
await prefs.remove(_prefKeySafPath);
}
}
String? get cachedPath => _cachedPath;
}