Flutter应用升级插件upgrade的使用
Flutter应用升级插件upgrade的使用
1. Preparation
您需要提供一个服务器,该服务器提供版本配置文件(App Version Config File)查询和下载安装文件的服务。例如,可以使用以下链接提供的升级服务器:Upgrade Server
2. Config Before Use
Android
- 创建
file_provider_path.xml
文件,并添加以下内容:
<?xml version="1 .0 " encoding="utf-8"?>
<paths>
<files-path name="files" path="/" />
<cache-path name="cache" path="/" />
<external-path name="external" path="/" />
<external-cache-path name="cache" path="/" />
<external-files-path name="files" path="/" />
</paths>
- 在
android/app/src/main/AndroidManifest.xml
中添加以下权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.package">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application>
<provider
android:authorities="${applicationId}.fileProvider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_path"/>
</provider>
</application>
</manifest>
MacOS
在 .entitlements
文件中设置以下属性:
<dict>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
</dict>
3. Create Version Config File (Appcast) at Local to Mark Current App’s Version
创建一个版本配置文件(Appcast Item),例如在 AppcastItem
。
4. Init Plugin in Suitable Places
初始化插件:
void main() {
UpgradeManager.instance.init(
url: 'http://localhost:8000/appcast/latest', // 升级服务器 URL
currentVersionPath: 'assets/version/version.json',
);
runApp(const MyApp());
}
5. Download if Need and Install
如何使用?请参阅 UpgradeManager
// 下载更新
UpgradeManager.instance.download()
// 安装更新
UpgradeManager.instance.install()
示例代码
import 'package:flutter/material.dart';
import 'package:upgrade/upgrade.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
[@override](/user/override)
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
[@override](/user/override)
void initState() {
super.initState();
UpgradeManager.instance.init(
url: 'http://localhost:8000/appcast/latest',
currentVersionPath: 'assets/version/version.json',
);
}
double progress = 0;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: CustomUpgradeView(
builder: (context, state) => _buildAppcastItemInfo(title: "Upgrade Current Version", item: state.current),
),
),
Align(
alignment: Alignment.bottomLeft,
child: CustomUpgradeView(
builder: (context, state) => _buildAppcastItemInfo(title: "Upgrade Latest Version", item: state.latest),
),
),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
child: CustomUpgradeStatusIndicator(
builder: (context, status) {
return Text(status.name);
},
),
),
),
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Download Progress"),
Padding(
padding: const EdgeInsets.only(top: 16),
child: SizedBox(
width: 256,
child: LinearProgressIndicator(value: progress, minHeight: 8,),
),
),
],
),
),
),
Align(
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () => UpgradeManager.instance.checkForUpdates(),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 24),
child: Text("Check for Updates"),
),
),
GestureDetector(
onTap: () => UpgradeManager.instance.download(onReceiveProgress: (received, total, _) {
setState(() {
progress = received / total;
});
}),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 24),
child: Text("Download"),
),
),
GestureDetector(
onTap: () => UpgradeManager.instance.install(),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 24),
child: Text("Install"),
),
)
],
),
)
],
),
);
}
Widget _buildAppcastItemInfo({required String title, AppcastItem? item}) {
if (item == null) {
return Text("$title: null", style: const TextStyle(fontWeight: FontWeight.bold));
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("$title: ", style: const TextStyle(fontWeight: FontWeight.bold)),
Text("releaseNotes: ${item.releaseNotes}"),
Text("version: ${item.version.toString()}"),
Text("displayVersionString: ${item.displayVersionString}"),
Text("os: ${item.os}"),
Text("minimumSystemVersion: ${item.minimumSystemVersion}"),
Text("maximumSystemVersion: ${item.maximumSystemVersion}"),
],
);
}
}
更多关于Flutter应用升级插件upgrade的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter应用升级插件upgrade的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用upgrade
插件来实现应用升级的示例代码。这个示例将展示如何检测新版本、下载APK文件并提示用户安装。
首先,确保你的Flutter项目中已经添加了upgrade
插件。你可以在pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
upgrade: ^x.x.x # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,我们编写代码来实现应用升级功能。假设我们有一个服务器API可以返回最新版本信息和APK下载链接。
1. 创建一个升级检查函数
首先,我们创建一个函数来检查新版本并下载APK文件。
import 'package:flutter/material.dart';
import 'package:upgrade/upgrade.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
Future<void> checkForUpdates() async {
// 假设服务器返回的JSON格式如下:
// {
// "versionCode": 2,
// "versionName": "1.1.0",
// "apkUrl": "https://example.com/app-release.apk",
// "releaseNotes": "This is a new update with bug fixes and improvements."
// }
String latestVersionUrl = 'https://example.com/latest_version.json';
final response = await http.get(Uri.parse(latestVersionUrl));
if (response.statusCode == 200) {
Map<String, dynamic> latestVersionData = jsonDecode(response.body);
int latestVersionCode = latestVersionData['versionCode'];
String latestVersionName = latestVersionData['versionName'];
String apkUrl = latestVersionData['apkUrl'];
String releaseNotes = latestVersionData['releaseNotes'];
PackageInfo packageInfo = await PackageInfo.fromPlatform();
int currentVersionCode = packageInfo.versionCode;
if (latestVersionCode > currentVersionCode) {
showUpgradeDialog(context, latestVersionName, apkUrl, releaseNotes);
}
} else {
// 处理请求失败的情况
print('Failed to fetch latest version info');
}
}
2. 显示升级对话框并下载APK
接下来,我们编写一个函数来显示升级对话框,并在用户同意升级后下载APK文件。
Future<void> showUpgradeDialog(BuildContext context, String latestVersionName, String apkUrl, String releaseNotes) async {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('New Update Available'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Version $latestVersionName is now available!'),
SizedBox(height: 10),
Text('Release Notes:'),
SizedBox(height: 5),
Text(releaseNotes, style: TextStyle(fontSize: 14)),
],
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('Skip'),
),
TextButton(
onPressed: () async {
Navigator.of(context).pop();
await downloadAndInstallApk(apkUrl);
},
child: Text('Update Now'),
),
],
),
);
}
Future<void> downloadAndInstallApk(String apkUrl) async {
Directory appDocDir = await getApplicationDocumentsDirectory();
String apkFilePath = '${appDocDir.path}/app-release.apk';
File apkFile = File(apkFilePath);
var response = await http.get(Uri.parse(apkUrl));
if (response.statusCode == 200) {
await apkFile.writeAsBytes(response.bodyBytes);
if (await canLaunch(apkFilePath)) {
await launch(apkFilePath);
} else {
throw 'Could not launch $apkFilePath';
}
} else {
throw 'Failed to download APK';
}
}
3. 在主应用中使用升级检查函数
最后,在你的主应用入口(如MyApp
的initState
或某个按钮点击事件中)调用checkForUpdates
函数。
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('App Upgrade Example'),
),
body: Center(
child: Builder(
builder: (context) {
return ElevatedButton(
onPressed: () {
checkForUpdates();
},
child: Text('Check for Updates'),
);
},
),
),
),
);
}
}
这个示例代码展示了如何使用upgrade
插件(虽然实际上upgrade
插件可能提供了更高级的功能,但这里为了演示目的,我们手动实现了逻辑)结合HTTP请求和文件操作来实现应用升级功能。请根据你的实际需求调整代码和API细节。