HarmonyOs

1.沙箱文件操作

应用沙箱是一种一啊全防护为目的的隔离机制,避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下 应用可见的目录范围即为“应用沙箱目录”

沙箱路径在

 1.获取沙箱目录

getContext().cacheDir

getContext().fileDir

getContext().tempDir

2.文件操作 

harmonyos提供文件操作的api,相当于nodejs的中的fs操作

值得注意的是:在api9中 使用fs在当前的API11heAPI12中 官方又提供了fileIO的基础方法,用法和fs基本一致

open 打开文件

close 关闭文件

write 写入文件

copy 复制文件

unlink 删除文件

mkdir 创建文件夹

上述方法均支持promise并提供有对应的同步方法

想要操作一个文件 ,首先要打开一个文件,读取一个文件的buffer或者fd,通过fd进行文件的buffer进行相应的操作

下载图片方法他是一个promise函数  返回的是一个下载任务的状态 有三种状态  一是进度 二是失败 三是下载完成

    let task = await request.downloadFile(getContext(), {
      url: this.url,
      filePath: filePath
    })
    // 下载进度
    task.on('progress', () => {
    })
    // 下载失败
    task.on('fail', () => {


    })
    // 下载成功
    task.on('complete', () => {
      this.filePath = filePath
      promptAction.showToast({
        message: '下载成功了'
      })
    })

 3.需求 实现一个图片 点击按钮下载到沙箱  并读取沙箱里的图片进行展示

import { request } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct DownLoadPage {
  @State url: string = 'https://c-ssl.dtstatic.com/uploads/item/202003/05/20200305161241_dfqmr.thumb.1000_0.jpg';
  @State filePath: string = ''

  async downLoad() {
    let filePath = getContext().filesDir + '/' + Date.now() + '.jpg'
    let task = await request.downloadFile(getContext(), {
      url: this.url,
      filePath: filePath
    })
    // 下载进度
    task.on('progress', () => {
    })
    // 下载失败
    task.on('fail', () => {


    })
    // 下载成功
    task.on('complete', () => {
      this.filePath = filePath
      promptAction.showToast({
        message: '下载成功了'
      })
    })
  }

  build() {
    Column({ space: 20 }) {
      Image(this.url).width('100%')
        .height(200)


      Button('下载图片').onClick(() => {
        this.downLoad()
      })

      Image('file://' + this.filePath)
        .width(200)
        .height(200)
    }

    .height('100%')
    .width('100%')
  }
}

读取沙箱内的文件要是用文件读取 即 “file://”

2.混合开发中的热更新操作

需求  将这个压缩包下载到沙箱 如果已经有了就再给它换个名字 路径放在下方:https://gitee.com/shuiruohanyu/toutiao_net/blob/master/resources/toutiao.zip

重点代码:

let fileName = 'toutiao.zip'
    let filePath = getContext().filesDir + '/' + fileName
    if (fileIo.listFileSync(getContext().filesDir).includes(fileName)) {
      fileIo.renameSync(filePath, getContext().filesDir + '/' + 'toutiao.bak.zip')
    }
    let task = await request.downloadFile(getContext(), {
      url: 'https://gitee.com/shuiruohanyu/toutiao_net/blob/master/resources/toutiao.zip',
      filePath: filePath
    })
    task.on('progress', (currentValue, totel) => {
      this.currentValue = currentValue
      this.totel = totel
    })
    task.on('complete', () => {
      this.showMask = false
      promptAction.showToast({
        message: '下载成功了'
      })
    })

全部代码

