flutter实现APP版本更新(全局弹窗overlay实现)

2023-11-01

升级说明:
Android:应用内更新下载+安装。iOS:跳转到appstore下载安装。
注:可以通过热更新技术进行升级(我不会)。
引用插件:

  #获取当前版本
  package_info: ^0.4.3+2
  #版本内更新
  ota_update: ^2.4.1
  #网页打开工具
  url_launcher: ^5.7.10
  #事件车
  event_bus: ^1.1.1

直接上代码:

class VersionUpdate {
  ///检查是否需要更新
  ///是否需要升级--判断
  static Future<bool> isUpdating() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    String localVersion = packageInfo.version;
    SpUtil.putString('localVersion', localVersion);
    ApiResponse<VersionEntity> res =
        await PersonalCenterAPI.updatingVersion(versionNo: packageInfo.version);
    if (res.status == Status.COMPLETED) {
      //如果获取服务器的版本号与当前应用程序的版本号对比,,不等那么提示升级(判断条件修改为符合自己的)
      SpUtil.putObject('netVersionInfo', res.data.toJson());
      if (res.data.currentVersion != localVersion) {
        BottomSheetDialog.overLayDialog();
      }
    }
    //return isUpdating;
  }

  ///android--去android应用内下载更新  ---ios跳去App Store
  static downloadNewVersion({String Url}) async {
    if (Platform.isIOS) {
      String url = Url;
      if (await canLaunch(url)) {
        await launch(url);
      } else {
        throw 'Could not launch $url';
      }
    } else if (Platform.isAndroid) {
      String url = Url;
      try {
        // destinationFilename 是对下载的apk进行重命名
        OtaUpdate().execute(url, destinationFilename: 'gzzoc.apk').listen(
          (OtaEvent event) {
            switch (event.status) {
              case OtaStatus.DOWNLOADING: // 下载中
                //TestEventBus().bus.fire(ProgressEvent(data: event.value));
                ProgressEventBus().bus.fire(ProgressEvents(data: event.value));
                print('status:${event.status},value:${event.value}');
                break;
              case OtaStatus.INSTALLING: //安装中
                break;
              case OtaStatus.PERMISSION_NOT_GRANTED_ERROR: // 权限错误
                print('更新失败');
                break;
              default: // 其他问题
                break;
            }
          },
        );
      } catch (e) {
        print('更新失败');
      }
    }
  }
}

overLayDialog

overLayDialog() {
    OverlayState overlayState = Application.globalKey.currentState.overlay;
    OverlayEntry overlayEntry;
    overlayEntry = new OverlayEntry(builder: (context) {
      return OverLayDialog(
        overlayEntry: overlayEntry,
      );
    });
    overlayState.insert(overlayEntry);
  }

OverLayDialog名字太像了(忘记改了)

class OverLayDialog extends StatefulWidget {
 final OverlayEntry overlayEntry;

 OverLayDialog({this.overlayEntry});

 @override
 _OverLayDialogState createState() => _OverLayDialogState();
}

class _OverLayDialogState extends State<OverLayDialog> {
 VersionEntity _netVersionInfo;
 String _progress;
 @override
 void initState() {
   // TODO: implement initState
   super.initState();
   _netVersionInfo =
       VersionEntity.fromJson(SpUtil.getObject('netVersionInfo'));
   ProgressEventBus().bus.on<ProgressEvents>().listen((event) {
     if (!mounted) return;
     setState(() {
       _progress = event.data;
     });
   });
 }

 @override
 Widget build(BuildContext context) {
   return Material(
     color: MyColors.black_cc00,
     child: Container(
         margin: EdgeInsets.symmetric(horizontal: 40),
         child: Center(
           child: Column(
             mainAxisSize: MainAxisSize.min,
             children: [
               Stack(
                 alignment: Alignment.bottomCenter,
                 children: [
                   Stack(
                     children: [
                       Image.asset(
                         'assets/images/version_update.png',
                       ),
                       Container(
                         margin: EdgeInsets.only(top: 60),
                         padding: EdgeInsets.symmetric(horizontal: 20),
                         child: Column(
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
                             Text(
                               '发现新版本',
                               style: TextStyle(
                                   color: MyColors.white,
                                   fontWeight: FontWeight.bold,
                                   fontSize: 21),
                             ),
                             Text('版本:${_netVersionInfo.currentVersion}',
                                 style: TextStyle(
                                     color: MyColors.white, fontSize: 16)),
                             Container(
                               height: MediaQuery.of(context).size.height / 3,
                               padding: EdgeInsets.only(top: 22, bottom: 22),
                               child: ListView.builder(
                                   // itemCount: _content.length,
                                   itemCount: _netVersionInfo?.description
                                       ?.split(';')
                                       ?.length,
                                   itemBuilder: (context, index) {
                                     return Padding(
                                       padding:
                                           EdgeInsets.symmetric(vertical: 7),
                                       child: Text(
                                         _netVersionInfo?.description
                                             ?.split(';')[index],
                                         style: TextStyle(
                                             color: MyColors.white,
                                             fontSize: 15),
                                       ),
                                     );
                                   }),
                             )
                           ],
                         ),
                       ),
                     ],
                   ),
                   Column(
                     children: [
                       _progress == null
                           ? SizedBox.shrink()
                           : Text(
                               '$_progress%',
                               style: TextStyle(
                                   color: MyColors.white, fontSize: 12),
                             ),
                       InkWell(
                         onTap: () {
                           if (_progress == null) {
                             VersionUpdate.downloadNewVersion(
                                 Url: _netVersionInfo?.url);
                             //'https://itunes.apple.com/cn/app/id414478124'
                           }
                         },
                         child: Container(
                           margin: EdgeInsets.only(
                               left: 20, right: 20, top: 5, bottom: 15),
                           decoration: BoxDecoration(
                             color: MyColors.white,
                             borderRadius:
                                 BorderRadius.all(Radius.circular(50)),
                           ),
                           child: Row(
                             mainAxisAlignment: MainAxisAlignment.center,
                             children: [
                               Container(
                                 padding: EdgeInsets.symmetric(vertical: 10),
                                 child: Text(
                                   '立刻升级',
                                   style: TextStyle(
                                       color: MyColors.yellow_17,
                                       fontSize: 17,
                                       fontWeight: FontWeight.bold),
                                 ),
                               )
                             ],
                           ),
                         ),
                       )
                     ],
                   )
                 ],
               ),
               SizedBox(
                 height: 14,
               ),
               _netVersionInfo?.forceFlag == '1'
                   ? SizedBox.shrink()
                   : InkWell(
                       onTap: () {
                         widget?.overlayEntry?.remove();
                       },
                       child: Icon(
                         Icons.cancel_outlined,
                         color: MyColors.white,
                         size: 30,
                       ),
                     )
             ],
           ),
         )),
   );
 }
}
使用:我是在闪屏页的初始化中调用的,按照自己的需求改就行
   //版本更新
   VersionUpdate.isUpdating();

说明:SpUtil.putString是个工具,就是存储本地版本号而已,改SharedPreferences去存就行。
Application.globalKey.currentState.overlay:

class Application {
  /// 全局key
  static final GlobalKey<NavigatorState> globalKey =
      GlobalKey<NavigatorState>();

注:适合刚入门看。缺少什么或者不懂的可以留言我补。刚接触flutter不久,各位指导指导。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flutter实现APP版本更新(全局弹窗overlay实现) 的相关文章

随机推荐

  • IRQL的理解和认识

    介绍 中断请求 IRQ Interrupt Request 一般有两种 一种是外部中断 也就是硬件产生的中断 例如 键盘中断 打印机中断 定时器中断 另一种是由软件指令 int n 产生的中断 例如 INT 3 断点中断 INT 1 单步中
  • (附源码)springboot+mysql+基于Java web的电动车销售平台 毕业设计201524

    电动车销售平台的设计与实现 摘 要 信息化社会内需要与之针对性的信息获取途径 但是途径的扩展基本上为人们所努力的方向 由于站在的角度存在偏差 人们经常能够获得不同类型信息 这也是技术最为难以攻克的课题 针对电动车销售平台等问题 对电动车销售
  • ES系列--分析器

    一 前言 ES进行文档分析就会涉及到分析器 无论是内置的分析器 还是自定义的分析器 都是由一个分词器 tokenizers 0或多个词项过滤器 token filters 0或多个字符过滤器 character filters 组成 二 内
  • 数据结构基本概念、线性表、顺序表

    一 头文件 head h ifndef HEAD H define HEAD H include
  • 蓝桥杯每日一题(30)单词分析(python)

    Topic 试题 G 单词分析 时间限制 1 0s 内存限制 512 0MB 本题总分 20 分 问题描述 小蓝正在学习一门神奇的语言 这门语言中的单词都是由小写英文字母组成 有些单词很长 远远超过正常英文单词的长度 小蓝学了很长时间也记不
  • 简述前端MVVM框架

    一张图说明 1 一句话总结 vm层 视图模型层 通过接口从后台m层 model层 请求数据 vm层继而和v view层 实现数据的双向绑定 2 mvc和mvvm的关系 c 控制层 被换成了vm viewmodel 层 MVVM是Model
  • TypeScript 总结

    文章目录 TypeScript 总结 概述 运行ts文件 方式一 方式二 基础 声明变量 类型 数组 元组 联合类型 取值限制 枚举类型 any unknown void undefined 类型适配 面向对象 函数 普通函数 箭头函数 可
  • 2.2-base-num-str

    for i in range 9 0 1 for j in range 1 i 1 print f j i str i j ljust 2 end print 1 9 9 2 9 18 3 9 27 4 9 36 5 9 45 6 9 54
  • 网络设备自动化运维工具——ansible入门笔记

    Ansible概述 Ansible是一款自动化运维工具 基于Python开发 集合了众多运维工具 Puppet CFengine Chef SaltStack 的优点 实现了批量系统配置 批量程序部署 批量运行命令等功能 Ansible是基
  • 管理者一定要戒掉这五个毛病,否则迟早被淘汰出局

    在职场中 很多人都想升职加薪 但是不是每个人都有能力当一个好的领导 有的人不断的为之努力 有的好不容易当上了领导 可以结果时间不长反而被辞退 并不是他们不够努力 而是当员工和领导有很大的差别 你的思维要及时调整 如果思维还停留在以前 那么只
  • rsyslog无法发送日志到server端问题定位

    问题描述 网络正常的情况下 代码端中使用openlog无法正常将日志发往syslog服务器 即使使用logger也无法正常发送 环境 ARM设备充当client端 pc虚拟机Ubuntu充当server端 验证方式 通过wireshark抓
  • 基于AF的HTTP

    搬搬砖头而已 iOS 基于AF的HTTP请求类 OKHTTPRequestManager h OKHTTPRequestManager h LL Created by Morris on 2020 9 22 Copyright 2020 L
  • 蓝桥杯训练——最小乘积(基本型)

    试题 算法训练 最小乘积 基本型 资源限制 时间限制 1 0s 内存限制 512 0MB 问题描述 给两组数 各n个 请调整每组数的排列顺序 使得两组数据相同下标元素对应相乘 然后相加的和最小 要求程序输出这个最小值 例如两组数分别为 1
  • Java设计模式——单例模式

    文章目录 为什么要用单例模式 单例模式 饿汉式 DCL 静态内部类 为什么要用单例模式 单例对象 Singleton 是一种常用的设计模式 在Java应用中 单例对象能保证在一个JVM中 该对象只有一个实例存在 这样的模式有几个好处 某些类
  • 大数相加和大数相乘

    1 大数相加 int或者long类型的数据往往满足不了数据容量的要求 这时需要用到数组或者字符串进行操作 考虑到数据的位数并不是一个确定的值 运用string来处理可以简化思维 在进行运算之前 需要明确下面几点要求 1 将两组数据中位数大的
  • vue单页面给页面添加锚点实现锚点跳转

    使用Element scrollIntoView 详情情查看 scrollIntoView 参数 alignToTop可选 一个Boolean值 如果为true 元素的顶端将和其所在滚动区的可视区域的顶端对齐 相应的 scrollIntoV
  • 虚拟专用网拨号出现错误提示:没有设置允许基本路由封装GRE协议数据包通过-原因解决方法

    今天给用户配置虚拟专用网拨号到单位的服务器 操作系统为win10 执行拨号后 提示上面的信息经过百度搜索 发现这个问题和网络运营商有关系 因为你使用的是移动或联通宽带 服务商阻止了虚拟专用网通道 只要换电信宽带就好了 恰巧就是使用了联通的移
  • C语言工资管理系统

    include
  • 03.前后端分离中台框架 zhontai 项目代码生成器的使用

    zhontai 项目 基于 Net7 x Vue 等技术的前后端分离后台权限管理系统 想你所想的开发理念 希望减少工作量 帮助大家实现快速开发 后端地址 https github com zhontai Admin Core 前端地址 ht
  • flutter实现APP版本更新(全局弹窗overlay实现)

    升级说明 Android 应用内更新下载 安装 iOS 跳转到appstore下载安装 注 可以通过热更新技术进行升级 我不会 引用插件 获取当前版本 package info 0 4 3 2 版本内更新 ota update 2 4 1