鸿蒙开发相关知识(四)【数据持久化(用户首选项、关系型数据库)、通知(基础通知、进度条通知、通知意图)】


一、数据持久化

1、用户首选项

(1)语法说明

  • 为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。
  • Key键为string类型,要求非空且长度不超过80个字节。
  • 如果Value值为string类型,可以为空,不为空时长度不超过8192个字节。
  • 建议存储的数据不超过一万条。
  • 导入用户首选项模块
import dataPreferences from '@ohos.data.preferences';
  • 要获取Preferences实例,读取指定文件
 dataPreferences.getPreferences(this.context, 'mystore', (err, preferences) => {
     if (err) {
       console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
       return;
     }
     console.info('Succeeded in getting preferences.');
     // 进行相关数据操作
   })
  • 数据操作
  • 写入数据,如果已经存在则会覆盖,可利用.has() 判断是否存在
 preferences.put('startup', 'auto', (err) => {
    if (err) {
      console.error(`Failed to put data. Code:${err.code}, message:${err.message}`);
      return;
    }
    console.info('Succeeded in putting data.');
  })
  • 读取数据,如果值为null或者非默认值类型,则返回默认数据。
 preferences.get('startup', 'default', (err, val) => {
    if (err) {
      console.error(`Failed to get value of 'startup'. Code:${err.code}, message:${err.message}`);
      return;
    }
    console.info(`Succeeded in getting value of 'startup'. val: ${val}.`);
  })
  • 删除数据
  preferences.delete('startup', (err) => {
    if (err) {
      console.error(`Failed to delete the key 'startup'. Code:${err.code}, message:${err.message}`);
      return;
    }
    console.info("Succeeded in deleting the key 'startup'.");
  })
  • 数据持久化,应用存入数据到Preferences实例后,可以使用flush()方法实现数据持久化
preferences.flush((err) => {
    if (err) {
      console.error(`Failed to flush. Code:${err.code}, message:${err.message}`);
      return;
    }
    console.info('Succeeded in flushing.');
  })

(2)完整代码示例

  • ets/common/util/PreferencesUtil.ts
  • 加载实例、写入、获取、删除方法
import preferences from '@ohos.data.preferences';

class PreferencesUtil{

  prefMap: Map<string, preferences.Preferences> = new Map()

  async loadPreference(context, name: string){
    try { // 加载preferences
      let pref = await preferences.getPreferences(context, name)
      this.prefMap.set(name, pref)
      console.log('testTag', `加载Preferences[${name}]成功`)
    } catch (e) {
      console.log('testTag', `加载Preferences[${name}]失败`, JSON.stringify(e))
    }
  }

  async putPreferenceValue(name: string, key: string, value: preferences.ValueType){
    if (!this.prefMap.has(name)) {
      console.log('testTag', `Preferences[${name}]尚未初始化!`)
      return
    }
    try {
      let pref = this.prefMap.get(name)
      // 写入数据
      await pref.put(key, value)
      // 刷盘
      await pref.flush()
      console.log('testTag', `保存Preferences[${name}.${key} = ${value}]成功`)
    } catch (e) {
      console.log('testTag', `保存Preferences[${name}.${key} = ${value}]失败`, JSON.stringify(e))
    }
  }

  async getPreferenceValue(name: string, key: string, defaultValue: preferences.ValueType){
    if (!this.prefMap.has(name)) {
      console.log('testTag', `Preferences[${name}]尚未初始化!`)
      return
    }
    try {
      let pref = this.prefMap.get(name)
      // 读数据
      let value = await pref.get(key, defaultValue)
      console.log('testTag', `读取Preferences[${name}.${key} = ${value}]成功`)
      return value
    } catch (e) {
      console.log('testTag', `读取Preferences[${name}.${key} ]失败`, JSON.stringify(e))
    }
  }
}

const preferencesUtil = new PreferencesUtil()

export default preferencesUtil as PreferencesUtil
  • ets/entryability/EntryAbility.ets
  • 应用启动时调用加载实例方法
import UIAbility from '@ohos.app.ability.UIAbility';
import PreferencesUtil from '../common/util/PreferencesUtil'

export default class EntryAbility extends UIAbility {
  async onCreate(want, launchParam) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate running');
    // 加载Preferences
    await PreferencesUtil.loadPreference(this.context, 'MyPreferences')
  }
}

  • ets/pages/Index.ets
  • 页面出现前(aboutToAppear())获取实例并赋值
