本帖主要实现Flutter安卓系统 APK在线下载以及安装
- 检查APK权限
//必要权限,安装权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
//写外置存储的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//读外置存储的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
//读取手机状态和身份
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
引用架包:
permission_handler: ^3.2.0
引用:
import 'package:permission_handler/permission_handler.dart';
/// 检查是否有权限
void checkPermission() async {
PermissionStatus permission = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
if (permission != PermissionStatus.granted) {
Map<PermissionGroup, PermissionStatus> permissions =
await PermissionHandler()
.requestPermissions([PermissionGroup.storage]);
if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
return;
}
} else {
return;
}
}
- 下载APK文件
引用架包:
dio: ^3.0.7
引用文件:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
/// 下载并安装APK文件
void updateAppEx(String url) async {
try {
File _apkFile = await downloadAndroid(url);
_apkFilePath = _apkFile.path;
if (_apkFilePath.isEmpty) {
print('make sure the apk file is set');
return;
}
} catch (e) {
print('下载APK失败: $e');
}
}
//用分割URL来获取下载的APK名称
String getFlieName(String url) {
try {
if (url != null) {
List<String> lstStr = url.split('/');
return lstStr.last;
}
} catch (e) {
print("获取下载文件名错误:$e");
}
return "";
}
/// 下载安卓更新包
// ignore: missing_return
Future<File> downloadAndroid(String url) async {
//获取APK文件名
String fileName = getFlieName(url);
if (fileName != "") {
/// 创建存储文件
Directory storageDir = await getExternalStorageDirectory();
String storagePath = storageDir.path;
String filePath = '$storagePath/$fileName';
File file = new File(filePath);
try {
// if (!file.existsSync()) {
Dio dio = new Dio();
// file.createSync();
Response response = await dio.download(url, filePath,
onReceiveProgress: (int count, int total) {
//进度
var d = (count / total).toStringAsFixed(2);
_dPercent = double.parse(d);
print((_dPercent * 100).toString() + "%");
print("现在进度: 当前:$count 总:$total");
setState(() {});
});
if (response.data.statusCode == 200) {
_downloadFinish = true;
print('文件下载完成!:${response.data}');
setState(() {});
}
// }
return file;
} catch (e) {
print(e);
}
}
}
- 安装APK
引用架包:
install_plugin: ^2.0.1
引用:
import 'package:install_plugin/install_plugin.dart';
//安装APK
void installApk() {
try {
InstallPlugin.installApk(
_apkFilePath, "com.example.flutterDemo")
.then((result) {
print('install apk $result');
}).catchError((error) {
print('install apk error: $error');
});
} catch (e) {
print('安装APK失败: $e');
}
}
- 完整代码
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:install_plugin/install_plugin.dart';
import 'package:path_provider/path_provider.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:permission_handler/permission_handler.dart';
class UpdateApk extends StatefulWidget {
@override
_UpdateApk createState() => _UpdateApk();
}
class _UpdateApk extends State<UpdateApk> {
/// 检查是否有权限
void checkPermission() async {
PermissionStatus permission = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
if (permission != PermissionStatus.granted) {
Map<PermissionGroup, PermissionStatus> permissions =
await PermissionHandler()
.requestPermissions([PermissionGroup.storage]);
if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
return;
}
} else {
return;
}
}
String _apkFilePath = "";
/// 下载并安装APK文件
void updateAppEx(String url) async {
try {
File _apkFile = await downloadAndroid(url);
_apkFilePath = _apkFile.path;
if (_apkFilePath.isEmpty) {
print('make sure the apk file is set');
return;
}
} catch (e) {
print('下载APK失败: $e');
}
}
void installApk() {
try {
InstallPlugin.installApk(_apkFilePath, "com.example.flutterDemo")
.then((result) {
print('install apk $result');
}).catchError((error) {
print('install apk error: $error');
});
} catch (e) {
print('安装APK失败: $e');
}
}
String getFlieName(String url) {
try {
if (url != null) {
List<String> lstStr = url.split('/');
return lstStr.last;
}
} catch (e) {
print("获取下载文件名错误:$e");
}
return "";
}
double _dPercent = 0;
/// 下载安卓更新包
// ignore: missing_return
Future<File> downloadAndroid(String url) async {
String fileName = getFlieName(url);
if (fileName != "") {
/// 创建存储文件
Directory storageDir = await getExternalStorageDirectory();
String storagePath = storageDir.path;
String filePath = '$storagePath/$fileName';
File file = new File(filePath);
try {
// if (!file.existsSync()) {
Dio dio = new Dio();
// file.createSync();
Response response = await dio.download(url, filePath,
onReceiveProgress: (int count, int total) {
//进度
var d = (count / total).toStringAsFixed(2);
_dPercent = double.parse(d);
print((_dPercent * 100).toString() + "%");
print("现在进度: 当前:$count 总:$total");
setState(() {});
});
if (response.data.statusCode == 200) {
_downloadFinish = true;
print('文件下载完成!:${response.data}');
setState(() {});
}
// }
return file;
} catch (e) {
print(e);
}
}
}
@override
void initState() {
// TODO: implement initState
//初始化系统数据
checkPermission();
super.initState();
}
//下载APP
Future updateApp() {
setState(() {});
//APK文件下载地址
var url = "http://flutterdemo/demo_1_0_1.apk";
updateAppEx(url);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10, top: 10, right: 10),
child: MaterialButton(
color: Color(0xFF0F4C81),
textColor: Colors.white,
child: Text('下载APK', textAlign: TextAlign.center),
onPressed: updateApp,
),
),
Padding(
padding: EdgeInsets.only(left: 10, top: 10, right: 10),
child: new LinearPercentIndicator(
width: MediaQuery.of(context).size.width - 20,
animation: true,
lineHeight: 25.0,
percent: _dPercent,
center: Text(((_dPercent * 100).toString() + "%")),
linearStrokeCap: LinearStrokeCap.roundAll,
progressColor: Colors.greenAccent,
),
),
Padding(
padding: EdgeInsets.only(left: 10, top: 10, right: 10),
child: MaterialButton(
color: Color(0xFF0F4C81),
textColor: Colors.white,
child: Text('安装APK', textAlign: TextAlign.center),
onPressed: installApk,
),
),
]),
),
);
}
}