【鸿蒙开发实战案例】手机应用使用信息统计

概述

本示例主要展示了设备使用信息情况。

样例展示

在这里插入图片描述

基础信息

在这里插入图片描述

设备使用信息统计

介绍

本示例使用[bundleState]相关接口完成设备中应用时长的统计功能。

效果预览

使用说明:

1.顶部的数据面板展示了最常用的五个应用的使用时间占比情况。

2.中部的竖向滑动栏展示了每个应用的使用总时长和最后一次使用的时间。

3.底部的横向滑动栏展示了不常用应用列表。

具体实现

●该示例使用bundleState接口中isIdleState方法判断指定bundleName的应用当前是否是空闲状态来分类不常用应用列表,queryBundleStateInfos方法通过指定起始和结束时间查询应用使用时长统计信息来获得每个应用的使用总时长。
●源码链接:[BundleStateUtil.ets]

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import usageStatistics from '@ohos.resourceschedule.usageStatistics'

import AppTime from '../model/AppTime'

import Logger from './Logger'

import { AppInfo, appInit } from '../model/AppInfo'

import { getAppName, getAppIcon, getTimStr } from './Util'



const TAG: string = 'BundleStateUtil'

const BEGIN_HOURS: number = 0

const BEGIN_MINUTES: number = 0

const BEGIN_SECONDS: number = 0

const END_HOURS: number = 23

const END_MINUTES: number = 59

const END_SECONDS: number = 59



export class BundleStateUtil {

  private apps: Array<AppInfo> = appInit()

  private freeApps: Array<AppInfo> = []



  /**

   * 获取不常用应用列表

   */

  async getFreeAppList(): Promise<Array<AppInfo>> {

    for (let appsKey in this.apps) {

      let bundleName = this.apps[appsKey].bundleName

      let isIdleState = await usageStatistics.isIdleState(bundleName)

      if (isIdleState) {

        this.freeApps.push({ bundleName: bundleName, name: getAppName(bundleName), icon: getAppIcon(bundleName) })

      }

      Logger.info(TAG, `freeApps=${JSON.stringify(this.freeApps)}`)

    }

    return this.freeApps

  }



  /**

   * 获取所有应用使用时间列表

   */

  async getTotalAppList(): Promise<Array<AppTime>> {

    let dateBegin = new Date()

    // 设置开始时间为00:00:00

    dateBegin.setHours(BEGIN_HOURS)

    dateBegin.setMinutes(BEGIN_MINUTES)

    dateBegin.setSeconds(BEGIN_SECONDS)

    Logger.info(TAG, `dateBegin= ${getTimStr(dateBegin)} ${dateBegin.toString()}`)

    let dateEnd = new Date()

    // 设置结束时间为23:59:59

    dateEnd.setHours(END_HOURS)

    dateEnd.setMinutes(END_MINUTES)

    dateEnd.setSeconds(END_SECONDS)

    Logger.info(TAG, `dateEnd= ${getTimStr(dateEnd)} ${dateEnd.toString()}`)

    let res = await usageStatistics.queryBundleStatsInfos(Date.parse(dateBegin.toString()), Date.parse(dateEnd.toString()))

    Logger.info(TAG, `queryBundleStateInfos promise success`)

    let list: Array<AppTime> = []

    for (let key in res) {

      if (res.hasOwnProperty(key)) {

        Logger.info(TAG, `queryBundleStateInfos promise result ${JSON.stringify(res[key])}`)

        let appTime = new AppTime(res[key].bundleName, res[key].abilityPrevAccessTime, res[key].abilityInFgTotalTime)

        list.push(appTime)

      }

    }

    return list

  }

}

[FreeApps.ets]

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import { AppInfo, appInit, BundleStateUtil } from 'feature-util'



const TAG = 'FreeApps'



@Component

export struct FreeApps {

  @State apps: Array<AppInfo> = appInit()

  @State freeApps: Array<AppInfo> = []



  aboutToAppear() {

    this.getFreeApps()

  }



  async getFreeApps() {

    let bundleStateUtil = new BundleStateUtil()

    this.freeApps = await bundleStateUtil.getFreeAppList()

  }



  build() {

    Column() {

      Text($r('app.string.free_apps'))

        .width('80%')

        .fontSize(20)

        .fontWeight(FontWeight.Bold)

        .direction(Direction.Ltr)

        .margin({ bottom: 10 })

      Column() {

        Scroll() {

          Row() {

            ForEach(this.freeApps, (item) => {

              Column() {

                Image(item.icon)

                  .margin({ top: 10 })

                  .width(70)

                  .height(70)

                  .objectFit(ImageFit.Fill)

                Text(item.name)

                  .fontSize(10)

                  .margin({ top: 5 })

              }

              .width(70)

              .height(120)

              .margin(10)

            }, item => item.name)

          }

          .borderRadius(10)

          .backgroundColor(Color.White)

        }

        .margin(5)

        .width('90%')

        .scrollable(ScrollDirection.Horizontal)

      }

      .width('95%')

      .padding(10)

    }.margin({ top: 20 })

  }

}

[PanelView.ets]

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import { AppTime, BundleStateUtil, getAppName, getTotalTime } from 'feature-util'



const TAG = 'PanelView'

const oftenUsed = 5



@Component

export struct PanelView {

  @State statisticals: Array<AppTime> = []

  @State panelName: string[] = []

  @State panelValue: number[] = []

