鸿蒙网络编程系列38-Web组件文件下载示例

1. web组件文件下载能力简介

在本系列的第22篇文章,介绍了web组件的文件上传能力,同样的,web组件也具备文件下载能力,鸿蒙API提供了处理web组件下载事件的委托类型WebDownloadDelegate,该类型包括四个下载事件的回调接口:

javascript 复制代码
class WebDownloadDelegate {
//下载开始前通知用户,用户需要在此接口中调用WebDownloadItem.start提供下载路径
onBeforeDownload(callback: Callback<WebDownloadItem>): void

//下载过程中的回调
onDownloadUpdated(callback: Callback<WebDownloadItem>): void

//下载完成后的回调
onDownloadFinish(callback: Callback<WebDownloadItem>): void

//下载失败时的回调
onDownloadFailed(callback: Callback<WebDownloadItem>): void
}

web组件的控制器类WebviewController提供了设置web组件下载事件委托的方法setDownloadDelegate:

javascript 复制代码
setDownloadDelegate(delegate: WebDownloadDelegate): void

web组件在下载状态变化时会自动调用委托中的对应回调函数。

本文将通过一个示例演示web组件的下载能力,通过进度条展示下载进度的变化。

2. web组件文件下载演示

本示例运行后的界面如图所示:

输入要浏览的网页地址,然后单击"加载"按钮加载网页,加载成功后单击要下载文件的超链接即可开始下载,如图所示:

这里我们下载的是哔哩哔哩网站的安卓版客户端,在应用的下载展示了下载的位置和当前的进度以及下载速度。下载完毕的界面如图所示:

这样就完成了web组件的下载功能演示。

3. web组件文件下载示例编写

下面详细介绍创建该示例的步骤。

步骤1:创建Empty Ability项目。

步骤2:在module.json5配置文件加上对权限的声明:

json 复制代码
"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]

这里添加了访问互联网的权限。

步骤3:在Index.ets文件里添加如下的代码:

javascript 复制代码
import webview from '@ohos.web.webview';
import web_webview from '@ohos.web.webview'

@Entry
@Component
struct Index {
  @State title: string = "Web组件文件下载示例"
  //下载状态
  @State downloadState: string = ""
  //当前下载速度
  @State downloadSpeed: string = ""
  //下载文件保存位置
  @State downloadPath: string = ""
  //下载进度
  @State downloadProgress: number = 0
  //要加载的网址
  @State webUrl: string = "https://app.bilibili.com/"

  scroller: Scroller = new Scroller()
  controller: web_webview.WebviewController = new web_webview.WebviewController()

  build() {
    Row() {
      Column() {
        Text(this.title)
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .width('100%')
          .textAlign(TextAlign.Center)
          .padding(10)

        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text("网址:")
            .fontSize(14)
            .width(50)
            .flexGrow(0)

          TextInput({ text: this.webUrl })
            .onChange((value) => {
              this.webUrl = value
            })
            .width(110)
            .fontSize(11)
            .flexGrow(1)

          Button("加载")
            .onClick(() => {
              this.controller.loadUrl(this.webUrl);
              this.controller.setDownloadDelegate(this.buildDownloadDelegate())
            })
            .width(60)
            .fontSize(14)
            .flexGrow(0)
        }
        .width('100%')
        .padding(5)

        Scroll(this.scroller) {
          Web({ src: "", controller: this.controller })
            .padding(10)
            .width('100%')
            .textZoomRatio(150)
            .backgroundColor(0xeeeeee)
        }
        .align(Alignment.Top)
        .backgroundColor(0xeeeeee)
        .height(300)
        .flexGrow(1)
        .scrollable(ScrollDirection.Vertical)
        .scrollBar(BarState.On)
        .scrollBarWidth(20)

        Progress({ total: 100, type: ProgressType.Linear, value: this.downloadProgress })
        Text(this.downloadPath)
          .fontSize(11)
          .width('100%')
          .padding(5)
        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text(this.downloadState)
            .fontSize(11)
          Divider().vertical(true).height(15).width(10)
          Text(this.downloadSpeed)
            .fontSize(11)
        }
        .width('100%')
        .padding(5)
      }
      .width('100%')
      .justifyContent(FlexAlign.Start)
      .height('100%')
    }
    .height('100%')
  }

  //创建web组件下载状态回调的委托
  buildDownloadDelegate() {
    let downloadDelegate: webview.WebDownloadDelegate = new webview.WebDownloadDelegate();
    //下载前的回调
    downloadDelegate.onBeforeDownload((webDownloadItem: webview.WebDownloadItem) => {
      //下载文件保存位置
      let localFilePath = getContext(this).cacheDir + "/" + webDownloadItem.getSuggestedFileName()
      webDownloadItem.start(localFilePath);
      this.downloadState = "开始下载"
      this.downloadPath = `保存位置:${localFilePath}`
    })

    //下载过程中的通知
    downloadDelegate.onDownloadUpdated((webDownloadItem: webview.WebDownloadItem) => {
      this.downloadState = "正在下载"
      this.downloadProgress = webDownloadItem.getPercentComplete()
      this.downloadSpeed = `当前下载速度:${webDownloadItem.getCurrentSpeed()}比特/秒`
    })

    //下载失败的通知
    downloadDelegate.onDownloadFailed(() => {
      this.downloadState = `下载失败`
    })

    //下载完成的通知
    downloadDelegate.onDownloadFinish(() => {
      this.downloadState = "下载完成"
    })

    return downloadDelegate
  }
}

步骤4:编译运行,可以使用模拟器或者真机。

步骤5:按照本节第2部分"web组件文件下载演示"操作即可。

4. 代码分析

本示例关键点在于构造web组件的下载委托,通过委托的onBeforeDownload回调设置下载文件的保存位置,并通过webDownloadItem的start方法开始下载。

javascript 复制代码
    downloadDelegate.onBeforeDownload((webDownloadItem: webview.WebDownloadItem) => {
      //下载文件保存位置
      let localFilePath = getContext(this).cacheDir + "/" + webDownloadItem.getSuggestedFileName()
      webDownloadItem.start(localFilePath);
      this.downloadState = "开始下载"
      this.downloadPath = `保存位置:${localFilePath}`
    })

(本文作者原创,除非明确授权禁止转载)

本文源码地址:
https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/web/DownloadInWeb

本系列源码地址:
https://gitee.com/zl3624/harmonyos_network_samples

相关推荐
GIS之路32 分钟前
ArcPy,一个基于 Python 的 GIS 开发库简介
前端
可夫小子2 小时前
OpenClaw基础-为什么会有两个端口
前端
喝拿铁写前端2 小时前
Dify 构建 FE 工作流:前端团队可复用 AI 工作流实战
前端·人工智能
喝咖啡的女孩3 小时前
React 合成事件系统
前端
从文处安3 小时前
「九九八十一难」组合式函数到底有什么用?
前端·vue.js
用户5962585736063 小时前
戴上AI眼镜逛花市——感受不一样的体验
前端
yuki_uix3 小时前
Props、Context、EventBus、状态管理:组件通信方案选择指南
前端·javascript·react.js
老板我改不动了3 小时前
前端面试复习指南【代码演示多多版】之——HTML
前端
panshihao3 小时前
Mac 环境下通过 SSH 操作服务器,完成前端静态资源备份与更新(全程实操无坑)
前端
hulkie4 小时前
从 AI 对话应用理解 SSE 流式传输:一项 "老技术" 的新生
前端·人工智能