🆙🚀 Flutter application upgrade/ Flutter App Upgrade /Flutter App Update/Flutter Update / download Plug-in (with notice bar progress), supports full upgrade, hot update and incremental upgrade
Android and IOS upgrade plugin.
Android
Get user installed android stores.Android
Get version from android stores(only support GooglePlay、XiaoMi、Tencent)Android
Jump to store mode upgradeAndroid
Download APK using download link
Android
hot upgradeAndroid
increment upgradeIOS
Jump to Appstore upgrade according to appidIOS
Get the current online version of Appstore according to appidFor the development of this plug-in, I haven't had a good meal for a long time. I hope you can click on the sponsor and give a little bit of money. Thank you!
pubspec.yaml
dependencies:
r_upgrade: last version
void upgradeFromUrl()async{
bool isSuccess =await RUpgrade.upgradeFromUrl(
'https://www.google.com',
);
print(isSuccess);
}
void getAndroidStores() async {
final stores = await RUpgrade.androidStores;
}
void getVersionName() async {
final versionName = await RUpgrade.getVersionFromAndroidStore(AndroidStore.GOOGLE_PLAY);
}
void upgradeFromAndroidStore(){
bool isSuccess = await RUpgrade.upgradeFromAndroidStore(AndroidStore.GOOGLE_PLAY);
print('${isSuccess?'jump success':'jump error'}');
}
make sure your application had this permission and request dynamic permission.
<!--(if you want to upload google store,can not add this permission)-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!--(if you want to use silent install,need to add this permission,and app is system app-->
<uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
RUpgrade.stream.listen((DownloadInfo info){
///...
});
info:
param | desc |
---|---|
(int) id | download id |
(int) max_length | download max bytes length (bytes) |
(int) current_length | download current bytes length (bytes) |
(double) percent | download percent 0-100 |
(double) planTime | download plan time /s (X.toStringAsFixed(0)) |
(String) path | download file path |
(double) speed | download speed kb/s |
(DownloadStatus) status | download status STATUS_PAUSED STATUS_PENDING STATUS_RUNNING STATUS_SUCCESSFUL STATUS_FAILED STATUS_CANCEL |
This upgrade have two part.
useDownloadManager
:
true
: Use system DownloadManager
to download
RUpgrade.stream
、install
、cancel
false
: Use Service
download(default use)
RUpgrade.stream
、install
、cancel
// [installType] downloaded finish will use install type to install apk.
// [apkName] apk name (such as `release.apk`)
// [notificationVisibility] notification visibility.
// [notificationStyle] download notification show style about content text, only support [useDownloadManager]==false.
// [useDownloadManager] if true will use DownloadManager,false will use my service ,
// if true will no use [pause] , [upgradeWithId] , [getDownloadStatus] , [getLastUpgradedId] methods.
// [upgradeFlavor] you can use [RUpgradeFlavor.normal] , [RUpgradeFlavor.hotUpgrade] , [RUpgradeFlavor.incrementUpgrade] flavor
void upgrade() async {
int id = await RUpgrade.upgrade(
'https://raw.githubusercontent.com/rhymelph/r_upgrade/master/apk/app-release.apk',
apkName: 'app-release.apk', installType: RUpgradeInstallType.normal,);
}
New upgraded flavor:(no support use DownloadManager)
enum RUpgradeFlavor {
normal, // full upgrade
hotUpgrade, // hot upgrade
incrementUpgrade, // increment upgrade
}
void cancel() async {
bool isSuccess=await RUpgrade.cancel(id);
}
void install() async {
bool isSuccess=await RUpgrade.install(id);
}
void installByPath(String path) async {
bool isSuccess=await RUpgrade.installByPath(path);
}
/// [RUpgrade.upgradeWithId]、[RUpgrade.upgrade]、[RUpgrade.install]、[RUpgrade.installByPath]
enum RUpgradeInstallType {
normal,//normal install
silent,//silent install
none,// not install
}
void pause() async {
bool isSuccess=await RUpgrade.pause(id);
}
void pause() async {
bool isSuccess=await RUpgrade.upgradeWithId(id);
/// return true.
/// * if download status is [STATUS_PAUSED] or [STATUS_FAILED] or [STATUS_CANCEL], will restart running.
/// * if download status is [STATUS_RUNNING] or [STATUS_PENDING], nothing happened.
/// * if download status is [STATUS_SUCCESSFUL] , will install apk.
///
/// return false.
/// * if not found the id , will return [false].
}
void getLastUpgradeId() async {
int id = await RUpgrade.getLastUpgradedId();
}
void getDownloadStatus()async{
DownloadStatus status = await RUpgrade.getDownloadStatus(id);
}
./bsdiff old.apk new.apk increment.patch
increment.patch
Upload to serverRUpgrade.upgrade(...,upgradeFlavor:RUpgradeFlavor.incrementUpgrade)
download fileRUpgrade.install(id)
install apk.The code is as follows:
int id;
void incrementUpgrade(){
id = await RUpgrade.upgrade(
'https://mydata-1252536312.cos.ap-guangzhou.myqcloud.com/r_upgrade.patch',
fileName: 'r_upgrade.patch',
useDownloadManager: false,
installType: RUpgradeInstallType.none,
upgradeFlavor: RUpgradeFlavor.incrementUpgrade,
);
}
void install(){
try {
await RUpgrade.install(id);
} catch (e) {
_state.currentState
.showSnackBar(SnackBar(content: Text('failure!')));
}
}
flutter build bundle
generate. flutter build bundle
|- AssetManifest.json
|- FontManifest.json
|- fonts
|- ...
|- isolate_snapshot_data *
|- kernel-blob.bin *
|- LICENSE
|- packages
|- ...
|- vm_snapshot_data *
RUpgrade.upgrade(...,upgradeFlavor:RUpgradeFlavor.hotUpgrade)
download file.id
to hot upgrade bool isSuccess = await RUpgrade.install(id);
if (isSuccess) {
_state.currentState
.showSnackBar(SnackBar(content: Text('Hot update succeeded, exit the application after 3S, please enter again')));
Future.delayed(Duration(seconds: 3)).then((_){
SystemNavigator.pop(animated: true);
});
}else{
_state.currentState
.showSnackBar(SnackBar(content: Text('Hot update failed, please wait for update package download to complete')));
}
At present, the hot update is still in the testing stage, only supporting the change of the flutter code, not supporting the resource file, etc. the author of the plug-in is not responsible for all the consequences caused by the hot update, and the user is responsible for it.
If you want to customize the content displayed in the download notification bar, you can do so, modify or add files project/android/app/main/res/values/r_upgrade_value.xml
,add the following code
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="r_upgrade_download_speech">%.0f kb/s</string>
<string name="r_upgrade_download_planTime">%.0fs left</string>
<string name="r_upgrade_download_finish">Download finished</string>
<string name="r_upgrade_download_paused">Download paused</string>
<string name="r_upgrade_download_failed">Download failed</string>
</resources>
And then.When you use upgrade
method,you should set the notificationStyle
param.
/// Notification show style about content text
enum NotificationStyle {
speechAndPlanTime, // 100kb/s 1s left
planTimeAndSpeech, // 1s left 100kb/s
speech,// 100kb/s
planTime, // 1s left
none, //
}
void upgradeFromAppStore() async {
bool isSuccess =await RUpgrade.upgradeFromAppStore(
'your AppId',//such as:WeChat AppId:414478124
false
);
print(isSuccess);
}
void getVersionFromAppStore() async {
String versionName = await RUpgrade.getVersionFromAppStore(
'your AppId',//such as:WeChat AppId:414478124
false
);
print(versionName);
}
Copyright 2021 rhymelph
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.