SAF初步修改,等待验证
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
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
|
||||
.where((e) => e is 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;
|
||||
}
|
||||
Reference in New Issue
Block a user