Flutter应用内更新插件flutter_rustore_update的使用
Flutter应用内更新插件flutter_rustore_update的使用
RuStore文档
通用
RuStore In-app updates SDK帮助您保持用户设备上的应用程序为最新版本。
当用户维护应用程序处于最新状态时,他们可以尝试新功能,并且还可以利用性能改进和错误修复。
您可以使用RuStore In-app updates SDK来显示应用程序更新过程,该过程支持后台下载和安装更新,并具有状态控制。在下载过程中,用户仍可以继续使用您的应用程序。
用户场景示例
准备必需参数
为了运行示例,您需要以下参数:
-
applicationId
- 您发布到RuStore控制台的应用程序ID,位于项目的build.gradle文件中:android { defaultConfig { applicationId = "ru.rustore.sdk.updateexample" } }
-
release.keystore
- 应用程序发布的签名。您可以在RuStore控制台中找到该签名。
设置示例应用程序
-
为了测试示例,您需要将两个版本的应用程序上传到控制台,每个版本具有不同的versionCode。在测试时,请指定比控制台中更小的versionCode。
defaultConfig { versionCode 1 }
-
在example/android/app/build.gradle文件中替换
applicationId
为您在RuStore控制台上发布的apk文件的applicationId:android { defaultConfig { applicationId = "ru.rustore.sdk.updateexample" // 通常在buildTypes后附加.debug } }
-
将签名替换为您的应用程序签名。设置
key_alias
,key_password
,store_password
参数:android{ signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] } } }
SDK正常工作的条件
为了使RuStore In-app updates SDK正常工作,必须满足以下条件:
- Android操作系统版本7.0或更高。
- 用户设备上应安装有RuStore。
- 设备上的RuStoreApp版本应是最新的。
- RuStore应用程序应被允许安装应用程序。
实现示例
要了解如何正确集成用于推送通知的包,建议查看示例应用程序。
在项目中添加插件
要将插件添加到项目中,请执行以下命令:
flutter pub add flutter_rustore_update
这将在pubspec.yaml文件中添加以下行:
dependencies:
flutter_rustore_update: ^7.0.1
检查更新
在请求更新之前,请检查您的应用程序是否有可用更新。为此,请调用info()方法。调用此方法会检查以下条件:
- 用户设备上应安装有RuStore。
- 设备上的RuStoreApp版本应是最新的。
- 用户和应用程序不应在RuStore中被阻止。
响应此方法时,您将收到一个包含更新信息的对象。
RustoreUpdateClient.info().then((info) {
print(info);
}).catchError((err) {
print(err);
});
info
对象包含一组参数,用于确定是否有更新可用:
updateAvailability
- 更新的可用性:UPDATE_AILABILITY_NOT_AVAILABLE
- 不需要更新。UPDATE_AILABILITY_AVAILABLE
- 需要下载更新或更新已下载到用户设备。UPDATE_AILABILITY_IN_PROGRESS
- 更新正在下载或安装已经开始。UPDATE_AILABILITY_UNKNOWN
- 默认状态。
installStatus
- 更新安装状态,如果用户当前正在安装更新:INSTALL_STATUS_DOWNLOADED
- 已下载。INSTALL_STATUS_DOWNLOADING
- 正在下载。INSTALL_STATUS_FAILED
- 发生错误。INSTALL_STATUS_INSTALLING
- 正在安装。INSTALL_STATUS_PENDING
- 等待中。INSTALL_STATUS_UNKNOWN
- 默认状态。
只有当updateAvailability
字段包含UPDATE_AILABILITY_AVAILABLE
值时,才能启动下载。
该方法可能会返回错误。有关错误列表的详细信息,请参见可能的错误部分。
下载更新
确认更新可用后,您可以请求用户下载更新,但在此之前,您需要使用listener()
方法启动下载状态监听器:
RustoreUpdateClient.listener((value) {
print("listener installStatus ${value.installStatus}");
print("listener bytesDownloaded ${value.bytesDownloaded}");
print("listener totalBytesToDownload ${value.totalBytesToDownload}");
print("listener installErrorCode ${value.installErrorCode}");
if (value.installStatus == INSTALL_STATUS_DOWNLOADED) {
// 可以在此处调用complete()方法
}
});
state
对象描述了更新下载的当前状态。它包含以下内容:
installStatus
- 更新安装状态,如果用户当前正在安装更新:INSTALL_STATUS_DOWNLOADED
- 已下载。INSTALL_STATUS_DOWNLOADING
- 正在下载。INSTALL_STATUS_FAILED
- 发生错误。INSTALL_STATUS_INSTALLING
- 正在安装。INSTALL_STATUS_PENDING
- 等待中。INSTALL_STATUS_UNKNOWN
- 默认状态。
bytesDownloaded
- 已下载的字节数。totalBytesToDownload
- 总共需要下载的字节数。installErrorCode
- 下载期间的错误代码。有关可能的错误的详细信息,请参见可能的错误部分。
延迟更新
从RuStore UI开始下载
要启动应用程序更新的下载,请调用download()
方法。
RustoreUpdateClient.download().then((value) {
print("download code ${value.code}");
}).catchError((err) {
print("download err ${err}");
});
如果用户确认下载更新,则value.code = ACTIVITY_RESULT_OK
;如果拒绝,则value.code = ACTIVITY_RESULT_CANCELED
。
调用该方法后,您可以使用监听器跟踪更新下载的状态。如果在监听器中收到INSTALL_STATUS_DOWNLOADED
状态,您可以调用complete()
方法来安装更新。建议通知用户更新已准备好安装。
该方法可能会返回错误。有关错误列表的详细信息,请参见可能的错误部分。
强制更新
从RuStore UI开始下载
要启动强制更新应用程序的下载,请调用immediate()
方法。
RustoreUpdateClient.immediate().then((value) {
print("silent code ${value.code}");
}).catchError((err) {
print("immediate err ${err}");
});
resultCode (Int)
:
ACTIVITY_RESULT_OK (-1)
- 更新完成,由于应用程序在更新过程中终止,可能不会收到代码。ACTIVITY_RESULT_CANCELED (0)
- 用户中断流程,或发生错误。假定在这种情况下应终止应用程序。ACTIVITY_RESULT_NOT_FOUND (2)
- RuStore未安装,或安装的版本不支持强制更新(RuStore versionCode < 191
)。
throwable
- 更新开始场景的错误。
成功更新后无需进一步操作。
静默更新
从RuStore UI无UI下载
对于这种类型的更新,建议实现自己的界面。
要启动静默更新应用程序的下载,请调用silent()
方法。
RustoreUpdateClient.silent().then((value) {
print("silent code ${value.code}");
}).catchError((err) {
print("silent err ${err}");
});
调用then
时,如果code = ACTIVITY_RESULT_OK
,则会注册下载更新的任务。
在这种场景下,只能通过then
调用ACTIVITY_RESULT_OK
,或者通过catchError
。
调用该方法后,您可以使用监听器跟踪更新下载的状态。
在收到INSTALL_STATUS_DOWNLOADED
状态后,您可以调用安装更新的方法。建议通知用户更新已准备好安装。
安装更新
灵活的更新完成
从RuStore UI开始更新
下载完更新的apk文件后,您可以启动更新安装。要启动更新安装,请调用completeUpdateFlexible()
方法。
RustoreUpdateClient.completeUpdateFlexible().catchError((err) {
print("completeUpdateFlexible err ${err}");
});
- 用户将看到更新完成的UI对话框。
- 成功更新后,应用程序将重新启动。
更新通过Android原生工具进行。成功更新后,应用程序将重新启动。
静默的更新完成
从RuStore UI无UI开始更新
下载完更新的apk文件后,您可以启动更新安装。要启动更新安装,请调用completeUpdateSilent()
方法。
RustoreUpdateClient.completeUpdateSilent().catchError((err) {
print("completeUpdateSilent err ${err}");
});
- 不会显示更新完成的UI对话框。
- 成功更新后,应用程序将关闭。
更新通过Android原生工具进行。成功更新后,应用程序将关闭。
在更新过程中可能会出现错误。有关详细信息,请参见可能的错误部分。
可能的错误
如果您收到onFailure
响应,则不建议自行向用户显示错误。错误显示可能会影响用户体验。
可能的错误列表:
UPDATE_ERROR_DOWNLOAD
- 下载错误。UPDATE_ERROR_BLOCKED
- 安装被系统阻止。UPDATE_ERROR_INVALID_APK
- 更新的APK无效。UPDATE_ERROR_CONFLICT
- 与当前应用程序版本冲突。UPDATE_ERROR_STORAGE
- 设备存储空间不足。UPDATE_ERROR_INCOMPATIBLE
- 与设备不兼容。UPDATE_ERROR_APP_NOT_OWNED
- 应用程序未购买。UPDATE_ERROR_INTERNAL_ERROR
- 内部错误。UPDATE_ERROR_ABORTED
- 用户拒绝安装更新。UPDATE_ERROR_APK_NOT_FOUND
- 用于启动安装的APK未找到。UPDATE_ERROR_EXTERNAL_SOURCE_DENIED
- 启动更新被禁止。例如,在第一个方法中返回更新不可用的响应,但用户调用了第二个方法。
示例代码
import 'package:flutter/material.dart';
import 'package:flutter_rustore_update/const.dart';
import 'package:flutter_rustore_update/flutter_rustore_update.dart';
void main() {
runApp(const App());
}
class App extends StatefulWidget {
const App({super.key});
[@override](/user/override)
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
int availableVersionCode = 0;
int installStatus = 0;
String packageName = "";
int updateAvailability = 0;
String infoErr = "";
int bytesDownloaded = 0;
int totalBytesToDownload = 0;
int installErrorCode = 0;
String completeErr = "";
int installCode = 0;
String updateError = "";
String silentError = "";
String immediateError = "";
[@override](/user/override)
void initState() {
super.initState();
}
void info() {
RustoreUpdateClient.info().then((info) {
setState(() {
availableVersionCode = info.availableVersionCode;
installStatus = info.installStatus;
packageName = info.packageName;
updateAvailability = info.updateAvailability;
});
}).catchError((err) {
print(err);
setState(() {
infoErr = err.message;
});
});
}
void update() {
RustoreUpdateClient.info().then((info) {
setState(() {
availableVersionCode = info.availableVersionCode;
installStatus = info.installStatus;
packageName = info.packageName;
updateAvailability = info.updateAvailability;
});
if (info.updateAvailability == UPDATE_AILABILITY_AVAILABLE) {
RustoreUpdateClient.listener((value) {
print("listener installStatus ${value.installStatus}");
print("listener bytesDownloaded ${value.bytesDownloaded}");
print("listener totalBytesToDownload ${value.totalBytesToDownload}");
print("listener installErrorCode ${value.installErrorCode}");
setState(() {
installStatus = value.installStatus;
bytesDownloaded = value.bytesDownloaded;
totalBytesToDownload = value.totalBytesToDownload;
installErrorCode = value.installErrorCode;
});
if (value.installStatus == INSTALL_STATUS_DOWNLOADED) {
RustoreUpdateClient.completeUpdateFlexible().catchError((err) {
print("completeUpdateFlexible err ${err}");
setState(() {
completeErr = err.message;
});
});
}
});
RustoreUpdateClient.download().then((value) {
print("download code ${value.code}");
setState(() {
installCode = value.code;
});
if (value.code == ACTIVITY_RESULT_CANCELED) {
print("user cancel update");
}
}).catchError((err) {
print("download err ${err}");
setState(() {
updateError = err.message;
});
});
}
}).catchError((err) {
print(err.toString());
setState(() {
infoErr = err.message;
});
});
}
void immediate() {
RustoreUpdateClient.info().then((info) {
setState(() {
availableVersionCode = info.availableVersionCode;
installStatus = info.installStatus;
packageName = info.packageName;
updateAvailability = info.updateAvailability;
});
if (info.updateAvailability == UPDATE_AILABILITY_AVAILABLE) {
RustoreUpdateClient.listener((value) {
print("listener installStatus ${value.installStatus}");
print("listener bytesDownloaded ${value.bytesDownloaded}");
print("listener totalBytesToDownload ${value.totalBytesToDownload}");
print("listener installErrorCode ${value.installErrorCode}");
setState(() {
installStatus = value.installStatus;
bytesDownloaded = value.bytesDownloaded;
totalBytesToDownload = value.totalBytesToDownload;
installErrorCode = value.installErrorCode;
});
});
RustoreUpdateClient.immediate().then((value) {
print("immediate code ${value.code}");
setState(() {
installCode = value.code;
});
}).catchError((err) {
print("immediate err ${err}");
setState(() {
immediateError = err.message;
});
});
}
}).catchError((err) {
print(err.toString());
setState(() {
infoErr = err.message;
});
});
}
void silent() {
RustoreUpdateClient.info().then((info) {
setState(() {
availableVersionCode = info.availableVersionCode;
installStatus = info.installStatus;
packageName = info.packageName;
updateAvailability = info.updateAvailability;
});
if (info.updateAvailability == UPDATE_AILABILITY_AVAILABLE) {
RustoreUpdateClient.listener((value) {
print("listener installStatus ${value.installStatus}");
print("listener bytesDownloaded ${value.bytesDownloaded}");
print("listener totalBytesToDownload ${value.totalBytesToDownload}");
print("listener installErrorCode ${value.installErrorCode}");
setState(() {
installStatus = value.installStatus;
bytesDownloaded = value.bytesDownloaded;
totalBytesToDownload = value.totalBytesToDownload;
installErrorCode = value.installErrorCode;
});
if (value.installStatus == INSTALL_STATUS_DOWNLOADED) {
RustoreUpdateClient.completeUpdateSilent().catchError((err) {
print("completeUpdateSilent err ${err}");
setState(() {
completeErr = err.message;
});
});
}
});
RustoreUpdateClient.silent().then((value) {
print("silent code ${value.code}");
setState(() {
installCode = value.code;
});
}).catchError((err) {
print("silent err ${err}");
setState(() {
silentError = err.message;
});
});
}
}).catchError((err) {
print(err.toString());
setState(() {
infoErr = err.message;
});
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
OutlinedButton(onPressed: info, child: Text("检查更新")),
SizedBox(height: 24),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('信息:'),
Text('availableVersionCode: $availableVersionCode'),
Text('installStatus: $installStatus'),
Text('packageName: $packageName'),
Text('updateAvailability: $updateAvailability'),
Text('错误: $infoErr'),
],
),
SizedBox(height: 48),
Row(
children: [
OutlinedButton(onPressed: update, child: Text("更新")),
SizedBox(width: 12),
OutlinedButton(onPressed: immediate, child: Text("强制更新")),
SizedBox(width: 12),
OutlinedButton(onPressed: silent, child: Text("静默更新")),
],
),
SizedBox(height: 48),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('安装:'),
Text('bytesDownloaded: $bytesDownloaded'),
Text('totalBytesToDownload: $totalBytesToDownload'),
Text('installErrorCode: $installErrorCode'),
Text('completeErr: $completeErr'),
Text('installCode: $installCode'),
SizedBox(height: 12),
Text('错误'),
Text('updateError: $updateError'),
Text('silentError: $silentError'),
Text('immediateError: $immediateError'),
],
),
],
),
),
),
),
);
}
}
更多关于Flutter应用内更新插件flutter_rustore_update的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter应用内更新插件flutter_rustore_update的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter应用中实现应用内更新功能,flutter_rustore_update
是一个可以选择的插件(请注意,插件名称可能因版本或社区维护而有所不同,这里假设插件名正确)。这个插件通常用于从指定的服务器下载新版本的应用 APK 文件,并提示用户进行安装。以下是如何使用 flutter_rustore_update
插件的一个基本示例。
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加对 flutter_rustore_update
的依赖。由于我无法实时检查最新的包名和版本,这里假设包名为 flutter_rustore_update
,你需要根据实际情况替换。
dependencies:
flutter:
sdk: flutter
flutter_rustore_update: ^x.y.z # 替换为实际版本号
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入插件:
import 'package:flutter_rustore_update/flutter_rustore_update.dart';
3. 检查并下载更新
你可以在应用启动时或某个特定的时间点检查更新。以下是一个简单的示例,演示如何检查更新并下载 APK 文件。
void checkForUpdates() async {
try {
// 假设你有一个API端点提供最新版本信息
String updateUrl = "https://yourserver.com/latest_version.json";
// 使用dio或其他HTTP客户端获取最新版本信息
var response = await Dio().get(updateUrl);
// 解析JSON响应,这里假设响应包含一个名为'apkUrl'的字段
var data = response.data;
String apkUrl = data['apkUrl'] as String;
// 使用flutter_rustore_update插件检查并下载更新
var updateManager = FlutterRustoreUpdate();
// 检查是否有新版本
bool hasUpdate = await updateManager.checkNeedUpdate(apkUrl: apkUrl);
if (hasUpdate) {
// 显示下载对话框
var result = await updateManager.downloadApk(apkUrl: apkUrl);
if (result) {
// 下载完成后提示用户安装
updateManager.installApk();
} else {
// 下载失败处理
print("下载更新失败");
}
} else {
// 没有新版本
print("当前版本已是最新");
}
} catch (e) {
// 错误处理
print("检查更新时发生错误: $e");
}
}
4. 调用检查更新函数
你可以在应用的主入口文件(如 main.dart
)中调用 checkForUpdates
函数。
void main() {
runApp(MyApp());
// 在适当的时间点调用检查更新函数
// 例如,在MyApp的initState中或使用定时器
checkForUpdates();
}
注意事项
- 权限:确保你的应用有必要的权限,如网络访问权限和写入外部存储权限(如果APK需要保存到设备)。
- 安全性:验证从服务器下载的APK文件的完整性,防止被篡改。
- 用户体验:提供友好的用户提示,告知用户有更新可用,并引导用户进行下载和安装。
这个示例是一个基本的实现,你可能需要根据实际需求进行扩展和修改。确保在发布应用前进行充分的测试。