HarmonyOS鸿蒙Next中APP如何实现应用内自动检查更新并下载安装?

HarmonyOS鸿蒙Next中APP如何实现应用内自动检查更新并下载安装?

问题描述

开发的鸿蒙 APP 需要支持应用内更新功能,用户打开 APP 后自动检查 AGC 上的最新版本,若有更新则提示用户下载安装,如何实现版本检查、Apk/Hap 下载和自动安装?是否需要申请特殊权限?

关键字:鸿蒙应用内更新、AGC 版本检查、Hap 下载、自动安装、权限申请

3 回复

原理解析

鸿蒙应用内更新核心流程:

  1. 从 AGC 获取最新版本信息(版本号、下载地址);
  2. 对比本地版本与最新版本,若有更新则提示用户;
  3. 通过 HTTP 下载最新 Hap/Apk 安装包;
  4. 调用系统安装接口完成安装,核心依赖 AGC 的 “应用更新服务” 和鸿蒙的 appInstaller API。

实现步骤

步骤 1:申请相关权限

module.json5 中声明权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.REQUEST_INSTALL_APKS",
        "reason": "需要安装应用更新包",
        "usedScene": { "ability": [".MainAbility"], "when": "inuse" }
      },
      {
        "name": "ohos.permission.INTERNET",
        "reason": "需要检查更新和下载安装包",
        "usedScene": { "ability": [".MainAbility"], "when": "inuse" }
      },
      {
        "name": "ohos.permission.WRITE_EXTERNAL_STORAGE",
        "reason": "需要存储下载的安装包",
        "usedScene": { "ability": [".MainAbility"], "when": "inuse" }
      }
    ]
  }
}

步骤 2:从 AGC 获取最新版本信息

import http from '@ohos.net.http';
import bundle from '@ohos.bundle';
import common from '@ohos.app.ability.common';

class AppUpdateManager {
  private context = getContext(this) as common.UIAbilityContext;
  // AGC应用更新接口(需在AGC控制台开启应用更新服务)
  private agcUpdateUrl = 'https://agc-update-drcn.cloud.huawei.com/checkAppUpdate';

