SAF初步修改,等待验证
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
<!--<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />-->
|
||||||
<application
|
<application
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
|||||||
+7
-1
@@ -1,7 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'pages/battery_health_page.dart';
|
import 'pages/battery_health_page.dart';
|
||||||
|
import 'services/saf_storage_service.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
// 🟢 初始化 SAF 服务
|
||||||
|
await SafStorageService().init();
|
||||||
|
|
||||||
void main() {
|
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/// SAF 权限状态
|
||||||
|
enum SafPermissionState {
|
||||||
|
/// 未授权(首次使用)
|
||||||
|
unauthorized,
|
||||||
|
|
||||||
|
/// 已授权,Uri 有效
|
||||||
|
authorized,
|
||||||
|
|
||||||
|
/// 授权已过期或 Uri 失效
|
||||||
|
expired,
|
||||||
|
|
||||||
|
/// 用户拒绝了授权
|
||||||
|
denied,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SAF 授权结果
|
||||||
|
class SafAuthorizationResult {
|
||||||
|
final bool success;
|
||||||
|
final String? uriString;
|
||||||
|
final SafPermissionState state;
|
||||||
|
final String? errorMessage;
|
||||||
|
|
||||||
|
SafAuthorizationResult(
|
||||||
|
{
|
||||||
|
required this.success,
|
||||||
|
this.uriString,
|
||||||
|
required this.state,
|
||||||
|
this.errorMessage,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
factory SafAuthorizationResult.success(String uri) {
|
||||||
|
return SafAuthorizationResult(
|
||||||
|
success: true,
|
||||||
|
uriString: uri,
|
||||||
|
state: SafPermissionState.authorized,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory SafAuthorizationResult.denied() {
|
||||||
|
return SafAuthorizationResult(
|
||||||
|
success: false,
|
||||||
|
state: SafPermissionState.denied,
|
||||||
|
errorMessage: '用户拒绝了文件夹访问权限',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory SafAuthorizationResult.expired() {
|
||||||
|
return SafAuthorizationResult(
|
||||||
|
success: false,
|
||||||
|
state: SafPermissionState.expired,
|
||||||
|
errorMessage: '文件夹访问权限已过期,请重新授权',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory SafAuthorizationResult.error(String message) {
|
||||||
|
return SafAuthorizationResult(
|
||||||
|
success: false,
|
||||||
|
state: SafPermissionState.unauthorized,
|
||||||
|
errorMessage: message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ import 'dart:developer' as dev;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
@@ -13,6 +12,8 @@ import 'package:device_info_plus/device_info_plus.dart';
|
|||||||
import '../models/device_matching.dart';
|
import '../models/device_matching.dart';
|
||||||
import '../utils/charge_utils.dart';
|
import '../utils/charge_utils.dart';
|
||||||
import '../widgets/charge_detail_page.dart';
|
import '../widgets/charge_detail_page.dart';
|
||||||
|
import '../services/saf_storage_service.dart';
|
||||||
|
import '../models/saf_permission_state.dart';
|
||||||
|
|
||||||
// --- 潘通色定义 ---
|
// --- 潘通色定义 ---
|
||||||
const Color kHealthGreen = Color(0xFF00B140);
|
const Color kHealthGreen = Color(0xFF00B140);
|
||||||
@@ -40,23 +41,24 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
double _maxVolt = 0;
|
double _maxVolt = 0;
|
||||||
double _minVolt = 0;
|
double _minVolt = 0;
|
||||||
bool _hasData = false;
|
bool _hasData = false;
|
||||||
final String _filePath = '/storage/emulated/0/mbattery_charger/';
|
|
||||||
|
|
||||||
// ---------- 趋势图数据 ----------
|
// ---------- 趋势图数据 ----------
|
||||||
List<Map<String, dynamic>> _trendData = [];
|
List<Map<String, dynamic>> _trendData = [];
|
||||||
|
|
||||||
// ---------- 充电状态 ----------
|
// ---------- 充电状态 ----------
|
||||||
bool _isCharging = false;
|
bool _isCharging = false;
|
||||||
String _chargeType = ''; // "EPP", "PPS", "SDP", "无线", "MZ_EPP" 等
|
String _chargeType = '';
|
||||||
double _chargePower = 0.0;
|
double _chargePower = 0.0;
|
||||||
double _chargeVolt = 0.0;
|
double _chargeVolt = 0.0;
|
||||||
double _chargeCurr = 0.0;
|
double _chargeCurr = 0.0;
|
||||||
int? _wiredLevel;
|
int? _wiredLevel;
|
||||||
bool _isWireless = false;
|
bool _isWireless = false;
|
||||||
|
|
||||||
// 🟢 1.3.0-dev.3: 充电开始时间(UTC),用于时间窗口判断
|
|
||||||
DateTime? _chargingStartTime;
|
DateTime? _chargingStartTime;
|
||||||
|
|
||||||
|
// ---------- SAF 状态 ----------
|
||||||
|
final SafStorageService _safService = SafStorageService();
|
||||||
|
SafPermissionState _safState = SafPermissionState.unauthorized;
|
||||||
|
|
||||||
// 动画控制
|
// 动画控制
|
||||||
late AnimationController _chargeAnimationController;
|
late AnimationController _chargeAnimationController;
|
||||||
late Animation<double> _bottomSlide;
|
late Animation<double> _bottomSlide;
|
||||||
@@ -150,22 +152,25 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 扫描目录 ----------
|
// ---------- 扫描目录 (SAF 模式) ----------
|
||||||
Future<void> _scanAndUpdateDB() async {
|
Future<void> _scanAndUpdateDB() async {
|
||||||
Directory dir = Directory(_filePath);
|
// 检查 SAF 授权状态
|
||||||
if (!await dir.exists()) return;
|
_safState = await _safService.getPermissionState();
|
||||||
|
if (_safState != SafPermissionState.authorized) {
|
||||||
|
_showSafAuthorizationDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<FileSystemEntity> files = await dir.list().toList();
|
try {
|
||||||
RegExp filePattern = RegExp(r'mbattery_charger_log_(\d{4}_\d{2}_\d{2})$');
|
final files = await _safService.listFiles();
|
||||||
|
RegExp filePattern = RegExp(r'mbattery_charger_log_(\d{4}_\d{2}_\d{2})$');
|
||||||
|
|
||||||
for (FileSystemEntity entity in files) {
|
for (String fileName in files) {
|
||||||
if (entity is File) {
|
|
||||||
String fileName = path.basename(entity.path);
|
|
||||||
Match? match = filePattern.firstMatch(fileName);
|
Match? match = filePattern.firstMatch(fileName);
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
String dateStr = match.group(1)!.replaceAll('_', '-');
|
String dateStr = match.group(1)!.replaceAll('_', '-');
|
||||||
try {
|
try {
|
||||||
List<String> lines = await entity.readAsLines();
|
List<String> lines = await _safService.readLogFile(fileName);
|
||||||
if (lines.isEmpty) continue;
|
if (lines.isEmpty) continue;
|
||||||
|
|
||||||
List<String> validLines = lines
|
List<String> validLines = lines
|
||||||
@@ -195,10 +200,12 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
dev.log('[_scanAndUpdateDB] ❌ 扫描异常: $e', name: 'BatteryHealth');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 1.3.0-dev.1: 使用 UTC 生成文件名 ----------
|
// ---------- UTC 文件名 ----------
|
||||||
String getTodayFileName() {
|
String getTodayFileName() {
|
||||||
DateTime nowUtc = DateTime.now().toUtc();
|
DateTime nowUtc = DateTime.now().toUtc();
|
||||||
String year = nowUtc.year.toString();
|
String year = nowUtc.year.toString();
|
||||||
@@ -208,7 +215,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 时间戳工具方法 ----------
|
// ---------- 时间戳工具方法 ----------
|
||||||
/// 解析日志行中的时间戳,强制解析为 UTC
|
|
||||||
DateTime? _parseLogTimestamp(String line) {
|
DateTime? _parseLogTimestamp(String line) {
|
||||||
RegExp reg = RegExp(r'\[(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})\]');
|
RegExp reg = RegExp(r'\[(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})\]');
|
||||||
Match? match = reg.firstMatch(line);
|
Match? match = reg.firstMatch(line);
|
||||||
@@ -231,20 +237,79 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 🟢 1.3.0-dev.3: 时间窗口以插入时刻为基准,只向前看
|
|
||||||
bool _isLogTimestampValid(DateTime? logTime) {
|
bool _isLogTimestampValid(DateTime? logTime) {
|
||||||
if (logTime == null) return false;
|
if (logTime == null) return false;
|
||||||
if (_chargingStartTime == null) {
|
if (_chargingStartTime == null) {
|
||||||
// 边缘情况:回退到当前时间 ±3 分钟
|
|
||||||
DateTime nowUtc = DateTime.now().toUtc();
|
DateTime nowUtc = DateTime.now().toUtc();
|
||||||
Duration diff = nowUtc.difference(logTime);
|
Duration diff = nowUtc.difference(logTime);
|
||||||
return diff.abs().inMinutes <= 3;
|
return diff.abs().inMinutes <= 3;
|
||||||
}
|
}
|
||||||
// 日志时间必须在 [充电开始时间, 充电开始时间 + 3 分钟] 范围内
|
|
||||||
DateTime endTime = _chargingStartTime!.add(const Duration(minutes: 3));
|
DateTime endTime = _chargingStartTime!.add(const Duration(minutes: 3));
|
||||||
return logTime.isAfter(_chargingStartTime!) && logTime.isBefore(endTime);
|
return logTime.isAfter(_chargingStartTime!) && logTime.isBefore(endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- SAF 授权引导 ----------
|
||||||
|
void _showSafAuthorizationDialog() {
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('需要文件夹访问权限'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: const [
|
||||||
|
Text('请授权访问日志文件夹,以读取电池数据。'),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'目标路径:\n/storage/emulated/0/mbattery_charger/',
|
||||||
|
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text('点击"选择文件夹"后,请在系统文件管理器中找到并选中上述文件夹。'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
setState(() {
|
||||||
|
_safState = SafPermissionState.denied;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text('取消'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final ctx = context;
|
||||||
|
Navigator.pop(ctx);
|
||||||
|
final result = await _safService.requestPermission();
|
||||||
|
if (result.success) {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() {
|
||||||
|
_safState = SafPermissionState.authorized;
|
||||||
|
});
|
||||||
|
readBatteryCapacity();
|
||||||
|
} else {
|
||||||
|
if (!mounted) return;
|
||||||
|
ScaffoldMessenger.of(ctx).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(result.errorMessage ?? '授权失败,请重试'),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_showSafAuthorizationDialog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('选择文件夹'), // 🟢 加这行
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- 核心:系统API定调 ----------
|
// ---------- 核心:系统API定调 ----------
|
||||||
void _applySystemChargeState(bool isCharging, String systemChargeType) {
|
void _applySystemChargeState(bool isCharging, String systemChargeType) {
|
||||||
dev.log(
|
dev.log(
|
||||||
@@ -263,12 +328,11 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
_chargeVolt = 0.0;
|
_chargeVolt = 0.0;
|
||||||
_chargeCurr = 0.0;
|
_chargeCurr = 0.0;
|
||||||
_wiredLevel = null;
|
_wiredLevel = null;
|
||||||
_chargingStartTime = null; // 🟢 清空开始时间
|
_chargingStartTime = null;
|
||||||
_updateChargeState();
|
_updateChargeState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🟢 1.3.0-dev.3: 记录充电开始时刻(仅当从断开状态变为充电状态时)
|
|
||||||
if (_chargingStartTime == null) {
|
if (_chargingStartTime == null) {
|
||||||
_chargingStartTime = DateTime.now().toUtc();
|
_chargingStartTime = DateTime.now().toUtc();
|
||||||
dev.log(
|
dev.log(
|
||||||
@@ -297,7 +361,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
_isWireless = false;
|
_isWireless = false;
|
||||||
_chargeType = "SDP";
|
_chargeType = "SDP";
|
||||||
} else {
|
} else {
|
||||||
// UNKNOWN 时清空旧类型,等待日志修正
|
|
||||||
dev.log(
|
dev.log(
|
||||||
'[_applySystemChargeState] ⚠️ 未知类型: $systemChargeType,清空类型等待日志',
|
'[_applySystemChargeState] ⚠️ 未知类型: $systemChargeType,清空类型等待日志',
|
||||||
name: 'BatteryHealth',
|
name: 'BatteryHealth',
|
||||||
@@ -324,7 +387,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
name: 'BatteryHealth',
|
name: 'BatteryHealth',
|
||||||
);
|
);
|
||||||
|
|
||||||
// ---------- 1. 收集所有在有效时间窗口内的数据行 ----------
|
|
||||||
List<Map<String, dynamic>> validLines = [];
|
List<Map<String, dynamic>> validLines = [];
|
||||||
for (String line in lines) {
|
for (String line in lines) {
|
||||||
DateTime? timestamp = _parseLogTimestamp(line);
|
DateTime? timestamp = _parseLogTimestamp(line);
|
||||||
@@ -349,10 +411,8 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按时间戳排序(从新到旧)
|
|
||||||
validLines.sort((a, b) => b['timestamp'].compareTo(a['timestamp']));
|
validLines.sort((a, b) => b['timestamp'].compareTo(a['timestamp']));
|
||||||
|
|
||||||
// 取最新的一条
|
|
||||||
Map<String, dynamic> latest = validLines.first;
|
Map<String, dynamic> latest = validLines.first;
|
||||||
String latestLine = latest['line'];
|
String latestLine = latest['line'];
|
||||||
String latestType = latest['type'];
|
String latestType = latest['type'];
|
||||||
@@ -363,7 +423,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
name: 'BatteryHealth',
|
name: 'BatteryHealth',
|
||||||
);
|
);
|
||||||
|
|
||||||
// ---------- 2. 无线处理 ----------
|
// ---------- 无线 ----------
|
||||||
if (latestType == 'wls') {
|
if (latestType == 'wls') {
|
||||||
dev.log('[_parseChargeDataFromLog] 处理无线数据', name: 'BatteryHealth');
|
dev.log('[_parseChargeDataFromLog] 处理无线数据', name: 'BatteryHealth');
|
||||||
|
|
||||||
@@ -390,7 +450,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 3. 有线处理 ----------
|
// ---------- 有线 ----------
|
||||||
if (latestType == 'usb') {
|
if (latestType == 'usb') {
|
||||||
dev.log('[_parseChargeDataFromLog] 处理有线数据', name: 'BatteryHealth');
|
dev.log('[_parseChargeDataFromLog] 处理有线数据', name: 'BatteryHealth');
|
||||||
|
|
||||||
@@ -411,7 +471,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
|
|
||||||
_isWireless = false;
|
_isWireless = false;
|
||||||
|
|
||||||
// 🟢 1.3.0-dev.2: real_type 优先级最高
|
|
||||||
if (realType != null && realType == "PPS") {
|
if (realType != null && realType == "PPS") {
|
||||||
_chargeType = "PPS";
|
_chargeType = "PPS";
|
||||||
} else if (realType != null &&
|
} else if (realType != null &&
|
||||||
@@ -438,14 +497,13 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🟢 1.3.0-dev.3: 增加超时保护
|
// ---------- SAF 文件读取 ----------
|
||||||
Future<void> _fetchChargeDataFromLog() async {
|
Future<void> _fetchChargeDataFromLog() async {
|
||||||
if (!_isCharging) {
|
if (!_isCharging) {
|
||||||
dev.log('[_fetchChargeDataFromLog] 未充电,跳过读取', name: 'BatteryHealth');
|
dev.log('[_fetchChargeDataFromLog] 未充电,跳过读取', name: 'BatteryHealth');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 超时检查:如果插入超过 5 分钟还没读到数据,不再频繁报错
|
|
||||||
if (_chargingStartTime != null) {
|
if (_chargingStartTime != null) {
|
||||||
Duration elapsed = DateTime.now().toUtc().difference(_chargingStartTime!);
|
Duration elapsed = DateTime.now().toUtc().difference(_chargingStartTime!);
|
||||||
if (elapsed.inMinutes > 5) {
|
if (elapsed.inMinutes > 5) {
|
||||||
@@ -457,24 +515,35 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String fullPath = _filePath + getTodayFileName();
|
// 检查 SAF 授权
|
||||||
dev.log('[_fetchChargeDataFromLog] 尝试读取: $fullPath', name: 'BatteryHealth');
|
_safState = await _safService.getPermissionState();
|
||||||
|
if (_safState != SafPermissionState.authorized) {
|
||||||
|
if (mounted) _showSafAuthorizationDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
File file = File(fullPath);
|
final fileName = getTodayFileName();
|
||||||
if (!await file.exists()) {
|
dev.log('[_fetchChargeDataFromLog] 尝试读取: $fileName', name: 'BatteryHealth');
|
||||||
|
|
||||||
|
final exists = await _safService.logFileExists(fileName);
|
||||||
|
if (!exists) {
|
||||||
dev.log(
|
dev.log(
|
||||||
'[_fetchChargeDataFromLog] ⚠️ 文件不存在: $fullPath',
|
'[_fetchChargeDataFromLog] ⚠️ 文件不存在: $fileName',
|
||||||
name: 'BatteryHealth',
|
name: 'BatteryHealth',
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> lines = await file.readAsLines();
|
final lines = await _safService.readLogFile(fileName);
|
||||||
|
if (lines.isEmpty) {
|
||||||
|
dev.log('[_fetchChargeDataFromLog] 文件为空', name: 'BatteryHealth');
|
||||||
|
return;
|
||||||
|
}
|
||||||
dev.log(
|
dev.log(
|
||||||
'[_fetchChargeDataFromLog] ✅ 读取成功,共 ${lines.length} 行',
|
'[_fetchChargeDataFromLog] ✅ 读取成功,共 ${lines.length} 行',
|
||||||
name: 'BatteryHealth',
|
name: 'BatteryHealth',
|
||||||
);
|
);
|
||||||
if (lines.isEmpty) return;
|
|
||||||
_parseChargeDataFromLog(lines);
|
_parseChargeDataFromLog(lines);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dev.log('[_fetchChargeDataFromLog] ❌ 读取异常: $e', name: 'BatteryHealth');
|
dev.log('[_fetchChargeDataFromLog] ❌ 读取异常: $e', name: 'BatteryHealth');
|
||||||
@@ -535,19 +604,20 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
|
|
||||||
// ---------- 读取当前数据 ----------
|
// ---------- 读取当前数据 ----------
|
||||||
Future<void> readBatteryCapacity() async {
|
Future<void> readBatteryCapacity() async {
|
||||||
var status = await Permission.manageExternalStorage.request();
|
// 检查 SAF 授权
|
||||||
if (!status.isGranted) {
|
_safState = await _safService.getPermissionState();
|
||||||
setState(() => _hasData = false);
|
if (_safState != SafPermissionState.authorized) {
|
||||||
|
if (mounted) _showSafAuthorizationDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _getDeviceInfo();
|
await _getDeviceInfo();
|
||||||
await _scanAndUpdateDB();
|
await _scanAndUpdateDB();
|
||||||
|
|
||||||
String fullPath = _filePath + getTodayFileName();
|
final fileName = getTodayFileName();
|
||||||
File file = File(fullPath);
|
final exists = await _safService.logFileExists(fileName);
|
||||||
|
|
||||||
if (!await file.exists()) {
|
if (!exists) {
|
||||||
List<Map<String, dynamic>> recent = await _queryRecentData(1);
|
List<Map<String, dynamic>> recent = await _queryRecentData(1);
|
||||||
if (recent.isNotEmpty) {
|
if (recent.isNotEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -567,7 +637,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> lines = await file.readAsLines();
|
final lines = await _safService.readLogFile(fileName);
|
||||||
if (lines.isEmpty) {
|
if (lines.isEmpty) {
|
||||||
setState(() => _hasData = false);
|
setState(() => _hasData = false);
|
||||||
if (_isCharging) _fetchChargeDataFromLog();
|
if (_isCharging) _fetchChargeDataFromLog();
|
||||||
@@ -700,8 +770,16 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
// 延迟初始化 SAF 并读取数据
|
||||||
readBatteryCapacity();
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
await _safService.init();
|
||||||
|
_safState = await _safService.getPermissionState();
|
||||||
|
if (_safState == SafPermissionState.unauthorized ||
|
||||||
|
_safState == SafPermissionState.expired) {
|
||||||
|
if (mounted) _showSafAuthorizationDialog();
|
||||||
|
} else {
|
||||||
|
readBatteryCapacity();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,9 +877,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
height: 1.0,
|
height: 1.0,
|
||||||
color: healthPercent < 70
|
color: healthPercent < 70 ? Colors.red : Colors.black,
|
||||||
? Colors.red
|
|
||||||
: Colors.black, // 🟢 动态颜色
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 2),
|
||||||
@@ -813,7 +889,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
height: 1.0,
|
height: 1.0,
|
||||||
color: healthPercent < 70
|
color: healthPercent < 70
|
||||||
? Colors.red
|
? Colors.red
|
||||||
: Colors.grey.shade600, // 🟢 动态颜色
|
: Colors.grey.shade600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1047,7 +1123,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
|||||||
} else if (value >= 70) {
|
} else if (value >= 70) {
|
||||||
barColor = kHealthYellow;
|
barColor = kHealthYellow;
|
||||||
} else {
|
} else {
|
||||||
barColor = Colors.red; // 🟢 小于 70 显示红色
|
barColor = Colors.red;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
barColor = Colors.grey.shade300;
|
barColor = Colors.grey.shade300;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
jni
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
import path_provider_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite_darwin
|
import sqflite_darwin
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
+261
-101
@@ -6,7 +6,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
async:
|
async:
|
||||||
@@ -14,7 +14,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.1"
|
version: "2.13.1"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
@@ -22,39 +22,55 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.1"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
|
code_assets:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: code_assets
|
||||||
|
sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.1"
|
version: "1.19.1"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
|
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.9"
|
version: "1.0.9"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
@@ -62,7 +78,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
|
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.1.2"
|
version: "10.1.2"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
@@ -70,7 +86,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: device_info_plus_platform_interface
|
name: device_info_plus_platform_interface
|
||||||
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.3"
|
version: "7.0.3"
|
||||||
fake_async:
|
fake_async:
|
||||||
@@ -78,7 +94,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.3"
|
||||||
ffi:
|
ffi:
|
||||||
@@ -86,7 +102,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
|
sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
file:
|
file:
|
||||||
@@ -94,9 +110,17 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
file_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: file_picker
|
||||||
|
sha256: "1bbf65dd997458a08b531042ec3794112a6c39c07c37ff22113d2e7e4f81d4e4"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.2.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -107,15 +131,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
sha256: "3854fe5e3bff0b113c658f260b90c95dea17c92db0f2addeac2e343dd9969785"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.35"
|
||||||
flutter_svg:
|
flutter_svg:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f"
|
sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -128,12 +160,20 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
hooks:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: hooks
|
||||||
|
sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.0"
|
version: "1.6.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
@@ -141,15 +181,31 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
jni:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: jni
|
||||||
|
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
jni_flutter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: jni_flutter
|
||||||
|
sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.0.2"
|
version: "11.0.2"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
@@ -157,7 +213,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.10"
|
version: "3.0.10"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
@@ -165,7 +221,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.2"
|
||||||
lints:
|
lints:
|
||||||
@@ -173,39 +229,63 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.1"
|
version: "5.1.1"
|
||||||
|
logging:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: logging
|
||||||
|
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.17"
|
version: "0.12.19"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.13.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0"
|
version: "1.18.0"
|
||||||
|
objective_c:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: objective_c
|
||||||
|
sha256: "6cb691c686fa2838c6deb34980d426145c2a5d537491cb83d463c33cdbc726ed"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "9.4.1"
|
||||||
|
package_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_config
|
||||||
|
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
path:
|
path:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
path_parsing:
|
path_parsing:
|
||||||
@@ -213,55 +293,55 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: path_parsing
|
name: path_parsing
|
||||||
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
sha256: a7f4874f987173da295a61c181b8ee71dab59b332a486b391babf26a1b884825
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.6"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba"
|
sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.23"
|
version: "2.3.1"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4"
|
sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.1"
|
version: "2.6.0"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
sha256: "58c2005f147315b11e9b4a7bc889cd5203e250cba8e3f012dae259b4972b5c16"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.2"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
sha256: "484838772624c3a4b94f1e44a3e19897fee738f2d5c4ce448443b0417f7c9dda"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.3"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
permission_handler:
|
permission_handler:
|
||||||
@@ -269,7 +349,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: permission_handler
|
name: permission_handler
|
||||||
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
|
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.4.0"
|
version: "11.4.0"
|
||||||
permission_handler_android:
|
permission_handler_android:
|
||||||
@@ -277,7 +357,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: permission_handler_android
|
name: permission_handler_android
|
||||||
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
|
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "12.1.0"
|
version: "12.1.0"
|
||||||
permission_handler_apple:
|
permission_handler_apple:
|
||||||
@@ -285,7 +365,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: permission_handler_apple
|
name: permission_handler_apple
|
||||||
sha256: "79dfa1df734798aa3cfdad166d3a3698c206d8813de13516ea1071b5d7e2f420"
|
sha256: "79dfa1df734798aa3cfdad166d3a3698c206d8813de13516ea1071b5d7e2f420"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.4.10"
|
version: "9.4.10"
|
||||||
permission_handler_html:
|
permission_handler_html:
|
||||||
@@ -293,7 +373,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: permission_handler_html
|
name: permission_handler_html
|
||||||
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3+5"
|
version: "0.1.3+5"
|
||||||
permission_handler_platform_interface:
|
permission_handler_platform_interface:
|
||||||
@@ -301,7 +381,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: permission_handler_platform_interface
|
name: permission_handler_platform_interface
|
||||||
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.0"
|
version: "4.3.0"
|
||||||
permission_handler_windows:
|
permission_handler_windows:
|
||||||
@@ -309,7 +389,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: permission_handler_windows
|
name: permission_handler_windows
|
||||||
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.1"
|
version: "0.2.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
@@ -317,7 +397,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.2"
|
version: "7.0.2"
|
||||||
platform:
|
platform:
|
||||||
@@ -325,7 +405,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.6"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
@@ -333,9 +413,81 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
record_use:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_use
|
||||||
|
sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.0"
|
||||||
|
shared_preferences:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shared_preferences
|
||||||
|
sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.5"
|
||||||
|
shared_preferences_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_android
|
||||||
|
sha256: "93ae5884a9df5d3bb696825bceb3a17590754548b5d740eba51500afc8d088f5"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.26"
|
||||||
|
shared_preferences_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_foundation
|
||||||
|
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.6"
|
||||||
|
shared_preferences_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_linux
|
||||||
|
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
|
shared_preferences_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_platform_interface
|
||||||
|
sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.2"
|
||||||
|
shared_preferences_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_web
|
||||||
|
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.3"
|
||||||
|
shared_preferences_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_windows
|
||||||
|
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -346,55 +498,55 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.2"
|
version: "1.10.2"
|
||||||
sqflite:
|
sqflite:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sqflite
|
name: sqflite
|
||||||
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
|
sha256: "58a799e6ac17dd32fbab93813d39ed835a75ccc0f8f85b8955fe318c6712b082"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.4.3"
|
||||||
sqflite_android:
|
sqflite_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqflite_android
|
name: sqflite_android
|
||||||
sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88
|
sha256: d0548f9d7422a2dae99ec6f8b0a3074463b132d216fa5ba0d230eeefc901983b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2+2"
|
version: "2.4.3"
|
||||||
sqflite_common:
|
sqflite_common:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqflite_common
|
name: sqflite_common
|
||||||
sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6"
|
sha256: "5bf6a55c166e73bf651ba7ec3ed486e577620e3dc8f3a9c6a258a8031b624590"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.6"
|
version: "2.5.11"
|
||||||
sqflite_darwin:
|
sqflite_darwin:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqflite_darwin
|
name: sqflite_darwin
|
||||||
sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
|
sha256: c86ca18b8f666bbf903924687fe21cc16fc385d086005067e26619ca530bef9f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.4.3+1"
|
||||||
sqflite_platform_interface:
|
sqflite_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqflite_platform_interface
|
name: sqflite_platform_interface
|
||||||
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
|
sha256: f84939f84350d92d04416f8bc4dc52d3896aec7716cc9e80cf0146342139dc50
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.12.1"
|
version: "1.12.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
@@ -402,7 +554,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
@@ -410,39 +562,39 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: synchronized
|
name: synchronized
|
||||||
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.0"
|
version: "3.4.1"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.2.2"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.6"
|
version: "0.7.11"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
vector_graphics:
|
vector_graphics:
|
||||||
@@ -450,7 +602,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: vector_graphics
|
name: vector_graphics
|
||||||
sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d"
|
sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.2.2"
|
||||||
vector_graphics_codec:
|
vector_graphics_codec:
|
||||||
@@ -458,23 +610,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: vector_graphics_codec
|
name: vector_graphics_codec
|
||||||
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
|
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.13"
|
version: "1.1.13"
|
||||||
vector_graphics_compiler:
|
vector_graphics_compiler:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_graphics_compiler
|
name: vector_graphics_compiler
|
||||||
sha256: b9b3f391857781aa96acacef96066f2f49b4cd03cf9fce3ca4d8da2ef5ea129e
|
sha256: "142a9146f447d15b10bdc00e21d5f4d83e5b32bb5f8f8f5a04c75311344923a3"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.2.6"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
@@ -482,7 +634,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.2.0"
|
version: "15.2.0"
|
||||||
web:
|
web:
|
||||||
@@ -490,7 +642,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
win32:
|
win32:
|
||||||
@@ -498,7 +650,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.15.0"
|
version: "5.15.0"
|
||||||
win32_registry:
|
win32_registry:
|
||||||
@@ -506,7 +658,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: win32_registry
|
name: win32_registry
|
||||||
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
|
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.5"
|
version: "1.1.5"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
@@ -514,17 +666,25 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.6.1"
|
version: "7.0.1"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.9.2 <4.0.0"
|
dart: ">=3.12.0 <4.0.0"
|
||||||
flutter: ">=3.35.0"
|
flutter: ">=3.44.0"
|
||||||
|
|||||||
+4
-1
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.3.0-dev.1
|
version: 1.3.0-dev.2
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.2
|
sdk: ^3.9.2
|
||||||
@@ -37,6 +37,9 @@ dependencies:
|
|||||||
path_provider: ^2.1.0
|
path_provider: ^2.1.0
|
||||||
path: ^1.9.0
|
path: ^1.9.0
|
||||||
flutter_svg: ^2.0.10+1
|
flutter_svg: ^2.0.10+1
|
||||||
|
shared_preferences: ^2.2.0
|
||||||
|
file_picker: ^6.0.0
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
jni
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||||
|
|||||||
Reference in New Issue
Block a user