import IndexFontSizePanel from '../views/IndexFontSizePanel'
import PreferencesUtil from '../common/util/PreferencesUtil'

@Entry
@Component
struct Index {
  @State message: string = '页面列表'
  @State showPanel: boolean = false
  @Provide fontSize: number = 16

  async aboutToAppear(){
    this.fontSize = await PreferencesUtil.getPreferenceValue('MyPreferences', 'IndexFontSize', 16) as number
  }

  build() {
    Column() {
      // 字体修改面板
      if(this.showPanel){
        IndexFontSizePanel()
          .transition({
            translate: { y: 115 }
          })
      }
    }
    .width('100%')
    .height('100%')
  }

}
  • views/IndexFontSizePanel.ets
  • onChange 方法中修改实例值
import PreferencesUtil from '../common/util/PreferencesUtil'

@Component
export default struct IndexFontSizePanel {
  @Consume fontSize: number
  fontSizLabel: object = {
    14: '小',
    16: '标准',
    18: '大',
    20: '特大',
  }

  build() {
    Column() {
      Text(this.fontSizLabel[this.fontSize]).fontSize(20)
      Row({ space: 5 }) {
        Text('A').fontSize(14).fontWeight(FontWeight.Bold)
        Slider({
          min: 14,
          max: 20,
          step: 2,
          value: this.fontSize
        })
          .showSteps(true)
          .trackThickness(6)
          .layoutWeight(1)
          .onChange(val => {
            // 修改字体大小
            this.fontSize = val
            // 写入Preferences
            PreferencesUtil.putPreferenceValue('MyPreferences', 'IndexFontSize', val)
          })
        Text('A').fontSize(20).fontWeight(FontWeight.Bold)
      }.width('100%')
    }
    .width('100%')
    .padding(15)
    .backgroundColor('#fff1f0f0')
    .borderRadius(20)
  }
}

2、关系型数据库

(1)初始化数据库

  • a、导入关系型数据库模块
import relationalStore from '@ohos.data.relationalStore';
  • b、初始化数据库表
  • rdb配置
const STORE_CONFIG = {
  name: 'RdbTest.db', // 数据库文件名
  securityLevel: relationalStore.SecurityLevel.S1 // 数据库安全级别
};
  • 初始化表的SQL
// 建表Sql语句
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, SALARY REAL, CODES BLOB)';
  • 获取rdb,执行SQL,后续的所有增删改查都是使用rdbStore对象
relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
  if (err) {
    console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
    return;
  }
  console.info(`Succeeded in getting RdbStore.`);
  store.executeSql(SQL_CREATE_TABLE); // 创建数据表

  // 这里执行数据库的增、删、改、查等操作

});

(2)增删改数据

  • a.新增数据
