SAF测试阶段,验证中
This commit is contained in:
+3
-1
@@ -20,7 +20,9 @@ class MyApp extends StatelessWidget {
|
||||
title: '电池健康度',
|
||||
theme: ThemeData(
|
||||
fontFamily: 'HarmonyOS_Sans_SC',
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: const Color.fromARGB(255, 255, 255, 255),
|
||||
),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: const BatteryHealthPage(),
|
||||
|
||||
@@ -283,18 +283,23 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
final ctx = context;
|
||||
Navigator.pop(ctx);
|
||||
// 触发关闭
|
||||
Navigator.pop(context);
|
||||
|
||||
// 延迟确保动画完成
|
||||
await Future.delayed(const Duration(milliseconds: 150));
|
||||
|
||||
final result = await _safService.requestPermission();
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
if (result.success) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_safState = SafPermissionState.authorized;
|
||||
});
|
||||
readBatteryCapacity();
|
||||
} else {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(ctx).showSnackBar(
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(result.errorMessage ?? '授权失败,请重试'),
|
||||
backgroundColor: Colors.red,
|
||||
@@ -303,7 +308,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
_showSafAuthorizationDialog();
|
||||
}
|
||||
},
|
||||
child: const Text('选择文件夹'), // 🟢 加这行
|
||||
child: const Text('选择文件夹'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -774,6 +779,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await _safService.init();
|
||||
_safState = await _safService.getPermissionState();
|
||||
|
||||
if (_safState == SafPermissionState.unauthorized ||
|
||||
_safState == SafPermissionState.expired) {
|
||||
if (mounted) _showSafAuthorizationDialog();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@@ -12,55 +11,49 @@ class SafStorageService {
|
||||
static const MethodChannel _channel = MethodChannel(
|
||||
'com.lxh.battery_health/saf',
|
||||
);
|
||||
static const String _prefKeySafPath = 'saf_storage_path';
|
||||
String? _cachedPath;
|
||||
static const String _prefKeySafUri = 'saf_storage_uri';
|
||||
String? _cachedUri;
|
||||
|
||||
// 🟢 初始化时从 SharedPreferences 恢复 URI
|
||||
Future<void> init() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_cachedPath = prefs.getString(_prefKeySafPath);
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 初始化,缓存路径: $_cachedPath');
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_cachedUri = prefs.getString(_prefKeySafUri);
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 初始化,缓存 URI: $_cachedUri');
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 初始化失败: $e');
|
||||
}
|
||||
_cachedUri = null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<SafPermissionState> getPermissionState() async {
|
||||
if (_cachedPath == null || _cachedPath!.isEmpty) {
|
||||
if (_cachedUri == null || _cachedUri!.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;
|
||||
}
|
||||
// 🟢 简化:直接返回 authorized,相信本地缓存的 URI
|
||||
return SafPermissionState.authorized;
|
||||
}
|
||||
|
||||
Future<SafAuthorizationResult> requestPermission() async {
|
||||
try {
|
||||
final String? selectedPath = await _channel.invokeMethod('selectFolder');
|
||||
final String? uriString = await _channel.invokeMethod('selectFolder');
|
||||
|
||||
if (selectedPath == null || selectedPath.isEmpty) {
|
||||
if (uriString == null || uriString.isEmpty) {
|
||||
return SafAuthorizationResult.denied();
|
||||
}
|
||||
|
||||
// 验证路径是否包含 mbattery_charger
|
||||
if (!selectedPath.contains('mbattery_charger')) {
|
||||
return SafAuthorizationResult.error('请选择 mbattery_charger 文件夹');
|
||||
}
|
||||
|
||||
_cachedPath = selectedPath;
|
||||
await _savePath(selectedPath);
|
||||
_cachedUri = uriString;
|
||||
await _saveUri(uriString);
|
||||
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 授权成功,路径: $selectedPath');
|
||||
print('[SAF] 授权成功,URI: $uriString');
|
||||
}
|
||||
|
||||
return SafAuthorizationResult.success(selectedPath);
|
||||
return SafAuthorizationResult.success(uriString);
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 授权失败: $e');
|
||||
@@ -73,8 +66,11 @@ class SafStorageService {
|
||||
final state = await getPermissionState();
|
||||
if (state != SafPermissionState.authorized) return false;
|
||||
try {
|
||||
final file = File('${_cachedPath!}/$fileName');
|
||||
return await file.exists();
|
||||
final files = await _channel.invokeMethod('listFiles');
|
||||
if (files is List) {
|
||||
return files.contains(fileName);
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
@@ -84,9 +80,11 @@ class SafStorageService {
|
||||
final state = await getPermissionState();
|
||||
if (state != SafPermissionState.authorized) return [];
|
||||
try {
|
||||
final file = File('${_cachedPath!}/$fileName');
|
||||
if (!await file.exists()) return [];
|
||||
return await file.readAsLines();
|
||||
final String? content = await _channel.invokeMethod('readLogFile', {
|
||||
'fileName': fileName,
|
||||
});
|
||||
if (content == null || content.isEmpty) return [];
|
||||
return content.split('\n');
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 读取文件失败: $e');
|
||||
@@ -99,13 +97,11 @@ class SafStorageService {
|
||||
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();
|
||||
final result = await _channel.invokeMethod('listFiles');
|
||||
if (result is List) {
|
||||
return result.cast<String>();
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 列出文件失败: $e');
|
||||
@@ -120,18 +116,30 @@ class SafStorageService {
|
||||
}
|
||||
|
||||
void _clearCache() {
|
||||
_cachedPath = null;
|
||||
_savePath(null);
|
||||
_cachedUri = null;
|
||||
_saveUri(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);
|
||||
Future<void> _saveUri(String? uri) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
if (uri != null && uri.isNotEmpty) {
|
||||
await prefs.setString(_prefKeySafUri, uri);
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 保存 URI 成功: $uri');
|
||||
}
|
||||
} else {
|
||||
await prefs.remove(_prefKeySafUri);
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 清除 URI');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('[SAF] 保存 URI 失败: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String? get cachedPath => _cachedPath;
|
||||
String? get cachedUri => _cachedUri;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user