  // 获取本地应用版本号
  async getLocalVersion() {
    const bundleInfo = await bundle.getBundleInfoForSelf(bundle.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    return bundleInfo.versionName; // 如1.0.0
  }

  // 从AGC检查最新版本
  async checkLatestVersion() {
    const httpRequest = http.createHttp();
    try {
      const localVersion = await this.getLocalVersion();
      const response = await httpRequest.request(this.agcUpdateUrl, {
        method: http.RequestMethod.POST,
        header: { 'Content-Type': 'application/json' },
        extraData: JSON.stringify({
          appId: '你的AGC应用ID',
          bundleName: this.context.bundleName,
          versionName: localVersion
        })
      });

      if (response.responseCode === 200) {
        const result = JSON.parse(response.result.toString());
        // 对比版本号(假设最新版本号为result.latestVersionName)
        if (this.compareVersion(result.latestVersionName, localVersion) > 0) {
          console.log('发现新版本:', result.latestVersionName);
          return {
            hasUpdate: true,
            downloadUrl: result.downloadUrl, // 安装包下载地址
            versionName: result.latestVersionName,
            releaseNotes: result.releaseNotes // 更新日志
          };
        }
      }
      return { hasUpdate: false };
    } catch (err) {
      console.error('检查更新失败:', err);
      return { hasUpdate: false };
    } finally {
      httpRequest.destroy();
    }
  }

  // 版本号对比(如1.1.0 > 1.0.0)
  compareVersion(v1: string, v2: string): number {
    const v1Arr = v1.split('.').map(Number);
    const v2Arr = v2.split('.').map(Number);
    for (let i = 0; i < Math.max(v1Arr.length, v2Arr.length); i++) {
      const num1 = v1Arr[i] || 0;
      const num2 = v2Arr[i] || 0;
      if (num1 > num2) return 1;
      if (num1 < num2) return -1;
    }
    return 0;
  }
}

步骤 3:下载安装包

import fs from '@ohos.file.fs';

// 下载安装包到沙箱目录
async function downloadUpdatePackage(downloadUrl: string): Promise<string> {
  const httpRequest = http.createHttp();
  try {
    const response = await httpRequest.request(downloadUrl, {
      method: http.RequestMethod.GET,
      responseType: http.ResponseType.STREAM
    });

    if (response.responseCode === 200) {
      // 沙箱下载目录
      const cacheDir = await this.context.getCacheDir();
      const savePath = `${cacheDir}/app_update.hap`; // 或.apk

      // 写入文件
      const file = await fs.open(savePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      await fs.write(file.fd, response.result as ArrayBuffer);
      await fs.close(file.fd);
      console.log('安装包下载完成:', savePath);
      return savePath;
    }
    throw new Error('下载失败');
  } catch (err) {
    console.error('下载安装包失败:', err);
    throw err;
  } finally {
    httpRequest.destroy();
  }
}

步骤 4:自动安装应用

import appInstaller from '@ohos.app.installer';

// 安装下载的安装包
async function installUpdate(savePath: string) {
  try {
    // 检查安装权限
    const atManager = abilityAccessCtrl.createAtManager();
    const status = await atManager.checkPermission(
      abilityAccessCtrl.PermissionType.PERMISSION,
      'ohos.permission.REQUEST_INSTALL_APKS'
    );

    if (status !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      // 申请安装权限
      await atManager.requestPermissionsFromUser(this.context, ['ohos.permission.REQUEST_INSTALL_APKS']);
    }

    // 调用系统安装接口
    const installParam = {
      bundleFilePath: savePath,
      installFlag: appInstaller.InstallFlag.INSTALL_REPLACE_EXISTING // 覆盖安装
    };

    const installResult = await appInstaller.install(installParam);
    if (installResult.resultCode === 0) {
      console.log('安装成功,应用将重启');
    } else {
      console.error('安装失败:', installResult.errorMsg);
    }
  } catch (err) {
    console.error('安装应用失败:', err);
  }
}

步骤 5:整合应用内更新流程

// 完整更新流程
async function checkAndUpdate() {
  const updateInfo = await this.checkLatestVersion();
  if (updateInfo.hasUpdate) {
    // 提示用户更新
    promptAction.showDialog({
      title: `发现新版本${updateInfo.versionName}`,
      message: updateInfo.releaseNotes,
      buttons: [{ text: '取消' }, { text: '立即更新' }]
    }).then(async (result) => {
      if (result.index === 1) {
        const savePath = await this.downloadUpdatePackage(updateInfo.downloadUrl);
        await this.installUpdate(savePath);
      }
    });
  }
}

避坑提醒

  • 需在 AGC 控制台开启 “应用更新服务”,并上传最新版本的 Hap/Apk;
  • 安装权限(REQUEST_INSTALL_APKS)需动态申请,用户同意后才能安装;
  • 下载的安装包需存储在应用沙箱目录,不可存储在外部公共目录;
  • 安装成功后应用会自动重启,需确保用户数据已保存。

更多关于HarmonyOS鸿蒙Next中APP如何实现应用内自动检查更新并下载安装?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,应用内自动检查更新并下载安装可通过@ohos.update模块实现。首先使用getUpdateInfo()检查更新,然后调用download()下载更新包,最后通过install()执行静默安装。整个过程需在应用沙箱权限内完成,确保用户授权。

在HarmonyOS Next中,实现应用内更新(包括检查、下载和安装)主要依赖于AppGallery Connect(AGC)的App Linking服务和系统提供的安装更新能力。以下是核心实现步骤和注意事项:

1. 版本检查

  • 集成AGC SDK:在项目中引入@hw-agconnect/api-ohos等相关库,并完成AGC配置。
  • 调用版本检查API:通过AGC提供的checkForUpdate()方法,检查云端是否有新版本。可设置检查策略(如每次启动检查或定时检查)。
  • 获取版本信息:从返回结果中解析版本号、更新日志、下载地址(App Linking链接)等。

2. 下载安装包(Hap)

  • 使用下载管理器:通过@ohos.request模块的downloadTask实现Hap包下载。需申请ohos.permission.INTERNET网络权限。
  • 存储路径:建议将Hap包下载至应用沙箱目录(如filesDir),无需额外存储权限。

3. 自动安装

  • 调用安装接口:使用@ohos.bundle.installer模块的getBundleInstaller()获取安装管理器,通过install()方法安装Hap。
  • 所需权限
    • 安装自身更新需配置"allowAppInstallation": true(在module.json5中声明)。
    • 若使用silentInstall(静默安装,仅限系统应用),需申请ohos.permission.INSTALL_BUNDLE权限(普通应用无法获取)。
  • 注意事项:普通应用只能通过弹窗提示用户确认安装,无法完全静默安装。

4. 关键配置

  • 更新包类型:确保AGC云端的发布包为Release类型,且与本地证书匹配。
  • App Linking配置:在AGC控制台启用App Linking,并关联更新包,获取下载链接。
  • 网络安全性:若服务器为HTTPS,需配置网络安全策略。

5. 代码示例(简化版)

// 1. 检查更新
import agconnect from '@hw-agconnect/api-ohos';
let checkResult = await agconnect.appChecking.checkForUpdate();

// 2. 下载Hap
import request from '@ohos.request';
let downloadTask = request.downloadFile(context, {
  url: checkResult.downloadUrl,
  filePath: 'xxx/update.hap'
});

// 3. 安装Hap
import installer from '@ohos.bundle.installer';
let bundleInstaller = installer.getBundleInstaller();
await bundleInstaller.install('xxx/update.hap', installOptions);

权限申请清单

  • 网络权限:ohos.permission.INTERNET
  • 安装权限:"allowAppInstallation": true(配置声明)
  • 存储权限:一般不需要(沙箱目录可读写)

注意事项

  • 安装过程需用户手动确认弹窗(安全限制)。
  • 确保下载的Hap包与当前应用签名一致,否则安装失败。
  • 建议在Wi-Fi环境下触发下载,并提示用户更新包大小。

通过以上步骤,可完成从检测到安装的完整更新流程。具体接口参数请参考官方文档。

回到顶部