  @State totalTime: number = 0

  @State panelViewHeight: number = 0



  aboutToAppear() {

    this.getTime()

  }



  async getTime() {

    let bundleStateUtil = new BundleStateUtil()

    let list = await bundleStateUtil.getTotalAppList()



    this.totalTime = getTotalTime(list)

    list.sort((a, b) => b.totalTime - a.totalTime)

    this.statisticals = list

    let topFiveTotalTime = 0

    for (let i = 0;i < oftenUsed; i++) {

      this.panelName.push(getAppName(this.statisticals[i].bundleName))

      this.panelValue.push(this.statisticals[i].totalTime)

      topFiveTotalTime += this.statisticals[i].totalTime

    }

    this.panelName.push('others')

    this.panelValue.push(this.totalTime - topFiveTotalTime)

  }



  build() {

    Column() {

      Text($r('app.string.application_duration'))

        .fontSize(20)

        .width('100%')

        .margin({ top: 10 })

        .textAlign(TextAlign.Center)

      Row() {

        DataPanel({ values: this.panelValue, max: this.totalTime, type: DataPanelType.Circle })

          .width(200)

          .height(200)

        Column() {

          ForEach(this.panelName, (item) => {

            Text(item)

              .fontSize(20)

              .margin({ top: 5 })

          }, item => item)

        }

        .margin({ top: 10, left: 35 })

      }

      .height(250)

      .margin({ top: 10 })

      .alignSelf(ItemAlign.Center)



    }

    .width('100%')

    .onAreaChange((oldArea: Area, newArea: Area) => {

      this.panelViewHeight = (newArea.height) as number * 0.3 // percentage

    })

  }

}

[UsageList.ets]

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import { AppTime, BundleStateUtil, hmsToString, getAppName, getAppIcon, getTotalTime } from 'feature-util'



const TAG = 'UsageList'



@Component

export struct UsageList {

  @State statisticals: Array<AppTime> = []

  @State totalTime: number = 0



  aboutToAppear() {

    this.getTime()

  }



  async getTime() {

    let bundleStateUtil = new BundleStateUtil()

    let list = await bundleStateUtil.getTotalAppList()



    this.totalTime = getTotalTime(list)

    list.sort((a, b) => b.totalTime - a.totalTime)

    this.statisticals = list

  }



  build() {

    Column() {

      Text(hmsToString(this.totalTime / 1000))

        .width('80%')

        .fontSize(30)

        .textAlign(TextAlign.Start)

        .fontWeight(FontWeight.Bold)

        .margin({ top: 15, bottom: 15 })

      Scroll() {

        Column() {

          ForEach(this.statisticals, (item) => {

            Row() {

              Image(getAppIcon(item.bundleName))

                .width(80)

                .height(80)

                .objectFit(ImageFit.Fill)

              Column() {

                Row() {

                  Text(getAppName(item.bundleName))

                    .width('60%')

                    .fontSize(25)

                    .fontWeight(FontWeight.Bold)

                  Text(hmsToString(Math.floor(item.totalTime / 1000)))

                    .width('40%')

                    .fontSize(22)

                    .textAlign(TextAlign.End)

                }

                .width('100%')

                .alignSelf(ItemAlign.Start)



                Progress({ value: item.totalTime, total: this.totalTime, type: ProgressType.Linear })

                  .height(20)

                  .width('100%')

                  .color(Color.Grey)

                  .margin({ top: 12 })

                  .style({ strokeWidth: 10 })

                  .alignSelf(ItemAlign.Start)



                Row() {

                  Text($r('app.string.application_last_used')).fontSize(15)

                  Text(hmsToString(Math.floor(item.prevAccessTime / 1000))).fontSize(15)

                }

              }

              .alignItems(HorizontalAlign.Start)

              .layoutWeight(1)

              .padding({ left: 5, right: 5 })

            }

            .height(95)

            .margin({ bottom: 50 })

          }, item => item.bundleName)

        }

        .justifyContent(FlexAlign.Start)

      }

      .width('90%')

      .height('80%')

      .scrollBar(BarState.Off)

      .backgroundColor(Color.White)

      .scrollable(ScrollDirection.Vertical)

      .borderRadius(10)

      .padding(20)

    }

    .width('100%')

    .height('55%')

    .margin({ top: 40 })

  }

}

写在最后

有很多小伙伴不知道该从哪里开始学习鸿蒙开发技术?也不知道鸿蒙开发的知识点重点掌握的又有哪些?自学时频繁踩坑,导致浪费大量时间。结果还是一知半解。所以有一份实用的鸿蒙(HarmonyOS NEXT)全栈开发资料用来跟着学习是非常有必要的。

获取完整版高清学习资料,请点击→鸿蒙全栈开发学习资料(安全链接,请放心点击)

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了

最新鸿蒙全栈开发学习线路在这里插入图片描述

鸿蒙HarmonyOS开发教学视频

在这里插入图片描述

大厂面试真题

在这里插入图片描述

在这里插入图片描述

鸿蒙OpenHarmony源码剖析

在这里插入图片描述

这份资料能帮住各位小伙伴理清自己的学习思路,更加快捷有效的掌握鸿蒙开发的各种知识。有需要的小伙伴自行领取,,先到先得~无套路领取!!

获取这份完整版高清学习资料,请点击→鸿蒙全栈开发学习资料(安全链接,请放心点击)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值