const valueBucket = {
  'NAME': 'Lisa',
  'AGE': 18,
  'SALARY': 100.5,
  'CODES': new Uint8Array([1, 2, 3, 4, 5])
};
//EMPLOYEE 数据表名
store.insert('EMPLOYEE', valueBucket, (err, rowId) => {
  if (err) {
    console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`);
    return;
  }
  console.info(`Succeeded in inserting data. rowId:${rowId}`);
})
  • b.修改数据
const valueBucket = {
  'NAME': 'Rose',
  'AGE': 22,
};
// 创建表'EMPLOYEE'的predicates
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
// 匹配表'EMPLOYEE'中'NAME'为'Lisa'的字段
predicates.equalTo('NAME', 'Lisa'); 
store.update(valueBucket, predicates, (err, rows) => {
  if (err) {
    console.error(`Failed to update data. Code:${err.code}, message:${err.message}`);
    return;
  }
  console.info(`Succeeded in updating data. row count: ${rows}`);
})

  • c.删除数据
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
predicates.equalTo('NAME', 'Lisa');
store.delete(predicates, (err, rows) => {
  if (err) {
    console.error(`Failed to delete data. Code:${err.code}, message:${err.message}`);
    return;
  }
  console.info(`Delete rows: ${rows}`);
})

(3)查询数据

  • a.查询数据、返回一个ResultSet结果集
let predicates = new relationalStore.RdbPredicates('EMPLOYEE');
predicates.equalTo('NAME', 'Rose');
let result = await store.query(predicates, ['ID', 'NAME', 'AGE', 'SALARY', 'CODES'])
  • b.解析结果
// 准备数组保存结果
let tasks:any[]=[]
//循环遍历结果集,判断结果是否遍历到最后一行
while(!result.isAtLastRow){
	//指针移动到下一行数据
	result.goToNextRow()
	//根据字段名获取字段index,从而获取字段值
	let id = result.getLong(result.getColumnIndex('ID'));
	let name = result.getString(result.getColumnIndex('NAME'));
	tasks.push({id,name})
}

(4)完整代码示例

  • ets/model/TaskModel.ets
import relationalStore from '@ohos.data.relationalStore';
import TaskInfo from '../viewmodel/TaskInfo';

class TaskModel {

  private rdbStore: relationalStore.RdbStore
  private tableName: string = 'TASK'

  /**
   * 初始化任务表
   */
  initTaskDB(context){
    // 1.rdb配置
    const config = {
      name: 'MyApplication.db',
      securityLevel: relationalStore.SecurityLevel.S1
    }
    // 2.初始化SQL语句
    const sql = `CREATE TABLE IF NOT EXISTS TASK (
                  ID INTEGER PRIMARY KEY AUTOINCREMENT,
                  NAME TEXT NOT NULL,
                  FINISHED bit
                 )`
    // 3.获取rdb
    relationalStore.getRdbStore(context, config, (err, rdbStore) => {
      if(err){
        console.log('testTag', '获取rdbStore失败!')
        return
      }
      // 执行Sql
      rdbStore.executeSql(sql)
      console.log('testTag', '创建task表成功!')
      // 保存rdbStore
      this.rdbStore = rdbStore
    })
  }

  /**
   * 查询任务列表
   */
  async getTaskList(){
    // 1.构建查询条件
    let predicates = new relationalStore.RdbPredicates(this.tableName)
    // 2.查询
    let result = await this.rdbStore.query(predicates, ['ID', 'NAME', 'FINISHED'])
    // 3.解析查询结果
    // 3.1.定义一个数组,组装最终的查询结果
    let tasks: TaskInfo[] = []
    // 3.2.遍历封装
    while(!result.isAtLastRow){
      // 3.3.指针移动到下一行
      result.goToNextRow()
      // 3.4.获取数据
      let id = result.getLong(result.getColumnIndex('ID'))
      let name = result.getString(result.getColumnIndex('NAME'))
      let finished = result.getLong(result.getColumnIndex('FINISHED'))
      // 3.5.封装到数组
      tasks.push({id, name, finished: !!finished})
    }
    console.log('testTag', '查询到数据:', JSON.stringify(tasks))
    return tasks
  }

  /**
   * 添加一个新的任务
   * @param name 任务名称
   * @returns 任务id
   */
  addTask(name: string): Promise<number>{
    return this.rdbStore.insert(this.tableName, {name, finished: false})
  }

  /**
   * 根据id更新任务状态
   * @param id 任务id
   * @param finished 任务是否完成
   */
  updateTaskStatus(id: number, finished: boolean) {
    // 1.要更新的数据
    let data = {finished}
    // 2.更新的条件
    let predicates = new relationalStore.RdbPredicates(this.tableName)
    predicates.equalTo('ID', id)
    // 3.更新操作
    return this.rdbStore.update(data, predicates)
  }

  /**
   * 根据id删除任务
   * @param id 任务id
   */
  deleteTaskById(id: number){
    // 1.删除的条件
    let predicates = new relationalStore.RdbPredicates(this.tableName)
    predicates.equalTo('ID', id)
    // 2.删除操作
    return this.rdbStore.delete(predicates)
  }
}

let taskModel = new TaskModel();

export default taskModel as TaskModel;

  • ets/entryability/EntryAbility.ets
  • 应用启动时调用初始化
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import TaskModel from '../model/TaskModel';

export default class EntryAbility extends UIAbility {
  async onCreate(want, launchParam) {
    // 初始化任务表
    TaskModel.initTaskDB(this.context)
  }
}

  • 页面调用方法查询、添加数据
import TaskModel from '../../model/TaskModel'

 // 总任务数量
  @Link totalTask: number
  @Link finishTask: number
  // 任务数组
  @State tasks: TaskInfo[] = []
  
  aboutToAppear(){
    // 查询任务列表
    console.log('testTag', '初始化组件,查询任务列表')
    TaskModel.getTaskList()
      .then(tasks => {
        this.tasks = tasks
        // 更新任务状态
        this.handleTaskChange()
      })
  }

  handleTaskChange(){
    // 1.更新任务总数量
    this.totalTask = this.tasks.length
    // 2.更新已完成任务数量
    this.finishTask = this.tasks.filter(item => item.finished).length
  }

  handleAddTask(name: string){
    // 1.新增任务
    TaskModel.addTask(name)
      .then(id => {
        console.log('testTag', '处理新增任务: ', name)
        // 回显到数组页面
        this.tasks.push(new TaskInfo(id, name))
        // 2.更新任务完成状态
        this.handleTaskChange()
        // 3.关闭对话框
        this.dialogController.close()
      })
      .catch(error => console.log('testTag', '新增任务失败:', name, JSON.stringify(error)))

  }

@Builder DeleteButton(index: number, id: number){
    Button(){
      Image($r('app.media.ic_public_delete_filled'))
        .fillColor(Color.White)
        .width(20)
    }
    .width(40)
    .height(40)
    .type(ButtonType.Circle)
    .backgroundColor(Color.Red)
    .margin(5)
    .onClick(() => {
      // 删除任务
      TaskModel.deleteTaskById(id)
        .then(() => {
          this.tasks.splice(index, 1)
          console.log('testTag', `尝试删除任务,index: ${index}`)
          this.handleTaskChange()
        })
        .catch(error => console.log('testTag', '删除任务失败,id = ', id, JSON.stringify(error)))

    })
  }

二、通知

1、基础通知

  • 应用可以通过通知接口发送通知消息,提醒用户关注应用中变化。
  • 用户可以在通知栏查看和操作通知内容

(1)基础使用

  • 导入notification模块
import notificationManager from '@ohos.notificationManager';
  • 构建通知请求
let request: notificationManager.NotificationRequest = {
  id: 1, 
  content: {
  		// 通知内容:...
    }
  },
  showDeliveryTime: true, // 是否显示分发时间
  deliveryTime: new Date().getTime(), // 通知发送时间
  groupName: 'wechat', // 组通知名称
  slotType: notify.SlotType.SOCIAL_COMMUNICATION  // 通道类型
  ...   //其它属性查看相关文档
}
  • 发布通知
notificationManager.publish(request, (err) => {
  if (err) {
    console.error(`Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
    return;
  }
  console.info('Succeeded in publishing notification.');
});

  • 取消通知
