1. 應用程序升級流程
由於在 IOS 中沒法直接下載安裝,如果版本不一致則直接跳轉到IOS應用對應的應用市場就可以了,所以本文僅介紹Android App的升級流程。
Android App升級流程:
1. 獲取本地版本號;
2. 請求服務器獲取服務器版本號;
3. 如果本地版本和服務器版本不一致則提示升級,彈窗提示用戶是否更新;
4. 用戶確定升級,調用文件傳輸方法下載apk文件;
5. 監聽下載進度;
6. 下載完成打開apk進行安裝。
2. Android 升級 App 涉及的 API 庫
3. 獲取版本信息
https://pub.flutter-io.cn/packages/package_info
1. 安裝插件
dependencies:
package_info: ^0.4.3+4
在pubspec.yaml中配置保存後,在VS Code環境中會自動下載依賴包。
如果無法正常下載,執行 flutter pub get 。
2. 引入並使用
// 引入獲取版本信息包
import 'package:package_info/package_info.dart';
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
// 應用名稱
print("appName:${appName}");
// 包名稱
print("packageName:${packageName}");
// 版本號
print("version:${version}");
// 構建編號
print("buildNumber:${buildNumber}");
4. 獲取文件存儲路徑
https://pub.flutter-io.cn/packages/path_provider
1. 安裝插件
dependencies:
path_provider: ^1.6.27
在pubspec.yaml中配置保存後,在VS Code環境中會自動下載依賴包。
如果無法正常下載,執行 flutter pub get 。
2. 引入並使用
// 引入獲取文件存儲路徑的包
import 'package:path_provider/path_provider.dart';
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
var directory = await getExternalStorageDirectory();
String storageDirectory = directory.path;
// 獲取臨時目錄
print("tempPath:${tempPath}");
// 獲取應用的安裝目錄
print("appDocDir:${appDocPath}");
// 獲取存儲卡的路徑
print("StorageDirectory:${storageDirectory}");
5. 文件下載
https://pub.flutter-io.cn/packages/flutter_downloader
1. 安裝插件
dependencies:
flutter_downloader: ^1.5.2
在pubspec.yaml中配置保存後,在VS Code環境中會自動下載依賴包。
如果無法正常下載,執行 flutter pub get 。
2. 配置權限
代碼如下:
<!-- 配置下載與安裝相關的權限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
其它配置:
代碼如下:
<!-- 處理在Android上打開下載文件的通知上的點擊操作-->
<provider
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
android:authorities="${applicationId}.flutter_downloader.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
<!-- 配置最大併發任務數:插件依賴於WorkManager庫 -->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
<provider
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
android:authorities="${applicationId}.flutter-downloader-init"
android:exported="false">
<!-- 設定數字以配置最大併發任務數 -->
<meta-data
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
android:value="5" />
</provider>
3. 引入並使用
// 引入獲取文件路徑的包(提前安裝)
import 'package:path_provider/path_provider.dart';
// 引入文件下載的包
import 'package:flutter_downloader/flutter_downloader.dart';
// 獲取存儲卡的路徑
final directory = await getExternalStorageDirectory();
String _localPath = directory.path;
await FlutterDownloader.enqueue(
// 遠程的APK地址(注意:安卓9.0以上後要求用https)
url: "http://www.ionic.wang/shop.apk",
// 下載保存的路徑
savedDir: _localPath,
// 是否在手機頂部顯示下載進度(僅限安卓)
showNotification:true,
// 是否允許下載完成點擊打開文件(僅限安卓)
openFileFromNotification:true,
);
FlutterDownloader.registerCallback((id, status, progress){
print(status);
print(progress);
});
6. 打開文件
https://pub.flutter-io.cn/packages/open_file
1. 安裝插件
dependencies:
open_file: ^3.0.3
在pubspec.yaml中配置保存後,在VS Code環境中會自動下載依賴包。
如果無法正常下載,執行 flutter pub get 。
2. 引入並使用
// 引入打開文件的包
import 'package:open_file/open_file.dart';
// 引入獲取文件路徑的包(提前安裝)
import 'package:path_provider/path_provider.dart';
// 獲取存儲卡的路徑
final directory = await getExternalStorageDirectory();
String _localPath = directory.path;
// 打開文件,apk的名稱需要與下載時對應
OpenFile.open("${_localPath}/shop.apk");
7. 替換版本
安裝包下載安裝後,默認會生成一個新的版本,並不會覆蓋原有的應用程序,爲此,需要提前做一些版本號的配置。
<!-- android/app/src/min/AndroidManifest.xml -->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my_app"
android:versionCode="2"
android:versionName="0.0.2">
......
</manifest>
上面的代碼在打包時,注意事項如下:
1. package的值不能變,即包名不能變;
2. android:versionCode的值要增加;
3. android:versionName的值要增加。
另外,上面代碼中配置的版本號在 package_info 這個插件中是無法獲取的,所以還需要在pubspec.yaml配置同樣的版本信息,這樣才能獲取版本信息進行對比。
# pubspec.yaml
version: 0.0.2+2
上面的代碼中0.0.2對應的是android:versionName的值,+2對應的是android:versionCode的值。
完成上面這些步驟,就可以開始開始正式打包了。