介绍

本篇Codelab使用ArkTS语言实现计步器应用,应用主要包括计步传感器、定位服务和后台任务功能:

1.  通过订阅计步器传感器获取计步器数据,处理后显示。

2.  通过订阅位置服务获取位置数据,处理后显示。

3.  通过服务开发实现后台任务功能。

相关概念

计步传感器:订阅计步器传感器数据,系统返回相关数据。

后台任务管理:应用中存在用户能够直观感受到的且需要一直在后台运行的业务时(如,后台播放音乐),可以使用长时任务机制。

位置服务:位置服务提供GNSS定位、网络定位、地理编码、逆地理编码、国家码和地理围栏等基本功能。

相关权限

本篇Codelab用到了计步传感器、后台任务及位置服务功能,需要在配置文件module.json5里添加权限:

● ohos.permission.ACTIVITY_MOTION

● ohos.permission.KEEP_BACKGROUND_RUNNING

● ohos.permission.APPROXIMATELY_LOCATION

● ohos.permission.LOCATION

● ohos.permission.LOCATION_IN_BACKGROUND

完整示例

gitee源码地址

源码下载

计步器应用(ArkTS).zip

环境搭建

我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。

软件要求

DevEco Studio版本:DevEco Studio 3.1 Release。

HarmonyOS SDK版本:API version 9。

硬件要求

设备类型:华为手机或运行在DevEco Studio上的华为手机设备模拟器。

HarmonyOS系统:3.1.0 Developer Release。

环境搭建

安装DevEco Studio,详情请参考下载和安装软件

设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。

如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

开发者可以参考以下链接,完成设备调试的相关配置:使用真机进行调试

使用模拟器进行调试

代码结构解读

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在源码下载或gitee中提供。

├──entry/src/main/ets               // 代码区
│ ├──common
│ │ ├──constants
│ │ │ └──CommonConstants.ets // 公共常量
│ │ └──utils // 日志类
│ │ ├──BackgroundUtil.ets // 后台任务工具类
│ │ ├──GlobalContext.ets // 首选项工具类
│ │ ├──LocationUtil.ets // 位置服务工具类
│ │ ├──Logger.ets // 日志工具类
│ │ ├──NumberUtil.ets // 数字处理工具类
│ │ └──StepsUtil.ets // 计步器工具类
│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口类
│ ├──pages
│ │ └──HomePage.ets // 应用首页
│ └──view
│ ├──CompletionStatus.ets // 目标设置页
│ ├──CurrentSituation.ets // 计步信息页
│ └──InputDialog.ets // 自定义弹窗
└──entry/src/main/resources // 资源文件夹

  

构建应用界面

计步器页面主要由Stack堆叠容器组件、Component自定义组件和CustomDialog自定义弹窗组件完成页面布局,效果如图所示:

// HomePage.ets
build() {
Stack({ alignContent: Alignment.TopStart }) {
CompletionStatus({
progressValue: $progressValue
}) CurrentSituation({
currentSteps: this.currentSteps,
startPosition: this.startPosition,
currentLocation: this.currentLocation
}) Row() {
Button(this.isStart ? $r('app.string.stop') : $r('app.string.start'))
...
}
...
}
...
}

  

计步传感器

应用启动后申请计步传感器权限,获取权限后订阅计步器传感器。通过订阅获取到计步传感器数据,解析处理后在页面显示。效果如图所示:

