准备工作
遇到问题
flutter_bugly
这个方法FlutterBugly. checkUpgrade ( isManual: true , isSilence: true ) , UpgradeInfo 一直返回null。
下面是打印出来的log
D/ CrashReport ( 31776 ) : [ Upload] Bugly version from headers is: bugly/ 1.0
D/ CrashReport ( 31776 ) : [ Upload] Status from server is 0 ( pid= 31776 | tid= 31843 ) .
D/ CrashReport ( 31776 ) : [ Upload] Received 127 bytes
D/ CrashReport ( 31776 ) : [ Util] Unzip 111 bytes data with type Gzip
D/ CrashReport ( 31776 ) : [ Upload] Response cmd is: 0 , length of sBuffer is: 0
D/ CrashReport ( 31776 ) : [ Database] insert t_pf success.
I/ CrashReport ( 31776 ) : [ Upload] Success: 804
D/ CrashReport ( 31776 ) : [ UploadManager] Local network consume: 30 KB
D/ CrashReport ( 31776 ) : [ Database] deleted t_lr data 1
D/ CrashReport ( 31776 ) : [ Database] insert t_lr success.
D/ CrashReport ( 31776 ) : [ UploadManager] Network total consume: 31 KB
I/ CrashReport ( 31776 ) : upload succ: [ 804 ] [ sended 775 ] [ recevied 127 ]
I/ CrashReport ( 31776 ) : 你已放弃让SDK来处理策略
I/ CrashReport ( 31776 ) : betaStrategy is null
I/ CrashReport ( 31776 ) : 用户自定义activity,创建task失败 [ strategy: null]
解决方案: 在本地打包设置版本名称和版本号 pubspec.yaml ,打包上传到腾讯bugly 应用升级里面 上传的构建版本必须比本地的大,把本地版本更改回去1.0.0+1 继续测试升级功能,就能获取到。
flutter_bugly 和 open_file AndroidManifest.xml 合并冲突报错
仔细查看open_file readme 在 /android/app/src/main/AndroidManifest.xml 添加
< manifest xmlns: android= "http://schemas.android.com/apk/res/android"
xmlns: tools= "http://schemas.android.com/tools"
package = "xxx.xxx.xxxxx" >
< application>
. . .
< provider
android: name= "androidx.core.content.FileProvider"
android: authorities= "${applicationId}.fileProvider"
android: exported= "false"
android: grantUriPermissions= "true"
tools: replace= "android:authorities" >
< meta- data
android: name= "android.support.FILE_PROVIDER_PATHS"
android: resource= "@xml/filepaths"
tools: replace= "android:resource" / >
< / provider>
< / application>
< / manifest>
app-update.dart
import 'package:ZyFlutter/utils/update_dialog.dart' ;
import 'package:flutter/material.dart' ;
import 'package:flutter_bugly/flutter_bugly.dart' ;
import 'package:open_file/open_file.dart' ;
import 'package:permission_handler/permission_handler.dart' ;
import 'package:path_provider/path_provider.dart' ;
import 'package:uuid/uuid.dart' ;
import 'package:dio/dio.dart' ;
import 'package:fluttertoast/fluttertoast.dart' ;
class AppUpdate {
String _platformVersion = 'Unknown' ;
GlobalKey< UpdateDialogState> _dialogKey = new GlobalKey ( ) ;
initUpgradeApp ( BuildContext context) {
FlutterBugly. init (
androidAppId: '' ,
iOSAppId: '' ,
) . then ( ( _result) {
_platformVersion = _result. message;
FlutterBugly. setUserId ( '' ) ;
FlutterBugly. putUserData ( key: 'name' , value: 'zhoukai' ) ;
int tag = 9527 ;
FlutterBugly. setUserTag ( tag) ;
checkUpgrade ( context) ;
} ) ;
}
void showUpdateDialog (
String version,
String url,
bool isForceUpgrade,
String title,
int fileSize,
int pubTime,
String content,
BuildContext contex) {
showDialog (
context: contex,
barrierDismissible: false ,
builder: ( _) = > _buildDialog ( version, url, isForceUpgrade, title,
fileSize, pubTime, content, contex) ) ;
}
Widget _buildDialog (
String version,
String url,
bool isForceUpgrade,
String title,
int fileSize,
int pubTime,
String content,
BuildContext context) {
return WillPopScope (
onWillPop: ( ) async = > isForceUpgrade,
child: UpdateDialog (
key: _dialogKey,
version: version,
title: title,
content: content,
pubTime: pubTime,
fileSize: fileSize,
onClickWhenDownload: ( _msg) {
Fluttertoast. showToast ( msg: _msg) ;
} ,
onClickWhenNotDownload: ( ) {
requestPermiss ( context) . then ( ( value) {
if ( value) {
getPhoneLocalPath ( context) . then ( ( result) {
var uuid = Uuid ( ) ;
String name = uuid. v4 ( ) . replaceAll ( '-' , '' ) ;
String appName = '${result}/${name}.apk' ;
downApk ( url, appName) ;
} ) ;
}
} ) ;
} ,
) ,
) ;
}
void downApk ( String url, String localPath) {
var dio = new Dio ( ) ;
try {
dio. download ( url, localPath, onReceiveProgress: ( received, total) {
double progress = received / total;
_updateProgress ( received / total) ;
if ( progress == 1 ) {
OpenFile. open ( localPath) ;
}
} ) ;
} catch ( err ) {
Fluttertoast. showToast ( msg: '下载失败!!!' ) ;
}
}
void _updateProgress ( _progress) {
_dialogKey. currentState. progress = _progress;
}
void checkUpgrade ( BuildContext context) {
print ( '获取更新中.....' ) ;
FlutterBugly. checkUpgrade ( ) . then ( ( UpgradeInfo info) {
print ( info) ;
print ( '*********************检查版本' ) ;
if ( info != null && info. id != null) {
print ( "----------------${info.apkUrl}" ) ;
showUpdateDialog (
info. versionName,
info. apkUrl,
info. upgradeType == 2 ,
info. title,
info. fileSize,
info. publishTime,
info. newFeature,
context,
) ;
}
} ) ;
}
Future requestPermiss ( BuildContext context) async {
var status = await Permission. storage. status;
if ( ! status. isGranted) {
Map< Permission, PermissionStatus> statuses =
await [ Permission. storage] . request ( ) ;
if ( ! statuses[ Permission. storage] . isGranted) {
Fluttertoast. showToast ( msg: '请打开存储权限!!!' ) ;
openAppSettings ( ) ;
return false ;
} else {
return true ;
}
} else {
return true ;
}
}
Future< String> getPhoneLocalPath ( BuildContext context) async {
final directory = Theme. of ( context) . platform == TargetPlatform. android
? await getExternalStorageDirectory ( )
: await getApplicationDocumentsDirectory ( ) ;
return directory. path;
}
}
update_dialog.dart
import 'package:flutter/material.dart' ;
class UpdateDialog extends StatefulWidget {
final key;
final version;
final String title;
final int fileSize;
final int pubTime;
final String content;
final Function onClickWhenDownload;
final Function onClickWhenNotDownload;
UpdateDialog ( {
this . key,
this . version,
this . title,
this . content,
this . fileSize,
this . pubTime,
this . onClickWhenDownload,
this . onClickWhenNotDownload,
} ) ;
@override
State< StatefulWidget> createState ( ) = > new UpdateDialogState ( ) ;
}
class UpdateDialogState extends State < UpdateDialog> {
var _downloadProgress = 0.0 ;
@override
Widget build ( BuildContext context) {
var _textStyle =
new TextStyle ( color: Theme. of ( context) . textTheme. body1. color) ;
return new AlertDialog (
title: new Text (
widget. title,
style: _textStyle,
) ,
content: _downloadProgress == 0.0
? new Text (
"版本${widget.version}\n${widget.content}" ,
style: _textStyle,
)
: new LinearProgressIndicator (
value: _downloadProgress,
) ,
actions: < Widget> [
new FlatButton (
child: new Text (
'更新' ,
style: _textStyle,
) ,
onPressed: ( ) {
if ( _downloadProgress != 0.0 ) {
widget. onClickWhenDownload ( "正在更新中" ) ;
return ;
}
widget. onClickWhenNotDownload ( ) ;
} ,
) ,
new FlatButton (
child: new Text ( '取消' ) ,
onPressed: ( ) {
Navigator. of ( context) . pop ( ) ;
} ,
) ,
] ,
) ;
}
set progress ( _progress) {
setState ( ( ) {
_downloadProgress = _progress;
if ( _downloadProgress == 1 ) {
Navigator. of ( context) . pop ( ) ;
_downloadProgress = 0.0 ;
}
} ) ;
}
}