Flutter 实现安卓端更新功能,一般需要以下几个步骤:
1. 获取当前应用的版本信息,比如版本号(versionCode)和版本名(versionName)。
2. 与服务器进行比对,检查是否有新版本的更新。
3. 如果有新版本,下载并安装更新包。
以下是具体的代码实现过程:
1. 获取当前应用的版本信息
我们可以使用 package_info 插件来获取当前应用的版本信息。在 pubspec.yaml 文件中添加依赖:
dependencies:
package_info: ^0.4.0
在代码中引入插件,并获取版本信息:
import 'package:package_info/package_info.dart';
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String packageName = packageInfo.packageName;
String versionName = packageInfo.version;
int versionCode = int.parse(packageInfo.buildNumber);
2. 与服务器进行比对,检查是否有新版本的更新
我们需要在服务器端维护一个版本信息文件,用来记录最新版本的版本号和下载地址等信息。通常我们会使用 JSON 格式来保存版本信息。下面是一个版本信息文件示例:
{
"versionCode": 2,
"versionName": "1.1.0",
"downloadUrl": "http://example.com/update.apk",
"changelog": "1. 修复了已知的 bug"
}
2. 增加了新功能
我们可以使用 http 插件来获取版本信息文件中的内容。在 pubspec.yaml 文件中添加依赖:
dependencies:
http: ^0.13.3
在代码中引入插件,并发起 http 请求获取版本信息文件内容:
import 'dart:convert';
import 'package:http/http.dart' as http;
try {
var response = await http.get(Uri.parse('http://example.com/version.json'));
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
int newVersionCode = data['versionCode'];
if (newVersionCode > versionCode) {
String newVersionName = data['versionName'];
String downloadUrl = data['downloadUrl'];
String changelog = data['changelog'];
// ...
} else {
// 已经是最新版本
}
} else {
// 请求失败
}
} catch (e) {
// 请求出现异常
}
3. 下载并安装更新包
如果有新版本更新,我们需要下载并安装更新包。通常我们会在应用的内部存储空间中创建一个文件夹来保存更新包。在 Android 系统中,可以使用 Intent.ACTION_VIEW 意图来启动系统自带的安装器来安装 APK 文件。以下是具体的代码实现:
import 'package:path_provider/path_provider.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
// 获取应用内部存储空间中的文件夹路径
String getDownloadDirectory() {
String directory = '';
if (Platform.isAndroid) {
directory = '/storage/emulated/0/Android/data/${packageName}/files/Download';
} else if (Platform.isIOS) {
directory = (await getApplicationSupportDirectory()).path;
}
return directory;
}
FlutterDownloader.initialize();
final taskId = await FlutterDownloader.enqueue(
url: downloadUrl,
savedDir: getDownloadDirectory(),
showNotification: true,
openFileFromNotification: true,
);
// 启动安装器安装 APK 文件
if (await FlutterDownloader.loadTasksWithRawQuery(query: 'SELECT * FROM task WHERE task_id=?', arguments: [taskId]).then((tasks) => tasks[0].status) == DownloadTaskStatus.complete) {
OpenFile.open('${getDownloadDirectory()}/update.apk');
}
完整的实现代码示例可以参考 https://github.com/openflutter/flutter_app_update。注意,在安装器中安装 APK 文件需要用户授权,需要在 AndroidManifest.xml 文件中添加以下权限:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
还需要在 MainActivity 中添加以下代码:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == InstallApkPlugin.REQUEST_CODE_INSTALL_APK && resultCode == RESULT_OK) {
Uri uri = data.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (getPackageManager().canRequestPackageInstalls()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(intent);
}
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(intent);
}
}
}