mifa网站开发费用,站嗨建站,帮人做网站在徐州被敲诈五万,马鞍山专业网站制作由于我做的项目不是放在APP商店#xff08;公司内部用#xff09;的#xff0c;一些flutter的第三方库不合适我#xff0c;我需要用的是从网上下载再安装#xff08;从服务下#xff09;#xff0c;网上也找了花了我好几天时间。不全又乱#xff0c;这我自己做一下备份…由于我做的项目不是放在APP商店公司内部用的一些flutter的第三方库不合适我我需要用的是从网上下载再安装从服务下网上也找了花了我好几天时间。不全又乱这我自己做一下备份
现在只使用安卓下载ios没有做后期可能更新
app更新要求 1.进入app就查看app是否要更新更新对比自己写 2.下载完成可以自动弹窗安装界面 正式开始
1.使用第三方库
dependencies:# 查询应用程序包信息package_info_plus: ^5.0.1# 创建和管理下载任务的插件flutter_downloader: ^1.11.6# 安装插件打开安装界面install_plugin: ^2.1.0# 权限处理程序permission_handler: ^11.3.0 package_info_plus插件获取版本的。我这就不实现了这个用起来没有难度的主要是看你怎么封装对比版本我这下面用的是网上的app连接就不用对比版本了直接下载。 2.权限
添加权限
android\app\src\main\AndroidManifest.xml manifest需要加上xmlns:toolshttp://schemas.android.com/tools, 不然可能报错 manifest xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:toolshttp://schemas.android.com/toolsapplicationandroid:labelcpmandroid:name${applicationName}android:iconmipmap/launcher_icon!-- flutter_downloader下载器安卓配置如果你想其它应该有权读取您的文件 --providerandroid:namevn.hunghd.flutterdownloader.DownloadedFileProviderandroid:authorities${applicationId}.flutter_downloader.providerandroid:exportedfalseandroid:grantUriPermissionstruemeta-dataandroid:nameandroid.support.FILE_PROVIDER_PATHSandroid:resourcexml/provider_paths//provider!-- 开始FlutterDownloader定制 --!-- 禁用默认初始化器 --providerandroid:nameandroidx.startup.InitializationProviderandroid:authorities${applicationId}.androidx-startupandroid:exportedfalsetools:nodemergemeta-dataandroid:nameandroidx.work.WorkManagerInitializerandroid:valueandroidx.startuptools:noderemove //provider!-- 声明自定义初始化器 --providerandroid:namevn.hunghd.flutterdownloader.FlutterDownloaderInitializerandroid:authorities${applicationId}.flutter-downloader-initandroid:exportedfalse!-- 更改此数字以配置最大并发任务数为5 --meta-dataandroid:namevn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKSandroid:value5 //provider!-- 结束FlutterDownloader定制 --/application!-- 允许网络连接 --uses-permission android:nameandroid.permission.INTERNET /!-- 接入wifi状态 --uses-permission android:nameandroid.permission.ACCESS_WIFI_STATE/!-- 允许程序获取网络信息状态 --uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE /!-- 写外部存储权限 --uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE/!-- 读取外部存储的权限 --uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE /!-- 安装 .apk 文件请求安装包权限 --uses-permission android:nameandroid.permission.REQUEST_INSTALL_PACKAGES /
/manifest
如果你是HTTP下载的 允许访问明文HTTP流量 你可能要通过这个去添加http下载权限 报错关键词 Cleartext HTTP traffic to xxx not permitted 3.初始化
import package:flutter_downloader/flutter_downloader.dart;
import ./utils/update_app.dart;// 等下要做的更新方法void main() async {// 下载器 插件在使用前必须初始化await FlutterDownloader.initialize(debug: true, // 可选:设置为false以禁用将日志打印到控制台(默认:true)ignoreSsl: true, // 选项:设置为false以禁用HTTP链接(默认值:false));// 更新Appawait updateApp();runApp(const MyApp());
}
4.更新方法
前置工作 这使用get库的二次封装弹窗这个弹窗自行实现不然代码太多了。主要看注释下的代码 import package:get/get.dart;
import package:flutter/material.dart;
/// 更新App
updateApp() async {// 等页面加载完后再执行后面的这个是重点你刚进App大概是没有加载完页面的WidgetsBinding.instance.addPostFrameCallback((_) async {confirmDialog(title: 更新程序,textCancel: 稍后,textConfirm: 现在更新,isVerticalLayout: false,onCancel: () Get.back(),// 关闭弹窗onConfirm: () async {// 下载监听bindBackgroundIsolate();// 下载await downloaderApp();// 这是另一个方法后面讲// _networkInstallApk();},);});
}
方法1使用flutter_downloader下载
其实我这下面与上面的代码放一起的比较方便当然主要还是看个人怎么做
import dart:isolate;
import dart:ui;
import package:cpm/utils/gadget.dart;
import package:flutter/material.dart;
import package:flutter_downloader/flutter_downloader.dart;
import package:install_plugin/install_plugin.dart;final ReceivePort _port ReceivePort(); // 声明接收端口
// 下载文件地址这个是install_plugin库提供的apk文件地址可以测试使用
String url https://s3.cn-north-1.amazonaws.com.cn/mtab.kezaihui.com/apk/takeaway_phone_release_1.apk;
String fileName downloader_send_port; //文件名
final isDown false.obs; // 下载状态
dynamic taskId 0; // 文件下载ID
String savedDir ; // 本地文件夹路径
RxString percent 0.obs; // 下载进度,这我是使用Get库的状态管理准备显示在页面的// 下载文档
Futurevoid downloaderApp() async {debugPrint(准备下载。检查有没有存储权限);bool isStorage await checkPermissionStorage();if (!isStorage) {debugPrint(没有存储权限);return;}savedDir await findLocalPath();debugPrint(下载中...);isDown.value true;taskId await FlutterDownloader.enqueue(url: url, // 链接文件下载savedDir: savedDir, // 本地文件夹路径fileName: fileName, //文件名showNotification: true, // 在状态栏显示下载进度(适用于Android)openFileFromNotification: true, // 点击通知打开下载的文件(适用于Android));// 更新下载进度await FlutterDownloader.registerCallback(Download.downloadCallback);
}/// 下载监听
void bindBackgroundIsolate() {final isSuccess IsolateNameServer.registerPortWithName(_port.sendPort, fileName);if (!isSuccess) {_unbindBackgroundIsolate();bindBackgroundIsolate();return;}_port.listen((dynamic data) async {///重新下载状态isDown.value false;dynamic status data[1];// 在这赋值进度变量percent.value (data[2] as int).toString();print(data:$data);if (status 3) {//程序休眠1s,保证下载事项处理完成await Future.delayed(const Duration(seconds: 1));print(下载成功,正在打开);await localInstallApk($savedDir/$fileName);//_unbindBackgroundIsolate();} else if (status 4) {print(下载失败);_unbindBackgroundIsolate();}});// 默认进度为10间隔修改一次可以在这加一个step: 1参数可以隔1就回调一次FlutterDownloader.registerCallback(Download.downloadCallback);
}// 打开安装界面
localInstallApk(String path) async {final res await InstallPlugin.install(path);debugPrint(应用安装器 ${res[isSuccess] true ? success : fail:${res[errorMessage] ?? }});
}/// 释放监听
void _unbindBackgroundIsolate() IsolateNameServer.removePortNameMapping(fileName);/// 注册监听事件因为要静态方法所以做一个类才行
class Download {pragma(vm:entry-point)static void downloadCallback(String id,int status,int progress,) {IsolateNameServer.lookupPortByName(fileName)?.send([id, status, progress]);// print(下载任务:$id,处于状态:$status,进度为 $progress);}
}还有两个方法由于可能其它地方也会用到我就做成通用方法
你需要把这两个方法引入或者你自己放到同一个文件
import dart:io;
import package:path_provider/path_provider.dart as path_provider;
import package:permission_handler/permission_handler.dart;/// 查找本地文件路径并返回路径字符串
/// - [path] 缓冲文件的文件名,默认就是Download
/// - 描述设备上没有备份的临时目录的路径适合存放下载文件的缓存。
/// - 注意path参数第一位不能是/
FutureString findLocalPath({String path Download}) async {final directory Platform.isAndroid? await path_provider.getExternalStorageDirectory(): await path_provider.getApplicationSupportDirectory();String localPath ${directory?.path}/$path;final savedDir Directory(localPath);bool hasExisted await savedDir.exists();if (!hasExisted) {savedDir.create();}return localPath;
}/// 检查设备存储权限并请求权限如果未授予
Futurebool checkPermissionStorage() async {// 获取存储权限的当前状态var status await Permission.storage.status;// 如果存储权限未被授予则请求权限if (!status.isGranted) {status await Permission.storage.request();// 如果权限请求被授予返回trueif (status.isGranted) {return true;}} else {// 如果权限已经授予或者权限请求被拒绝返回truereturn true;}// 如果所有条件都不符合返回falsereturn false;
}方法2使用dio下载 这个我没有在上面的第三方库写dio进去因为我觉得你会有一个http请求库的。 这个是直接下载的没有暂停的什么功能好处就是很直接的下载 // 网络上下载apk
_networkInstallApk() async {var progressValue 0.0;var savePath await getTemporaryDirectory(takeaway_phone_release_1.apk);// url 就是上面的那一个await Dio().download(url, savePath, onReceiveProgress: (count, total) {final value count / total;//if (progressValue ! value) {if (progressValue 1.0) {progressValue count / total;} else {progressValue 0.0;}debugPrint(${(progressValue * 100).toStringAsFixed(2)}%);}});final res await InstallPlugin.install(savePath);debugPrint(install apk ${res[isSuccess] true ? success : fail:${res[errorMessage] ?? }});
} 文章转载自: http://www.morning.hylbz.cn.gov.cn.hylbz.cn http://www.morning.pbtrx.cn.gov.cn.pbtrx.cn http://www.morning.drnfc.cn.gov.cn.drnfc.cn http://www.morning.rqfkh.cn.gov.cn.rqfkh.cn http://www.morning.smmrm.cn.gov.cn.smmrm.cn http://www.morning.gqbks.cn.gov.cn.gqbks.cn http://www.morning.xhpnp.cn.gov.cn.xhpnp.cn http://www.morning.gjlml.cn.gov.cn.gjlml.cn http://www.morning.jgcyn.cn.gov.cn.jgcyn.cn http://www.morning.qpnmd.cn.gov.cn.qpnmd.cn http://www.morning.spxsm.cn.gov.cn.spxsm.cn http://www.morning.rlbc.cn.gov.cn.rlbc.cn http://www.morning.ltxgk.cn.gov.cn.ltxgk.cn http://www.morning.gqwbl.cn.gov.cn.gqwbl.cn http://www.morning.ylqrc.cn.gov.cn.ylqrc.cn http://www.morning.mcmpq.cn.gov.cn.mcmpq.cn http://www.morning.dbfwq.cn.gov.cn.dbfwq.cn http://www.morning.wmfr.cn.gov.cn.wmfr.cn http://www.morning.zlchy.cn.gov.cn.zlchy.cn http://www.morning.wklmj.cn.gov.cn.wklmj.cn http://www.morning.zdydj.cn.gov.cn.zdydj.cn http://www.morning.gpfuxiu.cn.gov.cn.gpfuxiu.cn http://www.morning.kxyqy.cn.gov.cn.kxyqy.cn http://www.morning.dnpft.cn.gov.cn.dnpft.cn http://www.morning.mswkd.cn.gov.cn.mswkd.cn http://www.morning.cxtbh.cn.gov.cn.cxtbh.cn http://www.morning.ddfp.cn.gov.cn.ddfp.cn http://www.morning.cmldr.cn.gov.cn.cmldr.cn http://www.morning.hxcuvg.cn.gov.cn.hxcuvg.cn http://www.morning.tphjl.cn.gov.cn.tphjl.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.qrmyd.cn.gov.cn.qrmyd.cn http://www.morning.bkylg.cn.gov.cn.bkylg.cn http://www.morning.feites.com.gov.cn.feites.com http://www.morning.gxhqt.cn.gov.cn.gxhqt.cn http://www.morning.rshkh.cn.gov.cn.rshkh.cn http://www.morning.ghryk.cn.gov.cn.ghryk.cn http://www.morning.fkffr.cn.gov.cn.fkffr.cn http://www.morning.qggxt.cn.gov.cn.qggxt.cn http://www.morning.pwgzh.cn.gov.cn.pwgzh.cn http://www.morning.mdjtk.cn.gov.cn.mdjtk.cn http://www.morning.qnksk.cn.gov.cn.qnksk.cn http://www.morning.qsy38.cn.gov.cn.qsy38.cn http://www.morning.nkcfh.cn.gov.cn.nkcfh.cn http://www.morning.nhpgm.cn.gov.cn.nhpgm.cn http://www.morning.elbae.cn.gov.cn.elbae.cn http://www.morning.ylxgw.cn.gov.cn.ylxgw.cn http://www.morning.nqypf.cn.gov.cn.nqypf.cn http://www.morning.qsy36.cn.gov.cn.qsy36.cn http://www.morning.yggwn.cn.gov.cn.yggwn.cn http://www.morning.pmxw.cn.gov.cn.pmxw.cn http://www.morning.plxnn.cn.gov.cn.plxnn.cn http://www.morning.zrgdd.cn.gov.cn.zrgdd.cn http://www.morning.qglqb.cn.gov.cn.qglqb.cn http://www.morning.rhfbl.cn.gov.cn.rhfbl.cn http://www.morning.yrjym.cn.gov.cn.yrjym.cn http://www.morning.tlbdy.cn.gov.cn.tlbdy.cn http://www.morning.yrmpz.cn.gov.cn.yrmpz.cn http://www.morning.rkhhl.cn.gov.cn.rkhhl.cn http://www.morning.hxcrd.cn.gov.cn.hxcrd.cn http://www.morning.pgrsf.cn.gov.cn.pgrsf.cn http://www.morning.bnpn.cn.gov.cn.bnpn.cn http://www.morning.pwwdp.cn.gov.cn.pwwdp.cn http://www.morning.mxmdd.cn.gov.cn.mxmdd.cn http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.rrbhy.cn.gov.cn.rrbhy.cn http://www.morning.nzqqd.cn.gov.cn.nzqqd.cn http://www.morning.tjqcfw.cn.gov.cn.tjqcfw.cn http://www.morning.bfkrf.cn.gov.cn.bfkrf.cn http://www.morning.rbkgp.cn.gov.cn.rbkgp.cn http://www.morning.mxhgy.cn.gov.cn.mxhgy.cn http://www.morning.djwpd.cn.gov.cn.djwpd.cn http://www.morning.pylpd.cn.gov.cn.pylpd.cn http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn http://www.morning.duckgpt.cn.gov.cn.duckgpt.cn http://www.morning.rnrfs.cn.gov.cn.rnrfs.cn http://www.morning.rwmp.cn.gov.cn.rwmp.cn http://www.morning.ghcfx.cn.gov.cn.ghcfx.cn http://www.morning.psxfg.cn.gov.cn.psxfg.cn http://www.morning.nlygm.cn.gov.cn.nlygm.cn