import { request } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct DownLoadHotPage {
  @State message: string = '沙箱热更新';
  @State showMask: boolean = false;
  @State currentValue: number = 0
  @State totel: number = 0

  @Builder
  maskPopup() {
    Column() {
      Progress({
        value: this.currentValue,
        total: this.totel
      })


    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor('rgba(0,0,0,0.5)')

  }

  async downLoad() {
    this.showMask = true
    let fileName = 'toutiao.zip'
    let filePath = getContext().filesDir + '/' + fileName
    if (fileIo.listFileSync(getContext().filesDir).includes(fileName)) {
      fileIo.renameSync(filePath, getContext().filesDir + '/' + 'toutiao.bak.zip')
    }
    let task = await request.downloadFile(getContext(), {
      url: 'https://gitee.com/shuiruohanyu/toutiao_net/blob/master/resources/toutiao.zip',
      filePath: filePath
    })
    task.on('progress', (currentValue, totel) => {
      this.currentValue = currentValue
      this.totel = totel
    })
    task.on('complete', () => {
      this.showMask = false
      promptAction.showToast({
        message: '下载成功了'
      })
    })

  }

  build() {
    Column() {
      Button('热更新')
        .onClick(() => {
          this.downLoad()
        })
    }
    .height('100%')
    .width('100%')
    .bindContentCover($$this.showMask, this.maskPopup, {
      modalTransition: ModalTransition.NONE
    })
  }
}

看下下载下来的zip吧

解压操作

  async decompressFile() {

    try {
      await zlib.decompressFile(getContext().filesDir + '/' + 'toutiao.zip', getContext().filesDir)
    } catch (errData) {
      console.log(errData, 'dsjfjksdf')
    }

  }

解压成功后   我们就可以在Web组件中使用解压后的html

然后加载页面

controller: webview.WebviewController = new webview.WebviewController()

  build() {
    Column() {
      // Web的默认是禁止了浏览器的页面的存储化
      Web({
        src: 'file://' + getContext().tempDir + '/toutiao/index.html',
        controller: this.controller
      }).domStorageAccess(true) //解决页面中不能存储的问题
        .width('100%')
        .height('100%')

    }

  }

3. 原生能力

1.音视频播放Vedio   

@Entry
@Component
struct VideoPage {
  @State message: string = '音视频';

  build() {
    Column() {
      // 网络路径
      Video({
        src: 'https://vdept3.bdstatic.com/mda-qhia4gdeicc3c2gc/sc/cae_h264/1724119722028125307/mda-qhia4gdeicc3c2gc.mp4?v_from_s=hkapp-haokan-hbe&auth_key=1725010231-0-0-8fc29a5968bade17df3138163bbd3e5d&bcevod_channel=searchbox_feed&cr=2&cd=0&pd=1&pt=3&logid=1831750927&vid=10380342571472452940&klogid=1831750927&abtest=87345_2'
      })
        .width('100%')
        .height(200)
      // 资源路径
      Video({
        src: $rawfile('video.mp4')
      })
        .width('100%')
        .height(200)

      // 普通文件夹路径路径
      Video({
        src: '/assets/video1.mp4'
      })
        .width('100%')
        .height(200)


    }
    .height('100%')
    .width('100%')
  }
}

控制它的播放或暂停能力、重点代码截图

@Entry
@Component
struct VideoPage {
  @State message: string = '音视频';
  controller: VideoController = new VideoController();

  build() {
    Column() {

      // 资源路径
      Video({
        src: $rawfile('video.mp4'),
        controller: this.controller
      })
        .width('100%')
        .height(200)
      Button('播放').onClick((event: ClickEvent) => {
        this.controller.start()
      })
       
      Button('暂停').onClick((event: ClickEvent) => {
        this.controller.pause()
      })

    }


    .height('100%')
    .width('100%')
  }
}

设置不显示下边的那个控制器

.controls(false)
  Video({
        src: $rawfile('video.mp4'),
        controller: this.controller
      })
        .controls(false)
        .width('100%')
        .height(200)

 设置它的倍速

@Entry
@Component
struct VideoPage {
  @State message: string = '音视频';
  controller: VideoController = new VideoController();
  @State speed: number = 0.7

  build() {
    Column() {
      // 资源路径
      Video({
        src: $rawfile('video.mp4'),
        controller: this.controller,
        currentProgressRate: this.speed
      })

        .controls(false)
        .width('100%')
        .height(200)
      Button('播放').onClick((event: ClickEvent) => {
        this.controller.start()
      })

      Button('暂停').onClick((event: ClickEvent) => {
        this.controller.pause()
      })

      Slider({
        value: $$this.speed,
        min: 0.75,
        max: 2,
        step: 0.25
      })

    }


    .height('100%')
    .width('100%')
  }
}

重点代码截图

2.抖音小案例

3.canvas

  • ArkUI里边的画布和前端的Canvas的用法一致
  • 使用方法:
  1. 放置Canvas组件 -给宽和高
  2. 初始化画笔对象CanvasRenderingContext2D,将画笔作为构造参数传递给Canvas组件
  3. 可以在Canvas的onReady事件中进行动态绘制
  4. 绘制方法官方文档
@Entry
@Component
struct CanvasPage {
  @State message: string = 'Hello World';
  myPen: CanvasRenderingContext2D = new CanvasRenderingContext2D()

  build() {
    Column() {
      Canvas(this.myPen)
        .width('100%')
        .height(300)
        .backgroundColor(Color.Gray)
      Button('画线').onClick(() => {
        this.myPen.lineWidth = 4 //绘画的线的宽度
        this.myPen.strokeStyle = 'red' //绘画的线的颜色
        this.myPen.beginPath()//开始绘画
        this.myPen.moveTo(20, 20) //开始绘画的坐标
        this.myPen.lineTo(340, 280) //结束绘画的坐标

        this.myPen.stroke() //绘画出来
        this.myPen.closePath()//结束绘画
      })

    }
    .justifyContent(FlexAlign.Center)

    .height('100%')
    .width('100%')
  }
}

 点击按钮 出现这么个效果

3.写个签字版吧

@Entry
@Component
struct SignaturePage {
  @State message: string = '签字版';
  myPen: CanvasRenderingContext2D = new CanvasRenderingContext2D()
  Cwidth: number = 0
  Cheight: number = 0

  build() {
    Column() {
      Button('清除签字板').onClick(() => {
        this.myPen.clearRect(0, 0, this.Cwidth, this.Cheight)
      })
      Canvas(this.myPen)
        .width('100%')
        .height(300)
        .backgroundColor(Color.Gray)
        .onAreaChange((oldArea, newArea) => {
          this.Cwidth = newArea.width as number
          this.Cheight = newArea.height as number
        }
        )
        .onReady(() => {
          this.myPen.lineWidth = 2
          this.myPen.strokeStyle = 'red'
        })
        .onTouch((event: TouchEvent) => {
          // console.log(event.tiltX.toString())
          if (event.type == TouchType.Down) {
            console.log('按下了')
            this.myPen.beginPath()

            this.myPen.moveTo(event.touches[0].x, event.touches[0].y)
          } else if (event.type == TouchType.Move) {
            console.log('移动了')
            this.myPen.lineTo(event.touches[0].x, event.touches[0].y)
            this.myPen.stroke()
          } else if (event.type == TouchType.Up) {
            console.log('松开了')
            this.myPen.closePath()
          }
        })


    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值