修复部分配置文件
This commit is contained in:
parent
b9721f93c7
commit
894e7a44b0
421
README.md
421
README.md
|
|
@ -1,16 +1,15 @@
|
||||||
# App Upgrade Plugin
|
# App Upgrade Plugin
|
||||||
|
|
||||||
一款功能强大且灵活的 Flutter 应用内更新插件,专为提供符合主流平台用户习惯的无缝升级体验而设计。插件提供了简化版和增强版两套 API,满足不同复杂度的使用需求。
|
一款轻量、现代且易用的 Flutter 应用内更新插件。支持 Android 的“下载-安装”全流程,iOS 自动跳转 App Store。提供「一键检查更新」与「静默检查 + 用户决定」两种常见用法,并内置完善的权限处理与安装策略。
|
||||||
|
|
||||||
## ✨ 核心特性
|
## ✨ 特性
|
||||||
|
|
||||||
- **🎯 智能平台适配**:Android 支持完整的下载-安装流程,iOS 自动跳转 App Store
|
- **🎯 智能平台适配**:Android 直下直装,iOS 跳转 App Store
|
||||||
- **🔄 双模式更新**:非强制更新(后台下载)+ 强制更新(阻塞式对话框)
|
- **🔄 两种更新体验**:非强制(可后台下载)与强制更新(阻塞式对话框)
|
||||||
- **🛡️ 全面权限管理**:自动适配不同 Android 版本的存储、安装、通知权限
|
- **🛡️ 权限适配完善**:针对不同 Android 版本的存储、安装、通知权限
|
||||||
- **📱 现代化 UI**:Material Design 风格对话框,支持暗色主题和自定义样式
|
- **📱 现代化 UI**:Material 风格对话框,进度与状态可视化
|
||||||
- **🌐 健壮网络层**:基于 Dio,支持断点续传、重试机制、证书配置
|
- **🌐 网络可配置**:证书校验、超时、默认方法、Headers 等
|
||||||
- **🔒 安全可靠**:MD5/SHA256 文件校验,防止下载文件损坏
|
- **🔧 安装策略灵活**:系统流程/预检查权限/智能策略可选
|
||||||
- **🎨 高度可定制**:丰富的配置选项和回调接口
|
|
||||||
|
|
||||||
## 📦 安装
|
## 📦 安装
|
||||||
|
|
||||||
|
|
@ -23,97 +22,88 @@ dependencies:
|
||||||
|
|
||||||
## 🚀 快速开始
|
## 🚀 快速开始
|
||||||
|
|
||||||
### 方式一:简化版 API(推荐新手)
|
### 方式一:一键检查更新(推荐)
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
import 'package:app_upgrade_plugin/app_upgrade_plugin.dart';
|
import 'package:app_upgrade_plugin/app_upgrade_plugin.dart';
|
||||||
|
|
||||||
// 一行代码实现完整升级流程
|
|
||||||
void checkUpdate(BuildContext context) {
|
void checkUpdate(BuildContext context) {
|
||||||
|
// 可选:一次性配置常用选项
|
||||||
|
AppUpgradeSimple.instance.configure(
|
||||||
|
const UpgradeConfig(
|
||||||
|
showNoUpdateToast: true,
|
||||||
|
autoDownload: true,
|
||||||
|
autoInstall: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 一行调用,自动拉取并展示升级对话框
|
||||||
AppUpgradeSimple.instance.checkUpdate(
|
AppUpgradeSimple.instance.checkUpdate(
|
||||||
context: context,
|
context: context,
|
||||||
url: 'https://your-api.com/check-update',
|
url: 'https://your-api.com/check-update',
|
||||||
params: {'channel': 'release'}, // 可选参数
|
params: {'channel': 'release'},
|
||||||
showNoUpdateToast: true,
|
|
||||||
autoDownload: true,
|
|
||||||
autoInstall: false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 方式二:分离式 API(更灵活)
|
### 方式二:静默检查 + 由用户决定
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// 1. 检查更新(纯逻辑,不涉及UI)
|
final info = await AppUpgradeSimple.instance.checkUpdateSilent(
|
||||||
final upgradeInfo = await AppUpgradeSimple.instance.checkUpdateSilent(
|
|
||||||
url: 'https://your-api.com/check-update',
|
url: 'https://your-api.com/check-update',
|
||||||
params: {'platform': 'android'},
|
params: {'platform': 'android'},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 2. 根据需要显示UI
|
if (info != null && info.hasUpdate && context.mounted) {
|
||||||
if (upgradeInfo != null && context.mounted) {
|
// 再次调用一键方法以展示对话框(内部会重新请求一次最新信息)
|
||||||
AppUpgradeSimple.instance.showUpgradeDialog(
|
await AppUpgradeSimple.instance.checkUpdate(
|
||||||
context: context,
|
context: context,
|
||||||
info: upgradeInfo,
|
url: 'https://your-api.com/check-update',
|
||||||
autoDownload: true,
|
|
||||||
autoInstall: false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 方式三:增强版 API(高级用户)
|
说明:当前公开 API 中未暴露独立的 `showUpgradeDialog()` 方法,静默检查用于“询问后再触发一键流程”的业务场景。
|
||||||
|
|
||||||
|
### 常用配置
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
final plugin = AppUpgradePluginEnhanced.instance;
|
// 内置多套配置:
|
||||||
|
AppUpgradeSimple.instance.configure(UpgradeConfig.auto); // 自动下载+自动安装
|
||||||
|
AppUpgradeSimple.instance.configure(UpgradeConfig.silent); // 静默检查
|
||||||
|
AppUpgradeSimple.instance.configure(UpgradeConfig.withPermission); // 安装前检查权限(传统)
|
||||||
|
|
||||||
// 配置插件
|
// 自定义:
|
||||||
plugin.configure(
|
AppUpgradeSimple.instance.configure(const UpgradeConfig(
|
||||||
debugMode: true,
|
showNoUpdateToast: true,
|
||||||
wifiOnly: false,
|
autoDownload: true,
|
||||||
autoCheck: true,
|
autoInstall: false,
|
||||||
);
|
installTimeout: 60,
|
||||||
|
));
|
||||||
// 添加下载监听
|
|
||||||
plugin.addDownloadCallback((task) {
|
|
||||||
print('下载进度: ${task.progress}%');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 智能检查更新
|
|
||||||
final info = await plugin.checkUpdateSmart(
|
|
||||||
'https://your-api.com/check-update'
|
|
||||||
);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🎨 UI 展示
|
## 🎨 UI 能力
|
||||||
|
|
||||||
插件提供多种精美的 UI 组件:
|
- 发现新版本对话框(强制/非强制)
|
||||||
|
- 版本信息卡片(当前版本、新版本、APK 大小)
|
||||||
- **版本更新对话框**:显示版本信息、更新内容、文件大小
|
- 下载进度展示与可重试安装行为
|
||||||
- **下载进度对话框**:实时显示下载进度和状态
|
- Android 上支持“应用市场选择”或“直接下载”两种路径
|
||||||
- **应用市场选择**:支持多应用商店选择(华为、小米、OPPO等)
|
|
||||||
- **权限申请对话框**:友好的权限说明和引导
|
|
||||||
|
|
||||||
## ⚙️ Android 配置
|
## ⚙️ Android 配置
|
||||||
|
|
||||||
### 1. 权限配置
|
### 1) 权限
|
||||||
|
|
||||||
在 `android/app/src/main/AndroidManifest.xml` 中添加:
|
在 `android/app/src/main/AndroidManifest.xml` 中添加:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<!-- 网络权限 -->
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<!-- 安装权限(必需) -->
|
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
|
<!-- Android 13+ 通知权限(可选) -->
|
||||||
<!-- 通知权限(Android 13+,可选) -->
|
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||||
|
|
||||||
<application>
|
<application>
|
||||||
<!-- 你的其他配置 -->
|
<!-- FileProvider(Android 7.0+ APK 安装必需) -->
|
||||||
|
|
||||||
<!-- FileProvider 配置(必需,用于 Android 7.0+ APK 安装) -->
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.fileprovider"
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
|
@ -127,34 +117,27 @@ final info = await plugin.checkUpdateSmart(
|
||||||
</manifest>
|
</manifest>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. FileProvider 路径配置
|
### 2) FileProvider 路径
|
||||||
|
|
||||||
创建 `android/app/src/main/res/xml/file_paths.xml`:
|
创建 `android/app/src/main/res/xml/file_paths.xml`:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<!-- 外部存储 -->
|
|
||||||
<external-path name="external_files" path="." />
|
<external-path name="external_files" path="." />
|
||||||
<!-- 应用内部存储 -->
|
|
||||||
<files-path name="files" path="." />
|
<files-path name="files" path="." />
|
||||||
<!-- 缓存目录 -->
|
|
||||||
<cache-path name="cache" path="." />
|
<cache-path name="cache" path="." />
|
||||||
<!-- 外部缓存 -->
|
|
||||||
<external-cache-path name="external_cache" path="." />
|
<external-cache-path name="external_cache" path="." />
|
||||||
<!-- 下载目录 -->
|
|
||||||
<external-path name="downloads" path="Download/" />
|
<external-path name="downloads" path="Download/" />
|
||||||
</paths>
|
</paths>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Gradle 配置(可选)
|
### 3) Gradle(可选)
|
||||||
|
|
||||||
在 `android/app/build.gradle` 中:
|
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
android {
|
android {
|
||||||
compileSdk 34
|
compileSdk 34
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_11
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_11
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
|
|
@ -167,298 +150,126 @@ dependencies {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📡 服务端 API 协议
|
## 📡 服务端返回协议
|
||||||
|
|
||||||
你的版本检查接口需要返回以下格式的 JSON:
|
代码模型 `UpgradeInfo` 需要以下字段(关键字段必须):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"hasUpdate": true,
|
|
||||||
"isForceUpdate": false,
|
"isForceUpdate": false,
|
||||||
"versionBuildNumber": "101",
|
"versionBuildNumber": 101,
|
||||||
"versionName": "1.0.1",
|
"versionName": "1.0.1",
|
||||||
"updateContent": "1. 修复了登录问题\n2. 优化了界面显示\n3. 提升了性能",
|
"updateContent": "1. 修复登录\n2. 优化UI\n3. 提升性能",
|
||||||
"downloadUrl": "https://your-cdn.com/app-release.apk",
|
"downloadUrl": "https://your-cdn.com/app-release.apk",
|
||||||
"appStoreUrl": "https://apps.apple.com/app/id123456789",
|
"appStoreUrl": "https://apps.apple.com/app/id123456789",
|
||||||
"apkSize": 25165824,
|
"apkSize": 25165824,
|
||||||
"apkMd5": "d41d8cd98f00b204e9800998ecf8427e",
|
"apkMd5": "d41d8cd98f00b204e9800998ecf8427e",
|
||||||
"appMarkets": [
|
"appMarkets": [
|
||||||
{
|
{"name":"华为应用市场","packageName":"com.huawei.appmarket","url":"appmarket://details?id=com.yourapp.package"}
|
||||||
"name": "华为应用市场",
|
|
||||||
"packageName": "com.huawei.appmarket",
|
|
||||||
"url": "appmarket://details?id=com.yourapp.package"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "小米应用商店",
|
|
||||||
"packageName": "com.xiaomi.market",
|
|
||||||
"url": "mimarket://details?id=com.yourapp.package"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 字段说明
|
- `versionBuildNumber` 与 `versionName` 为必填,插件会与当前应用版本进行对比自动计算 `hasUpdate`。
|
||||||
|
- `downloadUrl` 仅 Android 需要;`appStoreUrl` 仅 iOS 使用。
|
||||||
|
|
||||||
| 字段 | 类型 | 必需 | 说明 |
|
## 🔧 进阶能力
|
||||||
|------|------|------|------|
|
|
||||||
| `hasUpdate` | boolean | ✅ | 是否有更新 |
|
|
||||||
| `isForceUpdate` | boolean | ✅ | 是否强制更新 |
|
|
||||||
| `versionCode` | string | ✅ | 版本号(数字字符串,用于版本比较) |
|
|
||||||
| `versionName` | string | ✅ | 版本名称(显示给用户) |
|
|
||||||
| `updateContent` | string | ✅ | 更新内容描述 |
|
|
||||||
| `downloadUrl` | string | Android必需 | APK下载地址 |
|
|
||||||
| `appStoreUrl` | string | iOS必需 | App Store链接 |
|
|
||||||
| `apkSize` | number | ❌ | APK文件大小(字节) |
|
|
||||||
| `apkMd5` | string | ❌ | APK文件MD5校验值 |
|
|
||||||
| `appMarkets` | array | ❌ | 应用市场列表 |
|
|
||||||
|
|
||||||
## 🔧 高级配置
|
### 1) 网络配置
|
||||||
|
|
||||||
### 网络配置
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// 自动模式(推荐)
|
// 自动选择(Debug 绕过证书、Release 严格校验)
|
||||||
// Debug: 自动绕过证书验证
|
AppUpgradePlugin().configureHttp(HttpConfig.auto);
|
||||||
// Release: 严格证书验证
|
|
||||||
|
|
||||||
// 手动配置
|
// 或手动:
|
||||||
AppUpgradePlugin().configureHttp(HttpConfig(
|
AppUpgradePlugin().configureHttp(const HttpConfig(
|
||||||
ignoreCertificate: false, // 是否忽略证书
|
ignoreCertificate: false,
|
||||||
enableLog: true, // 启用网络日志
|
enableLog: true,
|
||||||
connectTimeout: 30, // 连接超时(秒)
|
connectTimeout: 30,
|
||||||
receiveTimeout: 60, // 接收超时(秒)
|
receiveTimeout: 60,
|
||||||
defaultMethod: 'GET', // 默认请求方法
|
defaultMethod: 'GET',
|
||||||
headers: { // 自定义请求头
|
headers: {'User-Agent': 'MyApp/1.0'},
|
||||||
'User-Agent': 'MyApp/1.0',
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
```
|
```
|
||||||
|
|
||||||
### 权限管理
|
### 2) 权限助手(Android)
|
||||||
|
|
||||||
插件提供了独立的权限管理工具:
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
import 'package:app_upgrade_plugin/core/permission_helper.dart';
|
import 'package:app_upgrade_plugin/core/permission_helper.dart';
|
||||||
|
|
||||||
// 检查并请求存储权限
|
final hasStorage = await PermissionHelper.checkAndRequestStoragePermission(context: context);
|
||||||
final hasStorage = await PermissionHelper.checkAndRequestStoragePermission(
|
final hasInstall = await PermissionHelper.checkAndRequestInstallPermission(context: context);
|
||||||
context: context,
|
final hasNotification = await PermissionHelper.checkAndRequestNotificationPermission(context: context);
|
||||||
);
|
|
||||||
|
|
||||||
// 检查并请求安装权限
|
// 精确跳转安装权限设置
|
||||||
final hasInstall = await PermissionHelper.checkAndRequestInstallPermission(
|
await AppUpgradePlugin().openInstallPermissionSettings();
|
||||||
context: context,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 检查并请求通知权限
|
|
||||||
final hasNotification = await PermissionHelper.checkAndRequestNotificationPermission(
|
|
||||||
context: context,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 直接打开安装权限设置页面(新功能)
|
|
||||||
final opened = await AppUpgradePlugin().openInstallPermissionSettings();
|
|
||||||
if (opened) {
|
|
||||||
print('成功打开安装权限设置页面');
|
|
||||||
} else {
|
|
||||||
print('无法打开设置页面(非Android设备或系统限制)');
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 精确权限设置跳转
|
### 3) 安装策略(Android)
|
||||||
|
|
||||||
相比传统的 `openAppSettings()` 方法会打开应用的全部设置页面,新增的 `openInstallPermissionSettings()` 方法可以更精确地定位到安装权限设置:
|
|
||||||
|
|
||||||
- **Android 8.0+**:直接跳转到当前应用的"安装未知应用"权限页面
|
|
||||||
- **Android 8.0-**:跳转到应用详情页面
|
|
||||||
- **厂商适配**:针对小米、华为、OPPO、Vivo、三星等定制ROM优化
|
|
||||||
- **多重降级**:确保在各种情况下都能成功跳转到相关设置页面
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
// 方法1:使用系统流程安装(推荐,类似主流应用)
|
// 系统流程(推荐):系统处理权限并弹出安装确认
|
||||||
final systemSuccess = await AppUpgradePlugin().installApkWithSystemFlow(apkPath);
|
await AppUpgradePlugin().installApkWithSystemFlow(apkPath);
|
||||||
if (systemSuccess) {
|
|
||||||
print('使用系统流程启动安装');
|
|
||||||
} else {
|
|
||||||
print('系统流程安装失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 方法2:传统安装方式(需要预先检查权限)
|
// 传统安装:需要事先自行处理安装权限
|
||||||
final traditionalSuccess = await AppUpgradePlugin().installApk(apkPath);
|
await AppUpgradePlugin().installApk(apkPath);
|
||||||
|
|
||||||
// 如果需要手动管理权限,可以使用精确跳转
|
// 按配置策略安装
|
||||||
final settingsSuccess = await AppUpgradePlugin().openInstallPermissionSettings();
|
await AppUpgradePlugin().installApkWithConfig(
|
||||||
|
apkPath,
|
||||||
// 获取设备信息用于调试
|
config: InstallConfig.smart,
|
||||||
final deviceInfo = await AppUpgradePlugin().getDeviceInfo();
|
|
||||||
print('设备制造商: ${deviceInfo?['manufacturer']}');
|
|
||||||
print('Android版本: ${deviceInfo?['release']}');
|
|
||||||
```
|
|
||||||
|
|
||||||
**厂商特殊适配**:
|
|
||||||
|
|
||||||
| 厂商 | 特殊处理 | 预期效果 |
|
|
||||||
|------|---------|----------|
|
|
||||||
| 小米/红米 | MIUI权限管理页面 | 直接跳转到应用权限设置 |
|
|
||||||
| 华为/荣耀 | EMUI/HarmonyOS适配 | 跳转到应用管理页面 |
|
|
||||||
| OPPO | ColorOS标准方式 | 直接跳转到安装权限 |
|
|
||||||
| Vivo | FunTouch OS标准方式 | 直接跳转到安装权限 |
|
|
||||||
| 三星 | One UI标准方式 | 直接跳转到安装权限 |
|
|
||||||
| 原生Android | 标准Intent | 直接跳转到安装权限 |
|
|
||||||
|
|
||||||
### 两种安装方式对比
|
|
||||||
|
|
||||||
| 方法 | 权限检查 | 用户体验 | 适用场景 |
|
|
||||||
|------|---------|----------|----------|
|
|
||||||
| `installApk()` | 预先检查权限,无权限时返回错误 | 需要开发者处理权限申请 | 需要完全控制安装流程 |
|
|
||||||
| `installApkWithSystemFlow()` | 让系统处理权限检查 | 类似主流应用,直接弹出安装确认 | 推荐使用,体验更好 |
|
|
||||||
|
|
||||||
**`installApkWithSystemFlow()` 的优势**:
|
|
||||||
- ✅ 类似盒马、美团等主流应用的安装体验
|
|
||||||
- ✅ 系统自动处理权限检查和用户确认
|
|
||||||
- ✅ 无需开发者手动管理"安装未知应用"权限
|
|
||||||
- ✅ 弹出"XX正尝试安装应用"对话框,用户点击"继续"即可
|
|
||||||
|
|
||||||
```dart
|
|
||||||
// 推荐的安装流程
|
|
||||||
Future<void> installUpdate(String apkPath) async {
|
|
||||||
final success = await AppUpgradePlugin().installApkWithSystemFlow(apkPath);
|
|
||||||
if (success) {
|
|
||||||
print('安装程序已启动,等待用户确认');
|
|
||||||
} else {
|
|
||||||
print('启动安装程序失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 动态配置安装策略
|
|
||||||
|
|
||||||
插件提供了灵活的配置系统,可以根据需要选择不同的安装策略:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
import 'package:app_upgrade_plugin/app_upgrade_plugin.dart';
|
|
||||||
|
|
||||||
// 方式1:使用预定义配置
|
|
||||||
await AppUpgradePlugin().installApkWithConfig(apkPath, config: InstallConfig.systemFlow);
|
|
||||||
await AppUpgradePlugin().installApkWithConfig(apkPath, config: InstallConfig.preCheckPermission);
|
|
||||||
await AppUpgradePlugin().installApkWithConfig(apkPath, config: InstallConfig.smart);
|
|
||||||
|
|
||||||
// 方式2:自定义配置
|
|
||||||
final customConfig = InstallConfig(
|
|
||||||
strategy: InstallStrategy.smart,
|
|
||||||
autoOpenSettings: true,
|
|
||||||
showPermissionRationale: true,
|
|
||||||
rationaleTitle: '需要安装权限',
|
|
||||||
rationaleContent: '为了完成应用更新,需要允许安装未知来源的应用。',
|
|
||||||
);
|
);
|
||||||
await AppUpgradePlugin().installApkWithConfig(apkPath, config: customConfig);
|
|
||||||
|
|
||||||
// 方式3:根据用户设置动态选择
|
|
||||||
InstallStrategy getUserPreferredStrategy() {
|
|
||||||
// 从用户设置或配置文件读取
|
|
||||||
final userPreference = getSettingsFromStorage();
|
|
||||||
switch (userPreference) {
|
|
||||||
case 'system': return InstallStrategy.systemFlow;
|
|
||||||
case 'permission': return InstallStrategy.preCheckPermission;
|
|
||||||
case 'smart': return InstallStrategy.smart;
|
|
||||||
default: return InstallStrategy.systemFlow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final strategy = getUserPreferredStrategy();
|
|
||||||
final config = InstallConfig(strategy: strategy, autoOpenSettings: true);
|
|
||||||
await AppUpgradePlugin().installApkWithConfig(apkPath, config: config);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**三种策略对比**:
|
策略对比:
|
||||||
|
|
||||||
| 策略 | 行为 | 适用场景 |
|
- `systemFlow`:系统处理权限检查与确认,体验最佳
|
||||||
|------|------|----------|
|
- `preCheckPermission`:先检查权限,无权时返回错误,便于精细控制
|
||||||
| `systemFlow` | 让系统处理所有权限检查 | 希望类似主流应用的体验 |
|
- `smart`:有权用预检查,无权走系统流程
|
||||||
| `preCheckPermission` | 预先检查权限,无权限时跳转设置 | 需要完全控制权限流程 |
|
|
||||||
| `smart` | 有权限用预检查,无权限用系统流程 | 平衡控制和体验 |
|
|
||||||
|
|
||||||
## 🐛 故障排除
|
## 🐛 常见问题
|
||||||
|
|
||||||
### 常见问题
|
- 安装失败显示“解析包时出现问题”:检查 APK 完整性、签名与架构匹配
|
||||||
|
- 权限申请失败:确认 Manifest 权限、FileProvider 配置、在 MaterialApp 环境调用
|
||||||
|
- 下载失败/进度不更新:检查网络、下载 URL 可用性、服务端是否支持断点
|
||||||
|
- iOS 不跳转:确认 `appStoreUrl` 为有效的 App Store 链接
|
||||||
|
|
||||||
**Q: 安装失败,提示 "解析包时出现问题"**
|
## 📚 主要 API 清单
|
||||||
|
|
||||||
A: 检查以下几点:
|
|
||||||
- APK 文件是否完整下载(检查文件大小)
|
|
||||||
- APK 签名是否正确
|
|
||||||
- 设备架构是否匹配(armeabi-v7a, arm64-v8a)
|
|
||||||
|
|
||||||
**Q: 权限申请失败**
|
|
||||||
|
|
||||||
A: 确保:
|
|
||||||
- AndroidManifest.xml 中已声明相应权限
|
|
||||||
- FileProvider 配置正确
|
|
||||||
- 在 MaterialApp 环境中调用权限申请
|
|
||||||
|
|
||||||
**Q: 下载失败或进度不更新**
|
|
||||||
|
|
||||||
A: 检查:
|
|
||||||
- 网络连接是否正常
|
|
||||||
- 下载URL是否可访问
|
|
||||||
- 服务器是否支持断点续传
|
|
||||||
|
|
||||||
**Q: iOS 不跳转 App Store**
|
|
||||||
|
|
||||||
A: 确认:
|
|
||||||
- `appStoreUrl` 字段格式正确
|
|
||||||
- URL 为有效的 App Store 链接
|
|
||||||
|
|
||||||
### 调试技巧
|
|
||||||
|
|
||||||
开启调试模式以获取详细日志:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
// 简化版
|
|
||||||
AppUpgradeSimple.instance.init(debugMode: true);
|
|
||||||
|
|
||||||
// 增强版
|
|
||||||
AppUpgradePluginEnhanced.instance.configure(debugMode: true);
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📚 API 文档
|
|
||||||
|
|
||||||
### AppUpgradeSimple
|
### AppUpgradeSimple
|
||||||
|
|
||||||
| 方法 | 描述 |
|
- `configure(UpgradeConfig)`:配置升级参数
|
||||||
|------|------|
|
- `checkUpdate({context, url, params, ...})`:检查更新并显示 UI
|
||||||
| `checkUpdate()` | 检查更新并显示UI |
|
- `checkUpdateSilent({url, params})`:静默检查(不显示 UI)
|
||||||
| `checkUpdateSilent()` | 静默检查更新 |
|
- `preDownloadApk({url, onProgress})`:预下载 APK(Android)
|
||||||
| `showUpgradeDialog()` | 显示升级对话框 |
|
- `findDownloadedApk(version)`:查找已下载的 APK(Android)
|
||||||
|
- `getAppInfo()`:获取当前应用信息
|
||||||
|
|
||||||
### AppUpgradePluginEnhanced
|
### AppUpgradePlugin(底层能力)
|
||||||
|
|
||||||
| 方法 | 描述 |
|
- `configureHttp(HttpConfig)`:网络层配置
|
||||||
|------|------|
|
- `downloadApk(url, onProgress)`:下载 APK(Android)
|
||||||
| `configure()` | 配置插件 |
|
- `installApk(filePath)` / `installApkWithSystemFlow(filePath)` / `installApkWithConfig(filePath, config)`(Android)
|
||||||
| `checkUpdateSmart()` | 智能检查更新 |
|
- `openInstallPermissionSettings()`:跳转安装权限设置(Android)
|
||||||
| `downloadApkSmart()` | 智能下载APK |
|
- `getDeviceInfo()`、`getAndroidSdkVersion()`(Android)
|
||||||
| `installApkSmart()` | 智能安装APK |
|
- `goToAppStore(url)`:跳转到应用商店
|
||||||
| `addDownloadCallback()` | 添加下载监听 |
|
|
||||||
|
|
||||||
### PermissionHelper
|
### PermissionHelper(Android)
|
||||||
|
|
||||||
| 方法 | 描述 |
|
- `checkAndRequestStoragePermission(context)`
|
||||||
|------|------|
|
- `checkAndRequestInstallPermission(context)`
|
||||||
| `checkAndRequestStoragePermission()` | 存储权限 |
|
- `checkAndRequestNotificationPermission(context)`
|
||||||
| `checkAndRequestInstallPermission()` | 安装权限 |
|
|
||||||
| `checkAndRequestNotificationPermission()` | 通知权限 |
|
|
||||||
|
|
||||||
## 🤝 贡献
|
## 🤝 贡献
|
||||||
|
|
||||||
欢迎提交 Issue 和 Pull Request!
|
欢迎提交 Issue 与 Pull Request!
|
||||||
|
|
||||||
## 📄 许可证
|
## 📄 许可证
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
## 🔗 相关链接
|
## 🔗 参考
|
||||||
|
|
||||||
- [Flutter 官网](https://flutter.dev)
|
- [Flutter 官网](https://flutter.dev)
|
||||||
- [Android 应用安装权限文档](https://developer.android.com/reference/android/Manifest.permission#REQUEST_INSTALL_PACKAGES)
|
- [Android 安装权限文档](https://developer.android.com/reference/android/Manifest.permission#REQUEST_INSTALL_PACKAGES)
|
||||||
- [FileProvider 使用指南](https://developer.android.com/reference/androidx/core/content/FileProvider)
|
- [FileProvider 使用指南](https://developer.android.com/reference/androidx/core/content/FileProvider)
|
||||||
|
|
@ -230,7 +230,7 @@ class AppUpgradeSimple {
|
||||||
/// 检查网络连接状态
|
/// 检查网络连接状态
|
||||||
Future<bool> checkNetworkStatus() async {
|
Future<bool> checkNetworkStatus() async {
|
||||||
try {
|
try {
|
||||||
final result = await InternetAddress.lookup('google.com');
|
final result = await InternetAddress.lookup('baidu.com');
|
||||||
return result.isNotEmpty && result[0].rawAddress.isNotEmpty;
|
return result.isNotEmpty && result[0].rawAddress.isNotEmpty;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('网络检查失败: $e');
|
debugPrint('网络检查失败: $e');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue