# 内置安装器实现说明
## 📋 实现概述
实现了基于 PackageInstaller API 的内置安装器,支持 Android 8.0 及以下版本。同时保留了原有的系统安装器方式,用于 Android 8.1 及以上版本。
## ✅ 已完成的修改
### 1. 创建 InstallModule.java 原生插件
**文件路径**: `bBeng-HeartRate-4.66-pad/uniplugin_module/src/main/java/io/dcloud/uniplugin/InstallModule.java`
**功能**:
- ✅ 使用 PackageInstaller API 实现内置安装器
- ✅ 支持 Android 5.0+ (API 21+)
- ✅ 自动监听安装结果
- ✅ 提供安装进度反馈(日志)
- ✅ 兼容 Android 8.0 和 Android 12+ 的 PendingIntent 标志
**主要方法**:
- `installApkWithPackageInstaller(String apkPath, UniJSCallback callback)`: 使用内置安装器安装 APK
- `getAndroidVersion()`: 获取当前 Android 版本号
- `isPackageInstallerSupported()`: 检查是否支持 PackageInstaller
### 2. 注册插件到 dcloud_uniplugins.json
**文件路径**: `bBeng-HeartRate-4.66-pad/app/src/main/assets/dcloud_uniplugins.json`
**修改内容**:
```json
{
"type": "module",
"name": "InstallModule",
"class": "io.dcloud.uniplugin.InstallModule"
}
```
### 3. 修改 app-info.vue
**文件路径**: `heart-app-hbuilder-x/pages/platform-page/app-info/app-info.vue`
**主要修改**:
1. **添加版本判断逻辑**:
- Android 8.0 (API 26) 及以下:使用 PackageInstaller(内置安装器)
- Android 8.1 (API 27) 及以上:使用 `plus.runtime.install`(系统安装器)
2. **新增方法**:
- `checkAndroidVersionAndInstall()`: 检查版本并选择安装方式
- `installApkWithPackageInstaller()`: 使用内置安装器安装(无需退出 Kiosk)
- `installApkWithSystemInstaller()`: 使用系统安装器安装(普通安装,不涉及 Kiosk)
3. **移除的方法**:
- 移除了 `temporaryExitKioskAndInstall()` 方法(不再需要临时退出 Kiosk)
4. **修复**:
- 添加了缺失的 `showOpenFolder` 数据属性
## 🔄 工作流程
### Android 8.0 及以下(内置安装器)
```
用户点击下载/安装
↓
下载完成
↓
checkAndroidVersionAndInstall()
↓
检测到 API ≤ 26
↓
installApkWithPackageInstaller()
├─ 使用 PackageInstaller API
├─ 无需退出 Kiosk 模式 ✅
├─ 显示安装进度
└─ 监听安装结果
↓
安装完成/失败
↓
显示结果提示
```
### Android 8.1 及以上(系统安装器)
```
用户点击下载/安装
↓
下载完成
↓
checkAndroidVersionAndInstall()
↓
检测到 API > 26
↓
installApkWithSystemInstaller()
├─ 使用 plus.runtime.install
├─ 普通安装,不涉及 Kiosk ✅
└─ 系统处理安装流程
↓
安装完成/失败
↓
显示结果提示
```
## 🎯 核心优势
### 内置安装器(Android 8.0 及以下)
1. **无需退出 Kiosk 模式**
- 安装过程完全在应用内完成
- 不会触发系统安装界面
- 保持 Kiosk 模式锁定状态
2. **完全控制**
- 可以显示自定义安装进度
- 可以监听安装结果
- 可以处理安装错误
3. **用户体验**
- 无缝安装体验
- 不会中断应用使用
- 安装完成后自动处理
### 系统安装器(Android 8.1 及以上)
1. **简单可靠**
- 使用系统原生安装器
- 符合 Android 安全策略
- 用户熟悉的安装界面
2. **无需特殊处理**
- 不涉及 Kiosk 操作
- 系统自动处理权限
- 安装完成后自动重启
## 📝 代码示例
### Vue 层调用
```javascript
// 检查版本并安装
this.checkAndroidVersionAndInstall();
// 或直接调用内置安装器
this.installApkWithPackageInstaller();
// 或直接调用系统安装器
this.installApkWithSystemInstaller();
```
### 原生层调用
```java
// 获取 Android 版本
int version = InstallModule.getAndroidVersion();
// 检查是否支持
boolean supported = InstallModule.isPackageInstallerSupported();
// 安装 APK
InstallModule.installApkWithPackageInstaller(apkPath, callback);
```
## ⚠️ 注意事项
### 1. 权限要求
**AndroidManifest.xml 中已配置**:
```xml
```
### 2. Android 8.0 特殊处理
- Android 8.0 引入了 `REQUEST_INSTALL_PACKAGES` 权限
- 如果应用不是 Device Owner,可能需要用户授权"安装未知应用"
- 作为 Device Owner 应用,可以绕过部分限制
### 3. 安装结果监听
- 使用 BroadcastReceiver 动态注册监听安装结果
- 安装完成后自动取消注册
- 支持多个安装会话(通过 sessionId 区分)
### 4. 错误处理
- 文件不存在:返回错误信息
- 权限不足:返回错误信息
- 安装失败:返回系统错误信息
## 🧪 测试要点
1. ✅ Android 8.0 设备:测试内置安装器功能
2. ✅ Android 8.1+ 设备:测试系统安装器功能
3. ✅ 安装成功场景:验证安装流程和结果提示
4. ✅ 安装失败场景:验证错误处理和提示
5. ✅ Kiosk 模式:验证 Android 8.0 下无需退出 Kiosk
6. ✅ 权限处理:验证权限申请和授权流程
## 📚 相关文件
- `InstallModule.java`: 内置安装器实现
- `app-info.vue`: 前端安装逻辑
- `dcloud_uniplugins.json`: 插件注册配置
- `内置安装器方案分析.md`: 方案分析文档
## 🔗 参考资源
- [Android PackageInstaller 官方文档](https://developer.android.com/reference/android/content/pm/PackageInstaller)
- [Android 8.0 行为变更](https://developer.android.com/about/versions/oreo/android-8.0-changes)
- [PendingIntent 标志说明](https://developer.android.com/reference/android/app/PendingIntent)