YSVersionView.dart 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import 'dart:io';
  2. import 'package:dio/dio.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:open_file/open_file.dart';
  5. import 'package:package_info/package_info.dart';
  6. import 'package:path_provider/path_provider.dart';
  7. import 'package:permission_handler/permission_handler.dart';
  8. import 'package:url_launcher/url_launcher_string.dart';
  9. import 'YSTools.dart';
  10. class YSVersionView extends StatefulWidget {
  11. final String content;
  12. final String url;
  13. const YSVersionView({Key? key, this.content = '', this.url = ''}) : super(key: key);
  14. @override
  15. YSVersionViewState createState() => YSVersionViewState();
  16. }
  17. class YSVersionViewState extends State<YSVersionView> {
  18. int _progress = 0;
  19. bool _isTap = false;
  20. @override
  21. Widget build(BuildContext context) {
  22. return WillPopScope(
  23. onWillPop: () async{
  24. return false;
  25. },
  26. child: Center(child: Container(
  27. height: hsp(330),
  28. width: ysWidth(context)-hsp(100),
  29. decoration: const BoxDecoration(
  30. color: Colors.white,
  31. borderRadius: BorderRadius.all(Radius.circular(5))
  32. ),
  33. padding: EdgeInsets.all(hsp(10)),
  34. child: Column(
  35. children: [
  36. Container(
  37. height: hsp(30),
  38. alignment: Alignment.center,
  39. child: centerAlertText('发现新版本', size: 18,
  40. color: Colors.black,line: 100),
  41. ),
  42. Container(
  43. height: hsp(230),
  44. alignment: Alignment.topLeft,
  45. padding: const EdgeInsets.only(bottom: 10),
  46. child: SingleChildScrollView(
  47. padding: EdgeInsets.all(hsp(5)),
  48. child: centerAlertText(widget.content, size: 15,
  49. color: const Color(0xFFAFAFAF),line: 100),
  50. ),
  51. ),
  52. GestureDetector(
  53. onTap: () async{
  54. if(_isTap)return;
  55. if(Platform.isAndroid==true){
  56. bool isPer = await _checkPermission();
  57. if(isPer==true){
  58. _isTap = true;
  59. _installApk(widget.url);
  60. }
  61. }else if(Platform.isIOS==true){
  62. launchUrlString(widget.url);
  63. }
  64. },
  65. behavior: HitTestBehavior.opaque,
  66. child: Container(
  67. height: hsp(40),
  68. margin: EdgeInsets.only(left: hsp(20),right: hsp(20)),
  69. decoration: const BoxDecoration(
  70. color: Color(0xFF146DFE),
  71. borderRadius: BorderRadius.all(Radius.circular(3))
  72. ),
  73. alignment: Alignment.center,
  74. child: centerAlertText('立即升级${_progress==0||_progress==100?'':' $_progress%'}',
  75. color: Colors.white, size: 15,),
  76. ),
  77. ),
  78. ],
  79. ),
  80. )),
  81. );
  82. }
  83. Future<bool> _checkPermission() async {
  84. if(Platform.isAndroid==true){
  85. if (await Permission.contacts.request().isDenied) {
  86. Map<Permission, PermissionStatus> statuses = await [
  87. Permission.storage,
  88. ].request();
  89. if(statuses[Permission.storage]!.isDenied){
  90. return false;
  91. }
  92. }
  93. }
  94. return true;
  95. }
  96. Future<File?> _downloadAndroid(String url) async {
  97. PackageInfo packageInfo = await PackageInfo.fromPlatform();
  98. /// 创建存储文件
  99. Directory? storageDir = await getExternalStorageDirectory();
  100. String storagePath = storageDir!.path;
  101. File file = File('$storagePath/${packageInfo.appName}v'
  102. '${packageInfo.buildNumber}.apk');
  103. if (!file.existsSync()) {
  104. file.createSync();
  105. }
  106. try {
  107. /// 发起下载请求
  108. Response response = await Dio().get(url,
  109. onReceiveProgress: showDownloadProgress,
  110. options: Options(responseType: ResponseType.bytes,followRedirects: false,
  111. ));
  112. file.writeAsBytesSync(response.data);
  113. return file;
  114. } catch (e) {
  115. return null;
  116. }
  117. }
  118. /// 安装apk
  119. Future<void> _installApk(String url) async {
  120. File? apkFile = await _downloadAndroid(url);
  121. String apkFilePath = apkFile!.path;
  122. if (apkFilePath.isEmpty) {
  123. return;
  124. }
  125. OpenFile.open(apkFilePath);
  126. }
  127. /// 展示下载进度
  128. void showDownloadProgress(num received, num total) {
  129. if (total != -1) {
  130. _progress = int.parse('${(received / total~/0.01)}');
  131. setState(() {});
  132. if(_progress==100){
  133. _isTap = false;
  134. }
  135. }
  136. }
  137. }
  138. centerAlertText(String text,{Color color = Colors.white,required int size,bool isBold = false,int line = 1}) {
  139. return Text(text,style: TextStyle(fontSize: zsp(size),color: color,decoration: TextDecoration.none,
  140. fontWeight: isBold?FontWeight.bold:FontWeight.normal,),maxLines: line,overflow: TextOverflow.ellipsis,);
  141. }