首先要知道一點,android和ios的升級方式是不同的,ios只能通過跳轉appstore或者fir的方式,但是android可以直接下載安裝的
第一步:我們有bugly賬號的直接去新建產品就好了.然後到產品設定頁面,複製app id
出來.初始化的時候要用到
第二步:配置grdle檔案 不過我們一般都是arm平臺的,我這裡只用到了arm,不需要適配太多
defaultConfig { ndk { //設定支援的SO庫架構 abiFilters 'armeabi-v7a'//, 'arm64-v8a', 'x86', 'x86_64' } }
引入外掛 dependencies: flutter_bugly: ^0.2.8 然後在程式的入口檔案main.dart中初始化
FlutterBugly.init(androidAppId: "your android app id",iOSAppId: "your iOS app id");
ios是熱修復的用不到的可以不填的
第三步:
這一步是要重點說一下,因為要是用過android 原生引入bugly升級的都知道,bugly什麼都幫你做好了,但是flutter是做不到的.我們要自己去寫彈框還有下載安裝的邏輯.
@overridevoid initState() { super.initState(); if (mounted && Platform.isAndroid) _checkUpgrade(); if (Platform.isIOS) _checkUpdateIos();}Future _checkUpdateIos() async { var response = await NetUtils.post(context, Api.checkUpdate, params: {'currentVersion': '1111'}); if (response['data'] != null) { var data = response['data']; _showUpdateDialog(data['updateContent'], data['newestVersion'], data['newestVersion'], true); } Logger().log(Level.info, 'response:$response');}void _showUpdateDialog(String versionname, String version, String url, bool isForceUpgrade) { showDialog( barrierDismissible: false, context: context, builder: (BuildContext context) { final data = UpdateVersion( appStoreUrl: 'https://fir.im/***', versionName: versionname, apkUrl: url, content: version); return UpdateVersionDialog(data: data); }, );}
updateversion這個元件的程式碼
這裡也用到了兩個依賴
一個是最常用的檢測許可權的
dependencies: permission_handler: ^4.0.0
另外一個也很常用,url_launcher 我們經常用到的打電話,發簡訊,跳轉到瀏覽器都是要用到這個東西的
dependencies: url_launcher: ^5.4.1
import 'dart:async';import 'dart:io';import 'dart:math';import 'dart:ui';import 'package:flutter/cupertino.dart';import 'package:flutter/material.dart';import 'package:flutter/services.dart';import 'package:permission_handler/permission_handler.dart';import 'package:url_launcher/url_launcher.dart';class UpdateVersion { final String appStoreUrl; final String apkUrl; final String versionName; final String content; UpdateVersion( {this.appStoreUrl, this.apkUrl, this.versionName, this.content});}class UpdateVersionDialog extends StatefulWidget { final UpdateVersion data; UpdateVersionDialog({Key key, this.data}) : super(key: key); @override _UpdateVersionDialogState createState() => _UpdateVersionDialogState();}class _UpdateVersionDialogState extends State<UpdateVersionDialog> { static const channelName = 'plugins.megstar.com/update_version'; static const stream = const EventChannel(channelName); // 進度訂閱 StreamSubscription downloadSubscription; int percent = 0; _updateButtonTap(BuildContext context) async { if (Platform.isIOS) { final url = widget.data.appStoreUrl; if (await canLaunch(url)) { await launch(url, forceSafariVC: false); } else { throw 'Could not launch $url'; } } else if (Platform.isAndroid) { androidDownloadHandle(); } } // android 下載 androidDownloadHandle() async { // 許可權檢查 Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions([PermissionGroup.storage]); print(permissions); if (permissions[PermissionGroup.storage] == PermissionStatus.granted) { // 開始下載 _startDownload(); } else { showSettingDialog(); } } // 開啟應用設定 showSettingDialog() { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( content: Text("需要開啟儲存許可權"), actions: <Widget>[ new FlatButton( onPressed: () { Navigator.of(context).pop(); }, child: new Text("取消"), ), new FlatButton( onPressed: () { PermissionHandler().openAppSettings(); Navigator.of(context).pop(); }, child: new Text("確認"), ), ], ); }); } // 開始下載 void _startDownload() { if (downloadSubscription == null) { downloadSubscription = stream .receiveBroadcastStream(widget.data.apkUrl) .listen(_updateDownload); } } // 停止監聽進度 void _stopDownload() { if (downloadSubscription != null) { downloadSubscription.cancel(); downloadSubscription = null; percent = 0; } } // 進度下載 void _updateDownload(data) { int progress = data["percent"]; if (progress != null) { setState(() { percent = progress; }); } } @override void dispose() { super.dispose(); _stopDownload(); } @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; var _maxContentHeight = min(screenSize.height - 300, 180.0); return Material( type: MaterialType.transparency, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( padding: EdgeInsets.only(top: 10), width: screenSize.height > screenSize.width ? 265 : 370, decoration: ShapeDecoration( color: Color(0xFFFFFFFF), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(6), )), child: Column(children: <Widget>[ ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(6.0), topRight: Radius.circular(6.0), ), child: Image.asset( "assets/images/update.png", height: 110, width: double.infinity, fit: BoxFit.contain, )), Padding( padding: const EdgeInsets.fromLTRB(0, 10, 0, 5), child: Center( child: new Text('升級到新版本', style: new TextStyle( fontSize: 17.0, fontWeight: FontWeight.w500, )))), Container( child: Text( widget.data.versionName, style: TextStyle( color: Color(0xff3782e5), fontWeight: FontWeight.w500), ), ), ConstrainedBox( constraints: BoxConstraints(maxHeight: _maxContentHeight), child: Container( padding: EdgeInsets.fromLTRB(20, 10, 20, 10), child: SingleChildScrollView( child: Text( widget.data.content, style: TextStyle(color: Colors.black87), ), ), ), ), Padding( padding: const EdgeInsets.fromLTRB(33, 0, 33, 0), child: Container( height: 1.0 / MediaQueryData.fromWindow(window).devicePixelRatio, color: Color(0xffC0C0C0), ), ), Padding( padding: const EdgeInsets.only(top: 10), child: SizedBox( width: 170, height: 40, child: RaisedButton( child: Text( _getButtonText(), style: TextStyle(color: Color(0xdfffffff)), ), color: const Color(0xff5f9afa), onPressed: () { _updateButtonTap(context); }, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.0))), ), ), Padding( padding: EdgeInsets.fromLTRB(0, 8, 0, 10), child: SizedBox( height: 30, child: FlatButton( onPressed: () { Navigator.pop(context); }, textColor: Colors.black26, color: Colors.transparent, highlightColor: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30)), child: Text( "暫不升級", style: TextStyle(fontSize: 13), )), )) ])) ])); } _getButtonText() { if (percent == 100) { return "正在升級"; } if (percent > 0) { return "升級中$percent%"; } return "立即升級"; }}
我這裡下載更新的邏輯是在原生程式碼裡面寫的,不懂得私聊我吧.我這裡先放張截圖
當你看到這個頁面,恭喜你,你已經成功引入了
最新評論