Flutter应用包安装管理插件package_installer_plus的使用
Flutter应用包安装管理插件package_installer_plus的使用
package_installer_plus
是一个用于在 Android 应用中安装 APK 的 Flutter 插件。
使用方法
- 在
pubspec.yaml
文件中添加依赖:
dependencies:
package_installer_plus: ^1.0.0
- 运行
flutter pub get
以获取并安装该依赖。
Android 配置
无需进行额外配置。
示例代码
以下是一个完整的示例代码,展示了如何使用 package_installer_plus
插件从网络下载 APK 并进行安装。
import 'dart:io';
import 'dart:typed_data';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
import 'package:package_installer_plus/package_installer_plus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<FormState> _formKey = GlobalKey();
final TextEditingController _urlController = TextEditingController();
final _packageInstallerPlusPlugin = PackageInstallerPlus();
bool _isDownloading = false;
Timer? _logTimer;
double _percentage = 0;
[@override](/user/override)
void initState() {
super.initState();
}
[@override](/user/override)
void dispose() {
_urlController.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('安装 APK'),
),
body: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: Colors.blue.withAlpha(10),
borderRadius: BorderRadius.circular(30),
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
child: Form(
key: _formKey,
child: Column(
children: [
const SizedBox(height: 24),
TextFormField(
controller: _urlController,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
),
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入 URL';
}
return null;
},
minLines: 4,
maxLines: 15,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.done,
readOnly: _isDownloading,
decoration: InputDecoration(
fillColor: Colors.white,
hintText: 'APK 下载 URL',
hintStyle: const TextStyle(
color: Colors.black26,
fontSize: 12,
fontWeight: FontWeight.w400,
),
prefixIcon: Icon(Icons.link_rounded, color: Colors.green.shade800, size: 18),
contentPadding: EdgeInsets.zero,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.black38),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.black38),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.blueAccent, width: 1.5),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.red.shade800),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(color: Colors.red.shade800, width: 1.5),
),
),
onFieldSubmitted: (val) => _downloadApk(),
),
const SizedBox(height: 12),
Opacity(
opacity: _isDownloading ? 0.6 : 1,
child: ElevatedButton(
onPressed: _isDownloading ? null : () => _downloadApk(),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.green.shade900),
minimumSize: const MaterialStatePropertyAll(Size(100, 35)),
),
child: const Text(
'安装',
style: TextStyle(
color: Colors.white,
fontSize: 13,
),
),
),
),
const SizedBox(height: 12),
Visibility(
visible: _isDownloading,
maintainAnimation: true,
maintainSize: false,
maintainState: true,
child: Row(
children: [
Expanded(
child: LinearProgressIndicator(
color: Colors.green.shade800,
value: _percentage,
),
),
const SizedBox(width: 8),
Text('${(_percentage * 100).round()} %',
style: const TextStyle(
fontSize: 10,
),
),
],
),
),
],
),
),
),
),
),
);
}
// 异步下载 APK 并安装
Future<void> _downloadApk() async {
FocusScope.of(context).unfocus();
if (_formKey.currentState!.validate()) {
try {
if (_logTimer != null && _logTimer!.isActive) {
_logTimer!.cancel();
}
_percentage = 0;
_logTimer = Timer.periodic(const Duration(seconds: 1), (timer) async {
if (_percentage < 0.9) {
setState(() => _percentage = double.parse((_percentage + 0.1).toStringAsFixed(1)));
}
});
setState(() => _isDownloading = true);
String? filePath = await _downloadAndCreateFile(_urlController.text);
log('文件路径 : $filePath');
_logTimer?.cancel();
setState(() => _percentage = 1);
await Future.delayed(const Duration(seconds: 1));
if (filePath != null) {
bool res = await _packageInstallerPlusPlugin.installApk(filePath: filePath);
log('安装 APK 结果 : $res');
}
} catch (e) {
log('异常 : $e');
}
setState(() => _isDownloading = false);
}
}
// 下载文件并创建文件
Future<String?> _downloadAndCreateFile(String fileUrl) async {
Uint8List? res = await _downloadFile(fileUrl);
if (res != null) {
Directory folder = await getTemporaryDirectory();
if (!await folder.exists()) {
await folder.create();
}
File file = File('${folder.path}${Platform.pathSeparator}update.apk')
..createSync(recursive: true);
await file.writeAsBytes(res, flush: true);
return file.path;
}
return null;
}
// 下载文件
Future<Uint8List?> _downloadFile(String fileUrl) async {
log('开始下载文件');
Uint8List? returnVal;
await http.get(
Uri.parse(fileUrl),
).then((response) async {
log('下载文件结果 : 状态码 ${response.statusCode}, 数据长度 ${response.body.length}');
if (response.statusCode == 200) {
returnVal = response.bodyBytes;
} else {
returnVal = null;
}
}).catchError((error) {
log('下载文件错误 : ${error.toString()}');
returnVal = null;
});
log('结束下载文件');
return returnVal;
}
}
更多关于Flutter应用包安装管理插件package_installer_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter应用包安装管理插件package_installer_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter应用中使用package_installer_plus
插件来进行应用包安装管理的示例代码。这个插件允许你在Flutter应用中触发APK文件的安装过程。
首先,你需要在你的pubspec.yaml
文件中添加package_installer_plus
依赖:
dependencies:
flutter:
sdk: flutter
package_installer_plus: ^x.y.z # 请将x.y.z替换为最新版本号
然后,运行flutter pub get
来获取依赖。
接下来,在你的Flutter应用中,你可以按照以下步骤使用package_installer_plus
插件:
- 导入插件:
import 'package:package_installer_plus/package_installer_plus.dart';
- 请求安装权限(在Android上可能需要):
由于安装APK文件可能需要特定的权限,建议在安装前检查并请求这些权限。以下是一个简单的权限请求示例:
import 'package:permission_handler/permission_handler.dart';
Future<void> requestInstallPermissions() async {
var status = await Permission.installPackages.status;
if (!status.isGranted) {
var result = await Permission.installPackages.request();
if (result.isGranted) {
print("Install Packages permission granted.");
} else {
print("Install Packages permission denied.");
}
} else {
print("Install Packages permission is already granted.");
}
}
注意:你需要添加permission_handler
依赖来处理权限请求。
- 安装APK文件:
使用PackageInstallerPlus
类来安装APK文件。假设你有一个APK文件的路径,你可以这样调用安装方法:
Future<void> installApk(String apkFilePath) async {
try {
bool result = await PackageInstallerPlus.install(apkFilePath);
if (result) {
print("APK installation succeeded.");
} else {
print("APK installation failed.");
}
} catch (e) {
print("Error during APK installation: $e");
}
}
- 完整示例:
以下是一个完整的示例,将权限请求和APK安装结合起来:
import 'package:flutter/material.dart';
import 'package:package_installer_plus/package_installer_plus.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('APK Installer Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
// 请求安装权限
await requestInstallPermissions();
// APK文件路径(请替换为你的APK文件路径)
String apkFilePath = "/path/to/your/app.apk";
// 安装APK
await installApk(apkFilePath);
},
child: Text('Install APK'),
),
),
),
);
}
}
Future<void> requestInstallPermissions() async {
var status = await Permission.installPackages.status;
if (!status.isGranted) {
var result = await Permission.installPackages.request();
if (!result.isGranted) {
// 处理权限被拒绝的情况
throw Exception("Install Packages permission is required to install APK.");
}
}
}
Future<void> installApk(String apkFilePath) async {
try {
bool result = await PackageInstallerPlus.install(apkFilePath);
if (result) {
// 安装成功后的处理
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('APK installed successfully')));
} else {
// 安装失败后的处理
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('APK installation failed')));
}
} catch (e) {
// 错误处理
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e')));
}
}
注意:
- 在实际使用中,请确保APK文件路径是正确的。
- 在Android上,你可能需要在
AndroidManifest.xml
中添加相关权限声明,尽管package_installer_plus
插件通常已经处理了这些权限。 - iOS上不支持直接从应用中安装APK文件,这个插件主要用于Android平台。
这个示例展示了如何使用package_installer_plus
插件来请求安装权限并安装APK文件。希望这对你有所帮助!