鸿蒙版Flutter如何实现token从本地读取,不上传git
首先,我们需要创建一个配置文件来存储token,然后修改代码从该文件读取token。
以下是修改方案:
1.首先,创建一个配置服务类来管理API token:
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'dart:convert';
class ConfigService {
static const String _configFileName = 'app_config.json';
static const String _defaultToken = ''; // 默认为空,需要用户配置
// 获取配置文件路径
static Future<File> get _configFile async {
final directory = await getApplicationDocumentsDirectory();
return File('${directory.path}/$_configFileName');
}
// 读取配置
static Future<Map<String, dynamic>> getConfig() async {
try {
final file = await _configFile;
// 检查文件是否存在
if (!await file.exists()) {
// 如果不存在,创建默认配置
await file.writeAsString(json.encode({
'api_token': _defaultToken,
}));
}
// 读取配置
final contents = await file.readAsString();
return json.decode(contents) as Map<String, dynamic>;
} catch (e) {
print('读取配置文件出错: $e');
// 返回默认配置
return {'api_token': _defaultToken};
}
}
// 保存配置
static Future<void> saveConfig(Map<String, dynamic> config) async {
try {
final file = await _configFile;
await file.writeAsString(json.encode(config));
} catch (e) {
print('保存配置文件出错: $e');
}
}
// 获取API Token
static Future<String> getApiToken() async {
final config = await getConfig();
return config['api_token'] as String? ?? _defaultToken;
}
// 保存API Token
static Future<void> saveApiToken(String token) async {
final config = await getConfig();
config['api_token'] = token;
await saveConfig(config);
}
}
2.然后,修改ranking_info_page.dart
文件,从配置服务获取token:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:uuid/uuid.dart';
import 'tracking_model.dart';
import 'models/tracking_history_model.dart';
import 'services/tracking_history_service.dart';
import 'services/config_service.dart'; // 导入配置服务
import 'pages/tracking_history_page.dart';
import 'pages/about_page.dart';
// ... 现有代码 ...
class _RankingInfoPageState extends State<RankingInfoPage> {
// ... 现有代码 ...
String? _apiToken; // 添加API Token变量
@override
void initState() {
super.initState();
_loadApiToken(); // 加载API Token
}
// 加载API Token
Future<void> _loadApiToken() async {
final token = await ConfigService.getApiToken();
setState(() {
_apiToken = token;
});
// 如果token为空,显示设置对话框
if (token.isEmpty) {
// 延迟显示对话框,确保界面已经构建完成
WidgetsBinding.instance.addPostFrameCallback((_) {
_showTokenSettingDialog();
});
}
}
// 显示Token设置对话框
Future<void> _showTokenSettingDialog() async {
final TextEditingController tokenController = TextEditingController();
tokenController.text = _apiToken ?? '';
return showDialog<void>(
context: context,
barrierDismissible: false, // 用户必须点击按钮才能关闭对话框
builder: (BuildContext context) {
return AlertDialog(
title: const Text('设置API Token'),
content: SingleChildScrollView(
child: Column(
children: <Widget>[
const Text('请输入ALAPI的Token,用于查询快递信息。\n可以从 https://alapi.cn 获取。'),
const SizedBox(height: 16),
TextField(
controller: tokenController,
decoration: const InputDecoration(
labelText: 'API Token',
border: OutlineInputBorder(),
),
),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('保存'),
onPressed: () async {
final token = tokenController.text.trim();
if (token.isNotEmpty) {
await ConfigService.saveApiToken(token);
setState(() {
_apiToken = token;
});
Navigator.of(context).pop();
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Token不能为空')),
);
}
},
),
],
);
},
);
}
Future<void> _queryTracking() async {
// 检查Token是否已设置
if (_apiToken == null || _apiToken!.isEmpty) {
_showTokenSettingDialog();
return;
}
setState(() {
_isLoading = true;
_errorMessage = null;
_trackingResponse = null;
});
// ... 现有代码 ...
try {
final response = await http.post(
Uri.parse('https://v3.alapi.cn/api/tracking'),
body: {
'token': _apiToken, // 使用从配置中读取的token
'number': number,
'com': _selectedCompany,
'phone': phone,
},
);
// ... 现有代码 ...
} catch (e) {
// ... 现有代码 ...
}
}
// ... 现有代码 ...
@override
Widget build(BuildContext context) {
return Scaffold(
// ... 现有代码 ...
appBar: AppBar(
// ... 现有代码 ...
actions: [
// 添加设置Token的按钮
IconButton(
icon: const Icon(Icons.vpn_key),
tooltip: '设置API Token',
onPressed: _showTokenSettingDialog,
),
// ... 现有的按钮 ...
],
),
// ... 现有代码 ...
);
}
// ... 现有代码 ...
}
3.最后,需要在pubspec.yaml中添加path_provider依赖:
dependencies:
flutter:
sdk: flutter
http: ^1.1.0
uuid: ^4.0.0
url_launcher: ^6.1.14
flutter_phone_direct_caller: ^2.1.1
path_provider: ^2.1.1 # 添加这一行
# ... 其他依赖
dependency_overrides:
shared_preferences:
git:
url: "https://gitcode.com/openharmony-sig/flutter_packages.git"
path: "packages/shared_preferences/shared_preferences"
url_launcher:
git:
url: "https://gitcode.com/openharmony-sig/flutter_packages.git"
path: "packages/url_launcher/url_launcher"
path_provider:
git:
url: "https://gitcode.com/openharmony-sig/flutter_packages.git"
path: "packages/path_provider/path_provider"
flutter_phone_direct_caller:
git:
url: "https://gitcode.com/openharmony-sig/fluttertpc_flutter_phone_direct_caller.git"
flutter:
uses-material-design: true
这样修改后,API Token将从本地配置文件读取,而不是硬编码在代码中。用户首次使用应用时,会弹出对话框要求设置Token。用户也可以通过点击AppBar上的新增按钮随时修改Token。
这种方式可以确保敏感信息不会被上传到Git仓库中,提高了应用的安全性。
大家可以尝试啦。
效果如图:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。