Bootstrap

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

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

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

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:

setDownloadDelegate(delegate: WebDownloadDelegate): void

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

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

2. web组件文件下载演示

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

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

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

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

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

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

步骤1:创建Empty Ability项目。

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

"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]

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

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

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方法开始下载。

    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

;