// 取消 id=10 的通知
notificationManager.cancel(10)
// 取消当前应用所有通知
notificationManager.cancelAll()

(2)通知内容类型

  • 普通文本类型
let notificationRequest = {
  id: 1,
  content: {
    contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
    normal: {
      title: '通知标题',
      text: '通知内容详情',
      additionalText: '通知附加内容',
    }
  }
}
  • 长文本类型
let notificationRequest = {
  id: 1,
  content: {
    contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT, // 长文本类型通知
    longText: {
      title: '通知标题',
      text: '通知内容详情',
      additionalText: '通知附加内容',
      longText: '通知中的长文本、很长很长。。。',
      briefText: '通知概要总结',
      expandedTitle: '通知展开时的标题',
    }
  }
}
  • 多行文本类型
let notificationRequest = {
  id: 1,
  content: {
    contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE, // 多行文本类型通知
    multiLine: {
      title: '通知标题',
      text: '通知内容详情',
      additionalText: '通知附加内容',
      briefText: '通知概要总结',
      longTitle: '展开时的标题,有多行,我很宽',
      lines: ['第一行', '第二行', '第三行', '第四行'],
    }
  }
}

  • 图片类型
// 需要获取图片PixelMap信息
let imagePixelMap: PixelMap = undefined; 
let notificationRequest: notificationManager.NotificationRequest = {
  id: 1,
  content: {
    contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_PICTURE,
    picture: {
      title: '通知标题',
      text: '通知内容详情',
      additionalText: '通知附加内容',
      briefText: '通知概要总结',
      expandedTitle: '通知展开时的标题',
      picture: imagePixelMap
    }
  }
};

  • 获取图片PixelMap信息
async aboutToAppear() {
  // 获取资源管理器
  let rm = getContext(this).resourceManager;
  // 读取图片
  let file = await rm.getMediaContent($r('app.media.watchGT4'))
  // 创建PixelMap
  image.createImageSource(file.buffer).createPixelMap()
    .then(value => this.pixel = value)
    .catch(reason => console.log('testTag', '加载图片异常', JSON.stringify(reason)))
}

(3)完整代码示例

import notify from '@ohos.notificationManager'
import image from '@ohos.multimedia.image'

@Entry
@Component
struct NotificationPage {
  // 全局任务id
  idx: number = 100
  // 图象
  pixel: PixelMap

  async aboutToAppear() {
    // 获取资源管理器
    let rm = getContext(this).resourceManager;
    // 读取图片
    let file = await rm.getMediaContent($r('app.media.watchGT4'))
    // 创建PixelMap
    image.createImageSource(file.buffer).createPixelMap()
      .then(value => this.pixel = value)
      .catch(reason => console.log('testTag', '加载图片异常', JSON.stringify(reason)))
  }

  build() {
    Column({space: 20}) {
    
      Button(`发送normalText通知`)
        .onClick(() => this.publishNormalTextNotification())
      Button(`发送longText通知`)
        .onClick(() => this.publishLongTextNotification())
      Button(`发送multiLine通知`)
        .onClick(() => this.publishMultiLineNotification())
      Button(`发送Picture通知`)
        .onClick(() => this.publishPictureNotification())
    }
    .width('100%')
    .height('100%')
    .padding(5)
    .backgroundColor('#f1f2f3')
  }
  //通知普通文本
  publishNormalTextNotification() {
    let request: notify.NotificationRequest = {
      id: this.idx++,
      content: {
        contentType: notify.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
        normal: {
          title: '通知标题' + this.idx,
          text: '通知内容详情',
          additionalText: '通知附加内容'
        }
      },
      showDeliveryTime: true,
      deliveryTime: new Date().getTime(),
      groupName: 'wechat',
      slotType: notify.SlotType.SOCIAL_COMMUNICATION
    }
    this.publish(request)
  }
  //通知长文本
  publishLongTextNotification() {
    let request: notify.NotificationRequest = {
      id: this.idx++,
      content: {
        contentType: notify.ContentType.NOTIFICATION_CONTENT_LONG_TEXT,
        longText: {
          title: '通知标题' + this.idx,
          text: '通知内容详情',
          additionalText: '通知附加内容',
          longText: '通知中的长文本,我很长,我很长,我很长,我很长,我很长,我很长,我很长',
          briefText: '通知概要和总结',
          expandedTitle: '通知展开时的标题' + this.idx
        }
      }
    }
    this.publish(request)
  }
  //通知多行文本
  publishMultiLineNotification() {
    let request: notify.NotificationRequest = {
      id: this.idx++,
      content: {
        contentType: notify.ContentType.NOTIFICATION_CONTENT_MULTILINE,
        multiLine: {
          title: '通知标题' + this.idx,
          text: '通知内容详情',
          additionalText: '通知附加内容',
          briefText: '通知概要和总结',
          longTitle: '展开时的标题,我很宽,我很宽,我很宽',
          lines: [
            '第一行',
            '第二行',
            '第三行',
            '第四行',
          ]
        }
      }
    }
    this.publish(request)
  }
  //通知图片类型
  publishPictureNotification() {
    let request: notify.NotificationRequest = {
      id: this.idx++,
      content: {
        contentType: notify.ContentType.NOTIFICATION_CONTENT_PICTURE,
        picture: {
          title: '通知标题' + this.idx,
          text: '通知内容详情',
          additionalText: '通知附加内容',
          briefText: '通知概要和总结',
          expandedTitle: '展开后标题' + this.idx,
          picture: this.pixel
        }
      }
    }
    this.publish(request)
  }
  // 发送文本
  private publish(request: notify.NotificationRequest) {
    notify.publish(request)
      .then(() => console.log('notify test', '发送通知成功'))
      .then(reason => console.log('notify test', '发送通知失败', JSON.stringify(reason)))
  }
}

2、进度条通知

  • 进度条通知会展示一个动态的进度条,主要用于文件下载、长任务处理的进度显示。

(1)基础使用

  • 判断当前系统是否支持进度条模板
NotificationManager.isSupportTemplate('downloadTemplate').then((data) => {
  console.info(`[ANS] isSupportTemplate success`);
  let isSupportTpl: boolean = data; // isSupportTpl的值为true表示支持支持downloadTemplate模板类通知,false表示不支持
  // ...
}).catch((err) => {
  console.error(`[ANS] isSupportTemplate failed, error[${err}]`);
});
  • 通知模板
  • 模板名称,必须是 downloadTemplate
