鸿蒙NEXT开发-位置服务(基于最新api12稳定版)

news/2024/11/18 13:55:50 标签: harmonyos, 华为

注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下

如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识

专栏地址: https://blog.csdn.net/qq_56760790/category_12794123.html

鸿蒙next学习交流

qq群号:767465523

目录

1. 位置服务基本介绍

2. 申请位置权限

3. 获取设备的位置信息

3.1 基本介绍

3.2 接口说明

3.3 代码实现

3.3.1 配置文件加上位置权限信息

3.3.2 获取坐标代码

3.3.3 将经纬度坐标转换成实际地理位置信息(地理编码转化)

4. 学习地址


1. 位置服务基本介绍

移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。

鸿蒙的位置服务(Location Kit)提供了基础的定位服务,还提供了地理围栏、地理编码、逆地理编码、国家码等功能和接口。

使用位置时服务请打开设备“位置”开关。如果位置功能关闭并且代码未设置捕获异常,可能导致应用异常。模拟器不行,大家记得在真机上测试使用位置服务。

2. 申请位置权限

应用在使用Location Kit系统能力前,需要检查是否已经获取用户授权访问设备位置信息。如未获得授权,可以向用户申请需要的位置权限。

系统提供的定位权限有:

  • ohos.permission.LOCATION:用于获取精准位置,精准度在米级别。
  • ohos.permission.APPROXIMATELY_LOCATION:用于获取模糊位置,精确度为5公里。
  • ohos.permission.LOCATION_IN_BACKGROUND:用于应用切换到后台仍然需要获取定位信息的场景。

当应用需要访问用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等,应该向用户请求授权,这部分权限是user_grant权限。

当应用申请user_grant权限时,需要完成以下步骤:

  1. 在配置文件中,声明应用需要请求的权限。
  2. 将应用中需要申请权限的目标对象与对应目标权限进行关联,让用户明确地知道,哪些操作需要用户向应用授予指定的权限。
  3. 运行应用时,在用户触发访问操作目标对象时应该调用接口,精准触发动态授权弹框。该接口的内部会检查当前用户是否已经授权应用所需的权限,如果当前用户尚未授予应用所需的权限,该接口会拉起动态授权弹框,向用户请求授权。
  4. 检查用户的授权结果,确认用户已授权才可以进行下一步操作。

"requestPermissions":[
  {
    "name" : "ohos.permission.APPROXIMATELY_LOCATION",
    "reason": "$string:permission_location",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when":"inuse"
    }
  }
],

官方文档:

文档中心

3. 获取设备的位置信息

3.1 基本介绍

开发者可以调用HarmonyOS位置相关接口,获取设备实时位置,或者最近的历史位置,以及监听设备的位置变化。

对于位置敏感的应用业务,建议获取设备实时位置信息。如果不需要设备实时位置信息,并且希望尽可能的节省耗电,开发者可以考虑获取最近的历史位置。

3.2 接口说明

获取设备的位置信息接口介绍

接口名

功能描述

on(type: 'locationChange', request: LocationRequest | ContinuousLocationRequest, callback: Callback<Location>): void

开启位置变化订阅,并发起定位请求。

off(type: 'locationChange', callback?: Callback<Location>): void

关闭位置变化订阅,并删除对应的定位请求。

getCurrentLocation(request: CurrentLocationRequest | SingleLocationRequest, callback: AsyncCallback<Location>): void

获取当前位置,使用callback回调异步返回结果。

getCurrentLocation(request?: CurrentLocationRequest | SingleLocationRequest): Promise<Location>

获取当前位置,使用Promise方式异步返回结果。

getLastLocation(): Location

获取最近一次定位结果。

3.3 代码实现

3.3.1 配置文件加上位置权限信息

注意:记得在module.json5配置位置权限

"requestPermissions":[
  {
    "name" : "ohos.permission.APPROXIMATELY_LOCATION",
    "reason": "$string:permission_location",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when":"inuse"
    }
  }
],

3.3.2 获取坐标代码

import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit'
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State location: string = ''
  @State latitude: number = 0
  @State longitude: number = 0

  /**
   * 动态授权
   */
  aboutToAppear(): void {
    // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
    const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
    // 定义要申请的权限
    const permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION'];
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
    atManager.requestPermissionsFromUser(context, permissions).then((data) => {
      let grantStatus: Array<number> = data.authResults;
      let length: number = grantStatus.length;
      for (let i = 0; i < length; i++) {
        if (grantStatus[i] === 0) {
          // 用户授权,可以继续访问目标操作
          promptAction.showToast({
            message: '用户授权当前定位功能成功'
          })
        } else {
          // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
          promptAction.showToast({
            message: '用户必须授权才能访问当前定位功能'
          })
          return;
        }
      }
      // 授权成功
    }).catch((err: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

  /**
   * 获取位置
   */
  getLocation() {
    let request: geoLocationManager.SingleLocationRequest = {
      'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED,
      'locatingTimeoutMs': 10000
    }
    try {
      geoLocationManager.getCurrentLocation(request).then((result) => { // 调用getCurrentLocation获取当前设备位置,通过promise接收上报的位置
        console.log('current location: ' + JSON.stringify(result));
        this.latitude = result.latitude
        this.longitude = result.longitude
      })
        .catch((error: BusinessError) => { // 接收上报的错误码
          console.error('promise, getCurrentLocation: error=' + JSON.stringify(error));
        });
    } catch (err) {
      console.error("errCode:" + JSON.stringify(err));
    }
  }

  build() {
    Column() {
      Button('获取当前位置').onClick(() => {
        this.getLocation()
      }).margin(100)

      Text('当前位置')
      Text('纬度:'+this.latitude)
      Text('经度:'+this.longitude)

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

  }
}

3.3.3 将经纬度坐标转换成实际地理位置信息(地理编码转化)

import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit'
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';

@Entry
  @Component
  struct Index {
    @State location: string = ''
    @State latitude: number = 0
    @State longitude: number = 0

    /**
    * 动态授权
    */
    aboutToAppear(): void {
      // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
      const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
      // 定义要申请的权限
      const permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION'];
      let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
      // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
      atManager.requestPermissionsFromUser(context, permissions).then((data) => {
        let grantStatus: Array<number> = data.authResults;
        let length: number = grantStatus.length;
        for (let i = 0; i < length; i++) {
          if (grantStatus[i] === 0) {
            // 用户授权,可以继续访问目标操作
            promptAction.showToast({
              message: '用户授权当前定位功能成功'
            })
          } else {
            // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
            promptAction.showToast({
              message: '用户必须授权才能访问当前定位功能'
            })
            return;
          }
        }
        // 授权成功
      }).catch((err: BusinessError) => {
        console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
      })
    }

    /**
   * 获取位置
   */
    getLocation() {
      let request: geoLocationManager.SingleLocationRequest = {
        'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED,
        'locatingTimeoutMs': 10000
      }
      try {
        geoLocationManager.getCurrentLocation(request).then((result) => { // 调用getCurrentLocation获取当前设备位置,通过promise接收上报的位置
          console.log('current location: ' + JSON.stringify(result));
          // 获取坐标
          this.latitude = result.latitude
          this.longitude = result.longitude
          // 判断地理编码服务是否可用
          try {
            let isAvailable = geoLocationManager.isGeocoderAvailable();
            if (isAvailable) {
              let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest =
                { "latitude": this.latitude, "longitude": this.longitude, "maxItems": 1 };
              try {
                geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => {
                  if (err) {
                    console.log('getAddressesFromLocation err: ' + JSON.stringify(err));
                  } else {
                    console.log('getAddressesFromLocation data: ' + JSON.stringify(data));
                    // 成功获取到位置信息
                    this.location = data[0].placeName+''
                    return
                  }
                });
              } catch (err) {
                console.error("errCode:" + JSON.stringify(err));
              }
                }else{
            promptAction.showToast({
              message: '地理编码服务不可用'
            })
          }

        } catch (err) {
          console.error("errCode:" + JSON.stringify(err));
        }
      })
        .catch((error: BusinessError) => { // 接收上报的错误码
          console.error('promise, getCurrentLocation: error=' + JSON.stringify(error));
        });
    } catch (err) {
      console.error("errCode:" + JSON.stringify(err));
    }
  }

  build() {
    Column() {
      Button('获取当前位置').onClick(() => {
        this.getLocation()
      }).margin(100)

      Text('当前位置')
      Text('当前具体位置:' + this.location)

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

  }
}

4. 学习地址

全网首发鸿蒙NEXT星河版零基础入门到实战,2024年最新版,企业级开发!视频陆续更新中!_哔哩哔哩_bilibili


http://www.niftyadmin.cn/n/5756116.html

相关文章

《探索Zynq MPSoC》学习笔记(三)

引言&#xff1a;本文简要介绍FPGA器件技术发展以及当今FPGA器件的体系架构和特性。 第二章 FPGA、Zynq和Zynq MPSoC&#xff08;2&#xff09; 在本章涵盖的三种器件类型中&#xff0c;FPGA是建立时间最长的&#xff0c;也是Zynq和Zynq MPSoC器件PL元件的基础。因此&#xf…

reactflow 中 reactflowprovider 组件作用

1. 提供全局状态管理 它主要用于提供全局的状态管理。它包裹整个 React Flow 应用或者相关的组件树&#xff0c;使得在这个范围内的所有子组件都能够访问和共享与 React Flow 相关的状态。 例如&#xff1a;在一个复杂的流程图绘制应用中&#xff0c;可能有多个组件需要知道当…

如何在vscode 中打开新文件不覆盖上一个窗口

在 VSCode 中&#xff0c;如果你单击文件时出现了覆盖Tab的情况&#xff0c;这通常是因为VSCode默认开启了预览模式。在预览模式下&#xff0c;单击新文件会覆盖当前预览的文件Tab。为了解决这个问题&#xff0c;你可以按照以下步骤进行操作 1.打开VSCode&#xff1a;启动你的…

Android 源码编译资料集

1、window环境下载Android系统源代码的方法 window环境下载Android系统源代码的方法 - yongfengnice - 博客园 2、安卓构建参考 构建 Android | Android Open Source Project 3、使用windows系统的WSL编译Android10系统 Android系统开发 使用windows系统的WSL编译Androi…

nodejs+mysql+vue3 应用实例剖析

文章目录 node.js vue3 mysql 应用后端实现&#xff08;koa部分&#xff09;1. 项目初始化与依赖安装2. 目录结构3. config/db.js - 数据库配置与连接4. models/user.js - 用户模型及数据库操作5. controllers/authController.js - 认证控制器6. controllers/userController.j…

Oracle Instant Client 23.5安装配置完整教程

Oracle Instant Client 23.5安装配置完整教程 简介环境要求安装步骤1. 准备工作目录2. 下载Oracle Instant Client3. 解压Instant Client4. 安装依赖包5. 配置系统环境5.1 配置库文件路径5.2 配置环境变量 6. 配置Oracle钱包&#xff08;可选&#xff09; 验证安装常见问题解决…

基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络

一、介绍 垃圾识别分类系统。本系统采用Python作为主要编程语言&#xff0c;通过收集了5种常见的垃圾数据集&#xff08;‘塑料’, ‘玻璃’, ‘纸张’, ‘纸板’, ‘金属’&#xff09;&#xff0c;然后基于TensorFlow搭建卷积神经网络算法模型&#xff0c;通过对图像数据集进…

Java在移动端小程序开发中的性能优化研究

Java在移动端小程序开发中的性能优化研究 第一章 绪论 1.1 研究背景及意义 随着移动互联网的快速发展,移动端小程序以其即点即用的便捷性和轻量级特性,迅速成为用户获取服务的首选方式。在此背景下,研究Java在移动端小程序开发中的性能优化,对于提升用户体验、减少资源消…