HarmonyOS中 Location 功能的详细使用

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、基础配置与权限申请

1. 权限声明

module.json5中声明定位权限,需区分精确与模糊定位:

{
  "requestPermissions": [
    {
      "name": "ohos.permission.LOCATION",          // 精确位置(米级)
      "reason": "$string:location_permission",     // 权限说明
      "usedScene": {
        "abilities": ["EntryAbility"],
        "when": "inuse"                           // 使用时申请
      }
    },
    {
      "name": "ohos.permission.APPROXIMATELY_LOCATION", // 模糊位置(5公里级)
      "reason": "$string:fuzzy_location_permission",
      "usedScene": {
        "abilities": ["EntryAbility"],
        "when": "always"                          // 始终申请
      }
    }
  ]
}

注意:若需后台定位,需额外申请ohos.permission.LOCATION_IN_BACKGROUND权限。

2. 动态权限检查
import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit';

async function checkLocationPermission(): Promise<boolean> {
  let atManager = abilityAccessCtrl.createAtManager();
  try {
    let status = await atManager.checkAccessToken(
      abilityAccessCtrl.AccessToken.PERMISSION_LOCATION
    );
    return status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
  } catch (err) {
    console.error('权限检查失败:', err);
    return false;
  }
}

二、核心API与基础定位

1. 单次定位(获取当前位置)
import geoLocationManager from '@ohos.geoLocationManager';

async function getCurrentLocation(): Promise<void> {
  let request: geoLocationManager.SingleLocationRequest = {
    locatingPriority: geoLocationManager.LocationPriority.ACCURACY, // 高精度模式
    locatingTimeoutMs: 10000                                       // 超时10秒
  };

  try {
    let location = await geoLocationManager.getCurrentLocation(request);
    console.log(`纬度: ${location.latitude}, 经度: ${location.longitude}`);
  } catch (err) {
    console.error('定位失败:', err.code); // 错误码参考
  }
}

参数说明

  • locatingPriority:可选ACCURACY(GNSS优先)或LOW_POWER(网络定位) 。
  • locatingTimeoutMs:超时时间,建议设为5-30秒。
2. 连续定位(实时更新位置)
let locationCallback = (err, location) => {
  if (err) return;
  console.log(`实时位置: ${location.latitude}, ${location.longitude}`);
};

function startContinuousLocation() {
  let request: geoLocationManager.LocationRequest = {
    locatingPriority: geoLocationManager.LocationPriority.ACCURACY,
    interval: 2000 // 2秒更新一次
  };

  geoLocationManager.on('locationChange', request, locationCallback);
}

function stopContinuousLocation() {
  geoLocationManager.off('locationChange', locationCallback);
}

三、高级功能实现

1. 逆地理编码(坐标转地址)
import geoCoder from '@ohos.geoLocationManager';

async function reverseGeocode(lat: number, lon: number): Promise<string> {
  let request: geoCoder.ReverseGeoCodeRequest = {
    locale: 'zh-CN', // 语言
    latitude: lat,
    longitude: lon
  };

  try {
    let result = await geoCoder.getAddressesFromLocation(request);
    return result[0].address; // 返回首个地址
  } catch (err) {
    console.error('逆地理编码失败:', err);
    return '未知位置';
  }
}

 2. 地理围栏(区域监控)

let geofenceCallback = (err, event) => {
  if (err || !event) return;
  console.log(`进入围栏: ${event.geofences[0].geofenceId}`);
};

async function addGeofence() {
  let fence: geoLocationManager.Geofence = {
    latitude: 39.90469,      // 围栏中心纬度
    longitude: 116.40717,   // 围栏中心经度
    radius: 500,            // 半径500米
    expiration: 86400000    // 24小时后失效
  };

  try {
    await geoLocationManager.addGeofence(fence, geofenceCallback);
  } catch (err) {
    console.error('围栏添加失败:', err);
  }
}

四、第三方定位SDK集成(腾讯/百度)

1. 腾讯定位SDK集成
// 1. 安装SDK
"dependencies": {
  "@tencentmap/location_sdk": "1.0.6"
}

// 2. 初始化
import { scanBarcode } from '@kit.ScanKit';
scanBarcode.startScanForResult(context, {
  scanTypes: [scanBarcode.ScanType.QR_CODE]
}).then(result => {
  console.log('腾讯定位结果:', result.scanResult);
});
2. 百度定位SDK集成
// 配置工程引入SDK
import { BaiduLocation } from '@baidu/location_sdk';
BaiduLocation.init().then(() => {
  BaiduLocation.startLocation({
    coorType: 'gcj02' // 国测局坐标
  });
});

特点:提供高精度定位离线定位能力。

五、总结与优化

  1. 功耗优化

    • 低功耗场景使用LOW_POWER模式。
    • 非必要时不开启连续定位 。
  2. 错误处理

// 定位开关未打开
if (err.code === 3301100) {
  prompt.showToast({ message: '请开启位置服务' });
}

    3. 多设备适配

// 手表设备使用简化定位
if (deviceInfo.deviceType === 'watch') {
  request.locatingPriority = geoLocationManager.LocationPriority.LOW_POWER;
}

六、完整示例(获取位置并显示地址)

@Entry
@Component
struct LocationScreen {
  @State address: string = '正在定位...';

  async onPageShow() {
    if (await checkLocationPermission()) {
      let location = await getCurrentLocation();
      this.address = await reverseGeocode(location.latitude, location.longitude);
    } else {
      this.address = '权限未授权';
    }
  }

  build() {
    Column() {
      Text(this.address)
        .fontSize(20)
        .margin(10)
    }
  }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值