let template = {
  name:'downloadTemplate',
  data: {
    title: '标题:',
    fileName: 'music.mp4', // 文件名
    progressValue: 30, //进度条当前值
    progressMaxValue:100, // 进度条最大值
  }
}
  • 通知请求
let notificationRquest = {
  id: 1,
  slotType: notify.SlotType.OTHER_TYPES,
  template: template, //进度条模板
  content: {
    contentType: notify.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
    normal: {
      title: template.data.title + template.data.fileName,
      text: "sendTemplate",
      additionalText: "30%"
    }
  },
  deliveryTime: new Date().getTime(),
  showDeliveryTime: true
}
  • 发送通知,与基础通知相同

(3)完整代码示例

import notify from '@ohos.notificationManager'
import promptAction from '@ohos.promptAction'

enum DownloadState {
  NOT_BEGIN = '未开始',
  DOWNLOADING = '下载中',
  PAUSE = '已暂停',
  FINISHED = '已完成',
}

@Component
export default struct DownloadCard {
  // 下载进度
  @State progressValue: number = 0
  progressMaxValue: number = 100
  // 任务状态
  @State state: DownloadState = DownloadState.NOT_BEGIN

  // 下载的文件名
  filename: string = '圣诞星.mp4'

  // 模拟下载的任务的id
  taskId: number = -1

  // 通知id
  notificationId: number = 999

  isSupport: boolean = false

  async aboutToAppear(){
    // 1.判断当前系统是否支持进度条模板
    this.isSupport = await notify.isSupportTemplate('downloadTemplate')
  }

  build() {
    Row({ space: 10 }) {
      Image($r('app.media.ic_files_video')).width(50)
      Column({ space: 5 }) {
        Row() {
          Text(this.filename)
          Text(`${this.progressValue}%`).fontColor('#c1c2c1')
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)

        Progress({
          value: this.progressValue,
          total: this.progressMaxValue,
        })

        Row({ space: 5 }) {
          Text(`${(this.progressValue * 0.43).toFixed(2)}MB`)
            .fontSize(14).fontColor('#c1c2c1')
          Blank()
          if (this.state === DownloadState.NOT_BEGIN) {
            Button('开始').downloadButton()
              .onClick(() => this.download())

          } else if (this.state === DownloadState.DOWNLOADING) {
            Button('取消').downloadButton().backgroundColor('#d1d2d3')
              .onClick(() => this.cancel())

            Button('暂停').downloadButton()
              .onClick(() => this.pause())

          } else if (this.state === DownloadState.PAUSE) {
            Button('取消').downloadButton().backgroundColor('#d1d2d3')
              .onClick(() => this.cancel())

            Button('继续').downloadButton()
              .onClick(() => this.download())
          } else {
            Button('打开').downloadButton()
              .onClick(() => this.open())
          }
        }.width('100%')
      }
      .layoutWeight(1)
    }
    .width('100%')
    .borderRadius(20)
    .padding(15)
    .backgroundColor(Color.White)
  }


  cancel() {
    // 取消定时任务
    if(this.taskId > 0){
      clearInterval(this.taskId);
      this.taskId = -1
    }
    // 清理下载任务进度
    this.progressValue = 0
    // 标记任务状态:未开始
    this.state = DownloadState.NOT_BEGIN
    // 取消通知
    notify.cancel(this.notificationId)
  }

  download() {
    // 清理旧任务
    if(this.taskId > 0){
      clearInterval(this.taskId);
    }
    // 开启定时任务,模拟下载
    this.taskId = setInterval(() => {
      // 判断任务进度是否达到100
      if(this.progressValue >= 100){
        // 任务完成了,应该取消定时任务
        clearInterval(this.taskId)
        this.taskId = -1
        // 并且标记任务状态为已完成
        this.state = DownloadState.FINISHED
        // 发送通知
        this.publishDownloadNotification()
        return
      }
      // 模拟任务进度变更
      this.progressValue += 2
      // 发送通知
      this.publishDownloadNotification()
    }, 500)
    // 标记任务状态:下载中
    this.state = DownloadState.DOWNLOADING
  }

  pause() {
    // 取消定时任务
    if(this.taskId > 0){
      clearInterval(this.taskId);
      this.taskId = -1
    }
    // 标记任务状态:已暂停
    this.state = DownloadState.PAUSE
    // 发送通知
    this.publishDownloadNotification()
  }

  open() {
    promptAction.showToast({
      message: '功能未实现'
    })
  }