// HomePage.ets
requestPermissions(): void {
let atManager = abilityAccessCtrl.createAtManager();
try {
atManager.requestPermissionsFromUser(this.context, CommonConstants.REQUEST_PERMISSIONS).then((data) => {
if (data.authResults[0] !== 0 || data.authResults[1] !== 0) {
return;
}
const that = this;
try {
sensor.on(sensor.SensorId.PEDOMETER, (data) => {
try {
if (that.isStart) {
if (StepsUtil.checkStrIsEmpty(that.oldSteps)) {
that.oldSteps = data.steps.toString();
StepsUtil.putStorageValue(CommonConstants.OLD_STEPS, that.oldSteps);
} else {
that.currentSteps = (data.steps - NumberUtil._parseInt(that.oldSteps, 10)).toString();
}
} else {
that.currentSteps = data.steps.toString();
} if (StepsUtil.checkStrIsEmpty(that.stepGoal) || !that.isStart) {
return;
}
StepsUtil.putStorageValue(CommonConstants.CURRENT_STEPS, that.currentSteps);
that.progressValue = StepsUtil.getProgressValue(NumberUtil._parseInt(that.stepGoal, 10),
NumberUtil._parseInt(that.currentSteps, 10));
StepsUtil.putStorageValue(CommonConstants.PROGRESS_VALUE_TAG, String(that.progressValue));
} catch (err) {
Logger.error(TAG, 'Sensor on err' + JSON.stringify(err));
}
}, { interval: CommonConstants.SENSOR_INTERVAL });
...
}

  

位置服务

应用启动后申请位置服务权限,获取权限后启动服务,启动服务后订阅位置服务。通过订阅获取到位置服务数据,解析处理后在页面显示。效果如图所示:

// HomePage.ets
requestPermissions(): void {
...
LocationUtil.geolocationOn((location: geoLocationManager.Location) => {
if (this.latitude === location.latitude && this.longitude === location.longitude) {
return;
}
this.latitude = location.latitude;
this.longitude = location.longitude;
let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest = {
'latitude': this.latitude,
'longitude': this.longitude
};
geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest).then(data => {
if (data[0].placeName) {
this.currentLocation = data[0].placeName;
}
}).catch((err: Error) => {
Logger.error(TAG, 'GetAddressesFromLocation err ' + JSON.stringify(err));
});
});
...
}

  

将位置服务相关的函数封装到工具类中。

// LocationUtil.ets
class LocationUtil {
geolocationOn(locationChange: (location: geoLocationManager.Location) => void): void {
let requestInfo: geoLocationManager.LocationRequest = {
'priority': 0x203,
'scenario': 0x300,
'timeInterval': 0,
'distanceInterval': 0,
'maxAccuracy': 0
}
try {
geoLocationManager.on('locationChange', requestInfo, locationChange);
} catch (err) {
console.error("locationChange error:" + JSON.stringify(err));
}
} geolocationOff(): void {
geoLocationManager.off('locationChange');
}
}

  

后台任务

点击开始按钮开启后台任务,通过后台任务管理方法配置申请的后台模式等参数启动后台任务。

// HomePage.ets
build() {
Stack({ alignContent: Alignment.TopStart }) {
...
Row() {
Button(this.isStart ? $r('app.string.stop') : $r('app.string.start'))
...
.onClick(() => {
if (this.isStart) {
...
BackgroundUtil.stopContinuousTask(this.context);
} else {
if (this.stepGoal === '' || this.currentLocation === '') {
promptAction.showToast({ message: CommonConstants.WAIT });
} else {
...
BackgroundUtil.startContinuousTask(this.context);
}
}
StepsUtil.putStorageValue(CommonConstants.IS_START, String(this.isStart));
})
}
...
} // BackgroundUtil.ets
export class BackgroundUtil {
public static startContinuousTask(context: common.UIAbilityContext): void {
let wantAgentInfo: wantAgent.WantAgentInfo = {
wants: [
{
bundleName: context.abilityInfo.bundleName,
abilityName: context.abilityInfo.name
}
],
operationType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
}; wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
try {
backgroundTaskManager.startBackgroundRunning(context,
backgroundTaskManager.BackgroundMode.LOCATION, wantAgentObj).then(() => {
Logger.info(TAG, 'startBackgroundRunning succeeded');
}).catch((err: Error) => {
Logger.error(TAG, `startBackgroundRunning failed Cause: ${JSON.stringify(err)}`);
});
} catch (error) {
Logger.error(TAG, `stopBackgroundRunning failed. error: ${JSON.stringify(error)} `);
}
});
} public static stopContinuousTask(context: common.UIAbilityContext): void {
try {
backgroundTaskManager.stopBackgroundRunning(context).then(() => {
Logger.info(TAG, 'stopBackgroundRunning succeeded');
}).catch((err: Error) => {
Logger.error(TAG, `stopBackgroundRunning failed Cause: ${JSON.stringify(err)}`);
});
} catch (error) {
Logger.error(TAG, `stopBackgroundRunning failed. error:${JSON.stringify(error)} `);
}
}
}

  

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

1.  计步器传感器的功能实现。

2.  位置服务的功能实现。

3.  后台任务的功能实现。

在HarmonyOS上使用ArkUI实现计步器应用的更多相关文章

  1. 【HarmonyOS】【ArkUI】在Service中使用Emitter

    ​ 参考资料 1.相关基础知识:触发器Emitter2.启动服务:ServiceAbility开发 开发步骤 第一步:开发界面,界面内容由一个按钮组件+文本组件构成,然后在按钮组件中添加点击事件,开启 ...

  2. iOS 计步器的几种实现方式

    代码地址如下:http://www.demodashi.com/demo/11658.html 这篇文章介绍两种可以获取计步数据的方法,一种是采用CMPedometer获取手机计步器数据,另一种是采用 ...

  3. HarmonyOS三方件开发指南(15)-LoadingView功能介绍

    目录: 1. LoadingView组件功能介绍2. Lottie使用方法3. Lottie开发实现4.<HarmonyOS三方件开发指南>系列文章合集 1. LoadingView组件功 ...

  4. HarmonyOS开发者看过来,HDD上海站传递的重要信息都在这里

    4月17日,颇有HarmonyOS年度总结性质的HarmonyOS开发者日活动上海站正式开始. 活动中,华为消费者业务AI与智慧全场景业务部副总裁段孟对HarmonyOS生态建设的最新进展做了发言,并 ...

  5. HDC2021技术分论坛:“积木拼装”,HarmonyOS弹性部署大揭秘!

    作者:peitaiyi,华为终端OS产品交付专家 HarmonyOS是一款面向万物互联时代的.全新的分布式操作系统.在传统的单设备系统能力基础上,HarmonyOS提出了基于同一套系统能力.适配多种终 ...

  6. 360携手HarmonyOS打造独特的“天气大师”

    做创新,首先要找到有增长趋势的流量红利,对我们来说,HarmonyOS就是绝佳的合作伙伴. --申悦 360手机助手创研产品部负责人 一.我们是谁? 我们来自360,是一支致力于孵化新业务的内部创新小 ...

  7. CC2540 USB Dongle 使用说明

    CC2540做的USB Dongle可以烧写不同的固件从而做很多PC端的应用,下面我们来介绍下下载固件的方法和一些典型应用: 下载接口: 3V3引脚连接到CC Debugger的Target Volt ...

  8. HDC2021技术分论坛:进程崩溃/应用卡死,故障频频怎么办?

    ​作者:jiwenqiang,DFX技术专家 提到开发一个产品,我们通常首先想到的是要实现什么样的功能,但是除了功能之外,非功能属性也会很大程度上影响一个产品的体验效果,比如不定时出现的应用卡死.崩溃 ...

  9. 从本质上学会基于HarmonyOS开发Hi3861(主要讲授方法)

    引言:花半秒钟就看透事物本质的人,和花一辈子都看不透事物本质的人,注定是截然不同的命运 做开发也一样,如果您能看透开发的整个过程,就不会出现"学会了某个RTOS的开发,同样的RTOS开发换一 ...

  10. 【HarmonyOS】【Demo】【JAVA UI】 鸿蒙怎么在Webview上添加组件

    在大家HarmonyOS开发中,Webview组件上添加组件可能是很常见的功能了,HarmonyOS的webview和Android的webwiew存在一点点区别,今天来实现这个功能 使用项目布局显示 ...

随机推荐

  1. 【Azure Developer】AAD API如何获取用户“Block sign in”信息(accountEnabled)

    问题描述 使用API获取所有Azure AD中的用户列表,API所参考的文档:https://docs.microsoft.com/en-us/graph/api/user-list?view=gra ...

  2. 【Azure 应用服务】App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢?

    问题描述 App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢? 问题解答 答案是可以的,Azure App Service .NE ...

  3. UI自动化测试中图片验证码的处理?

    首先定位验证码image的元素,然后通过element.screenshot('a.png')截图保存到本地,通过第三方接口识别本地图片验证码

  4. python删除指定文件夹下文件和文件夹的方法

    前记   python删除指定文件夹下的文件,是一个常用的功能.我找了不少地方,一直没有找到合适的模版,那只好自己倒腾一个比较实用的模版了. 基本模块   这里面会用到几个模块,一个是目录下所有文件的 ...

  5. 几个常用的cmd命令

    compmgmt.msc 计算机管理  devmgmt.msc 设备管理器  diskmgmt.msc 磁盘管理工具  dfrg.msc 磁盘碎片整理  eventvwr.msc 事件查看器  fsm ...

  6. 26_H.264编码实战

    目录 使用FFmpeg命令进行H.264编码 使用FFmpeg代码实现H.264编码 1.获取编码器 2.创建上下文 3.打开编码器 4.创建 AVFrame 5.创建 AVPacket 6.打开文件 ...

  7. 3DCAT实时云渲染助力广府庙会元宇宙焕新亮相,开启线上奇趣之旅!

    超 400 万人次打卡,商圈营业额逾 3.6 亿元,2023 年广府庙会于2023年2月11日圆满落幕. 活动期间,佳境美如画,融合VR.AR.虚拟直播等技术的广府庙会元宇宙焕新亮相,群众只需点击一个 ...

  8. npm ERR! code ENOENT npm ERR! syscall open npm ERR! path C:\Users\shuzi\Desktop\保密文件项目\test-ui/package.json npm ERR! errno -4058

    打开一个新的项目,因为当前项目文件夹下没有npm,"dev": "npm run start:dev",所以所以没有展示对应的运行图,如下图: 打开一个新的前端 ...

  9. 记录-有意思的气泡 Loading 效果

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 今日,群友提问,如何实现这么一个 Loading 效果: 这个确实有点意思,但是这是 CSS 能够完成的? 没错,这个效果中的核心气泡效果 ...

  10. sklearn库主要模块功能简介

    1.sklearn库简介 sklearn,全称scikit-learn,是python中的机器学习库,建立在numpy.scipy.matplotlib等数据科学包的基础之上,涵盖了机器学习中的样例数 ...