  publishDownloadNotification(){
    // 1.判断当前系统是否支持进度条模板
    if(!this.isSupport){
      // 当前系统不支持进度条模板
      return
    }
    // 2.准备进度条模板的参数
    let template = {
      name: 'downloadTemplate',
      data: {
        progressValue: this.progressValue,
        progressMaxValue: this.progressMaxValue
      }
    }
    let request: notify.NotificationRequest = {
      id: this.notificationId,
      template: template,
      content: {
        contentType: notify.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
        normal: {
          title: this.filename + ':  ' + this.state,
          text: '',
          additionalText: this.progressValue + '%'
        }
      }
    }
    // 3.发送通知
    notify.publish(request)
      .then(() => console.log('test', '通知发送成功'))
      .catch(reason => console.log('test', '通知发送失败!', JSON.stringify(reason)))
  }
}

@Extend(Button) function downloadButton() {
  .width(75).height(28).fontSize(14)
}

3、通知意图

  • 我们可以给通知或其中的按钮设置的行为意图(Want
  • 从而实现拉起应用组件或发布公共事件等能力。

(1)基础使用

  • 导入模块
import NotificationManager from '@ohos.notificationManager';
import wantAgent from '@ohos.app.ability.wantAgent';
  • 意图行为信息
let wantAgentInfo = {
    wants: [
        {
            deviceId: '',
            bundleName: 'com.example.test',
            abilityName: 'com.example.test.MainAbility',
            action: '',
            entities: [],
            uri: '',
            parameters: {}
        }
    ],
    operationType: wantAgent.OperationType.START_ABILITY,
    requestCode: 0,
    wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
}
  • 创建wantAgent实例
 // 用于保存创建成功的WantAgent对象,后续使用其完成触发的动作。
let wantAgentObj = null;

wantAgent.getWantAgent(wantAgentInfo, (err, data) => {
    if (err) {
        console.error('[WantAgent]getWantAgent err=' + JSON.stringify(err));
    } else {
        console.info('[WantAgent]getWantAgent success');
        wantAgentObj = data;
    }
});
  • 通知请求
let notificationRequest = {
    content: {
       // ....
    },
    id: 1,
    label: 'TEST',
    wantAgent: wantAgentObj,
}

(2)完整代码示例

import wantAgent, { WantAgent } from '@ohos.app.ability.wantAgent'
import promptAction from '@ohos.promptAction'


@Component
export default struct DownloadCard {
  // 存放wantAgent实例
  wantAgentInstance: WantAgent
  
  async aboutToAppear(){
    // 1.判断当前系统是否支持进度条模板
    this.isSupport = await notify.isSupportTemplate('downloadTemplate')
    // 2.创建拉取当前应用的行为意图
    // 2.1.创建wantInfo信息
    let wantInfo: wantAgent.WantAgentInfo = {
      wants: [
        {
          bundleName: 'com.example.myapplication',
          abilityName: 'EntryAbility',
        }
      ],
      requestCode: 0,
      operationType: wantAgent.OperationType.START_ABILITY,
      wantAgentFlags: [wantAgent.WantAgentFlags.CONSTANT_FLAG]
    }
    // 2.2.创建wantAgent实例
    this.wantAgentInstance = await wantAgent.getWantAgent(wantInfo)
  }

  build() {
    ···· 
    // 同进度条通知代码示例
  }

  open() {
    promptAction.showToast({
      message: '功能未实现'
    })
  }

  publishDownloadNotification(){
    // 1.判断当前系统是否支持进度条模板
    if(!this.isSupport){
      // 当前系统不支持进度条模板
      return
    }
    // 2.准备进度条模板的参数
    let template = {
      name: 'downloadTemplate',
      data: {
        progressValue: this.progressValue,
        progressMaxValue: this.progressMaxValue
      }
    }
    let request: notify.NotificationRequest = {
      id: this.notificationId,
      template: template,
      // 通知意图
      wantAgent: this.wantAgentInstance,
      
      content: {
        contentType: notify.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
        normal: {
          title: this.filename + ':  ' + this.state,
          text: '',
          additionalText: this.progressValue + '%'
        }
      }
    }
    // 3.发送通知
    notify.publish(request)
      .then(() => console.log('test', '通知发送成功'))
      .catch(reason => console.log('test', '通知发送失败!', JSON.stringify(reason)))
  }
}

@Extend(Button) function downloadButton() {
  .width(75).height(28).fontSize(14)
}
  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值