HarmonyOS鸿蒙Next中是否支持后台持续获取 GPS 位置(如运动轨迹记录)
HarmonyOS鸿蒙Next中是否支持后台持续获取 GPS 位置(如运动轨迹记录) 我们正在开发一款跑步类 App,需在锁屏或切后台后持续每秒获取一次高精度定位,这个有API或者实现代码吗?急急急。感谢 大佬 了。
实现 锁屏/切后台后每秒获取一次高精度定位 是完全可行的,但需要严格遵循系统权限管理、后台保活机制和定位 API 的规范使用。
一、前提条件
- 目标设备为真机(模拟器不支持后台高频定位)
- 用户手动授权 后台定位权限(不能静默申请)
- App 声明了后台定位能力(
backgroundModes: ["location"]) - 使用
ContinuousTask保活,防止系统杀进程
二、配置文件:module.json5
{
"module": {
"requestPermissions": [
{ "name": "ohos.permission.LOCATION" },
{ "name": "ohos.permission.LOCATION_IN_BACKGROUND" },
{ "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" }
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"type": "page",
"backgroundModes": ["location"] // ⚠️ 关键:声明后台定位模式
}
]
}
}
三、核心代码(ArkTS)
1. 定位管理类:RunningLocationService.ets
import geolocation from '@ohos.geolocation';
import backgroundTaskManager from '@ohos.backgroundTaskManager';
import common from '@ohos.app.ability.common';
import hilog from '@ohos.hilog';
const TAG = 'RunningLocation';
export class RunningLocationService {
private context: common.UIAbilityContext;
private isRunning = false;
private taskId: number = -1;
private callback: geolocation.LocationCallback | null = null;
constructor(context: common.UIAbilityContext) {
this.context = context;
}
async start(): Promise<void> {
if (this.isRunning) return;
try {
// 1. 检查并请求权限(必须由用户主动触发)
const auth = await geolocation.checkLocationAuthorization();
if (auth !== geolocation.LocationAuthorizationStatus.AUTHORIZED) {
await geolocation.requestLocationAuthorization();
const newAuth = await geolocation.checkLocationAuthorization();
if (newAuth !== geolocation.LocationAuthorizationStatus.AUTHORIZED) {
throw new Error('未获得定位权限');
}
}
// 2. 开启定位服务
await geolocation.enableLocation();
// 3. 申请后台持续任务(保活)
this.taskId = await backgroundTaskManager.startContinuousTask(
this.context,
backgroundTaskManager.ContinuousTaskType.CONTINUOUS_TASK_TYPE_LOCATION
);
// 4. 配置高精度 + 1秒间隔
const config: geolocation.LocationRequestConfig = {
priority: geolocation.LocationRequestPriority.HIGH_ACCURACY,
scenario: geolocation.LocationRequestScenario.RUNNING, // 跑步场景优化
timeInterval: 1000, // 1秒
distanceInterval: 0, // 忽略距离变化
maxAccuracy: 5, // 要求5米内精度
cacheValidTime: 0 // 不用缓存
};
// 5. 注册回调
this.callback = (location: geolocation.Location) => {
hilog.info(TAG, `📍定位: ${location.latitude}, ${location.longitude}, 精度=${location.accuracy}m`);
// TODO: 发送到UI、记录轨迹、计算配速等
};
geolocation.on('locationChange', config, this.callback);
this.isRunning = true;
hilog.info(TAG, '✅ 跑步定位服务已启动(支持锁屏/后台)');
} catch (err) {
hilog.error(TAG, `❌ 启动失败: ${JSON.stringify(err)}`);
this.stop();
throw err;
}
}
stop(): void {
if (!this.isRunning) return;
if (this.callback) {
geolocation.off('locationChange', this.callback);
this.callback = null;
}
if (this.taskId !== -1) {
backgroundTaskManager.stopContinuousTask(this.context, this.taskId)
.catch(e => hilog.error(TAG, `停止保活任务失败: ${JSON.stringify(e)}`));
this.taskId = -1;
}
geolocation.disableLocation().catch(() => {});
this.isRunning = false;
hilog.info(TAG, '⏹️ 定位服务已停止');
}
}
2. 在 Ability 中调用(用户点击“开始跑步”时触发)
// EntryAbility.ets
import { RunningLocationService } from '../common/RunningLocationService';
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
private locationService: RunningLocationService | null = null;
onCreate() {
this.locationService = new RunningLocationService(this.context);
}
// 假设用户点击“开始跑步”按钮
onStartRunning() {
this.locationService?.start().catch(err => {
console.error('定位启动失败,请检查权限或系统设置', err);
// 可弹窗提示用户去设置中开启“后台高耗电”和“后台定位”
});
}
onDestroy() {
this.locationService?.stop();
}
}
测试建议
- 真机测试(华为 Mate/P系列、Pura 系列等)
- 启动 App → 点击“开始跑步” → 锁屏 → 观察日志是否持续输出
- 进入 设置 > 电池 > 应用启动管理,关闭自动管理,手动允许后台活动
更多关于HarmonyOS鸿蒙Next中是否支持后台持续获取 GPS 位置(如运动轨迹记录)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
楼主您好,您可参考以下方案:
【解决方案】
示例代码基于位置服务获取设备定位信息:本示例通过@kit.LocationKit中的geoLocationManager实现获取缓存位置、获取当前位置和持续定位功能,并结合@kit.BackgroundTasksKit中的backgroundTaskManager开启长时任务,实现后台定位功能,同时运用map.Marker将位置信息标记在地图上。开发者可以在需要用到设备位置信息的开发场景中,如查看所在城市天气、出行打车、旅行导航以及观察运动轨迹等,集成本示例代码实现定位功能。
1、在进入长时任务前注意申请位置权限和后台运行权限:
// 启动定位之前先申请位置权限
let per = await reqPermissionsFromUser(['ohos.permission.APPROXIMATELY_LOCATION', 'ohos.permission.LOCATION'],
this.getUIContext().getHostContext() as common.UIAbilityContext)
'requestPermissions': [
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:app_name",
"usedScene": {}
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:app_name",
"usedScene": {}
},
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND",
"reason": "$string:app_name",
"usedScene": {}
},
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
"reason": "$string:app_name",
"usedScene": {}
}
],
2、声明后台模式类型:在module.json5文件中为需要使用长时任务的UIAbility声明相应的长时任务类型,配置文件中填写长时任务类型的配置项。
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"backgroundModes": ["location"],// 声明支持定位后台模式
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
},
],
3、添加后台应用的相关信息:
let wantAgentInfo: wantAgent.WantAgentInfo = {
// 添加需要被拉起应用的bundleName和abilityName
wants: [
{
bundleName: "com.example.backgroundtask",
abilityName: "EntryAbility"
}
],
// 指定点击通知栏消息后的动作是拉起ability
actionType: wantAgent.OperationType.START_ABILITY,
// 使用者自定义的一个私有值
requestCode: 0,
// 点击通知后,动作执行属性
actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
};
4、启动长时任务时,注意长时任务类型,需要与具体的任务对应,本例中为获取位置信息所以需要启动"location"类型的任务。
let list: Array<string> = ["location"]; // 注意长时任务类型
backgroundTaskManager.startBackgroundRunning(this.context, list, wantAgentObj)
.then(async (res: backgroundTaskManager.ContinuousTaskNotification) => {
console.info("Operation startBackgroundRunning succeeded");
// 此处执行具体的长时任务逻辑,该示例中为获取位置信息
if (!geoLocationManager.isLocationEnabled()) {
this.message = 'permission error';
}
let request: geoLocationManager.ContinuousLocationRequest = {
'interval': 1,
'locationScenario': geoLocationManager.UserActivityScenario.NAVIGATION
}
try {
geoLocationManager.on('locationChange', request, (location: geoLocationManager.Location) => {
this.message = JSON.stringify(location);
this.seq++;
console.info(this.seq.toString(), 'testing: ', JSON.stringify(location));
});
} catch (err) {
this.message = JSON.stringify(err);
}
})
.catch((error: BusinessError) => {
console.error(`Failed to Operation startBackgroundRunning. code is ${error.code} message is ${error.message}`);
});
【背景知识】
- 长时任务(ArkTS):应用退至后台后,在后台需要长时间运行用户可感知的任务,如播放音乐、导航等。为防止应用进程被挂起,导致对应功能异常,可以申请长时任务,使应用在后台长时间运行。
- Location Kit(位置服务):位置子系统使用多种定位技术提供服务,如GNSS定位、基站定位、WLAN/蓝牙定位(基站定位、WLAN/蓝牙定位后续统称“网络定位技术”);通过这些定位技术,无论用户设备在室内或是户外,都可以准确地确定设备位置。
- geoLocationManager.on(‘locationChange’):获取时候位置的接口,开启位置变化订阅,并发起定位请求。
应该支持
在鸿蒙(HarmonyOS)系统中,支持后台持续获取高精度GPS位置(包括锁屏/切后台场景),可通过以下方案实现每秒定位:
实现方案
1. 权限配置(module.json5)
"requestPermissions": [
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND",
"reason": "后台持续定位",
"usedScene": { "abilities": ["EntryAbility"], "when": "always" }
},
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
"reason": "保持后台运行",
"usedScene": { "abilities": ["EntryAbility"], "when": "always" }
}
],
"abilities": [
{
"backgroundModes": ["location"] // 声明定位长时任务
}
]
2. 核心代码实现
import geoLocationManager from '@kit.GeoLocationKit';
import backgroundTaskManager from '@kit.ResourceScheduleKit';
import wantAgent from '@kit.AbilityKit';
// 配置高精度定位参数(每秒1次)
const locationRequest: geoLocationManager.LocationRequest = {
priority: geoLocationManager.LocationRequestPriority.FIRST_FIX, // 最高精度
scenario: geoLocationManager.LocationRequestScenario.NAVIGATION, // 导航级定位
timeInterval: 1, // 1秒间隔
distanceInterval: 0, // 无距离限制
maxAccuracy: 0 // 最高精度
};
// 开启后台定位任务
async function startBackgroundTracking() {
const context = getContext(this) as common.UIAbilityContext;
// 1. 创建WantAgent(后台任务触发入口)
const wantAgentInfo = {
wants: [{ bundleName: context.abilityInfo.bundleName }],
requestCode: 0,
operationType: wantAgent.OperationType.START_ABILITY
};
const agent = await wantAgent.getWantAgent(wantAgentInfo);
// 2. 启动长时定位任务
await backgroundTaskManager.startBackgroundRunning(
context,
backgroundTaskManager.BackgroundMode.LOCATION,
agent
);
// 3. 注册位置监听(每秒回调)
geoLocationManager.on('locationChange', locationRequest, (location) => {
console.log(`实时位置:${location.latitude},${location.longitude}`);
// 此处处理轨迹记录逻辑
});
}
// 停止定位
function stopTracking() {
geoLocationManager.off('locationChange'); // 取消监听
backgroundTaskManager.stopBackgroundRunning(); // 结束长时任务
}
关键注意事项
权限要求:
- 必须申请ohos.permission.LOCATION_IN_BACKGROUND
- 必须申请ohos.permission.KEEP_BACKGROUND_RUNNING
- 用户需在设置中开启 "始终允许"定位权限
设备限制:
- 需引导用户关闭省电模式(如vivo的i管家→允许后台高耗电)
- 测试时避免充电状态(可能绕过省电限制)
性能优化:
// 按需调整定位参数(降低精度可省电)
const batterySaverRequest = {
priority: geoLocationManager.LocationRequestPriority.ACCURACY,
timeInterval: 5 // 低功耗时延长间隔
};
状态验证:
- 成功时状态栏显示定位图标
- 通过backgroundTaskManager.getBackgroundRunningStatus()检查任务状态
完整工作流程
graph TD
A[申请后台定位权限] --> B[配置长时任务类型]
B --> C[启动BackgroundMode.LOCATION]
C --> D[注册locationChange监听]
D --> E[每秒接收高精度定位]
E --> F[存储轨迹数据]
F --> G{是否继续?}
G -- 是 --> E
G -- 否 --> H[取消监听并结束任务]
此方案满足运动轨迹记录场景需求,实测中需注意:
- 首次使用需手动授予"始终允许"权限
- 华为设备需关闭"电池优化"
- 持续定位会显著增加耗电,建议提供省电模式选项
高频定位(每秒1次)会显著增加功耗!!!(如果是专业就当我没说好吧)注意平衡功耗!!!
ⅰ.定位服务API:
ohos.location.LocationManager
ⅱ.后台任务API:
ohos.resourcemanager.BackgroundTaskManager
ⅲ.相关权限API:
ohos.permission.LOCATION
ohos.permission.BACKGROUND_LOCATION
ⅳ.若需要锁屏后CPU不休眠,可结合 PowerManager 申请唤醒锁
ohos.permission.KEEP_BACKGROUND_RUNNING
实现代码如下:
配置权限 module.json5
__________________________开始于下
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.LOCATION",
"reason": "$string:location_reason",
"usedScene": { "abilities": [".MainAbility"], "when": "always" }
},
{
"name": "ohos.permission.BACKGROUND_LOCATION",
"reason": "$string:bg_location_reason",
"usedScene": { "abilities": [".MainAbility"], "when": "always" }
}
]
}
}
___________________截止于此
申请后台运行能力_____(这一段是用Java写的,我才从Java转还不太熟ArkTs)
import ohos.resourcemanager.BackgroundTaskManager;
import ohos.resourcemanager.continuoustask.ContinuousTaskParam;
import ohos.resourcemanager.continuoustask.ContinuousTaskType;
// 申请后台持续任务(定位类型)
ContinuousTaskParam param = new ContinuousTaskParam(ContinuousTaskType.TYPE_LOCATION);
BackgroundTaskManager.getInstance().startContinuousTask(getContext(), param, (result, msg) -> {
if (result) {
startLocationUpdate();
}
}
________初始化定位管理器并设置高精度监听
import ohos.location.*;
import ohos.rpc.RemoteException;
private LocationManager locationManager;
private MyLocationListener locationListener;
// 初始化
private void initLocationManager() {
locationManager = LocationManager.getInstance(getContext());
locationListener = new MyLocationListener();
// 配置高精度定位参数
LocationRequest request = new LocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setInterval(1000); // 定位间隔1秒
request.setFastestInterval(1000); // 最快间隔1秒
}
// 开始持续定位
private void startLocationUpdate() {
try {
locationManager.requestLocationUpdates(request, locationListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
// 自定义位置监听器
class MyLocationListener implements LocationCallback {
@Override
public void onLocationChanged(Location location) {
// 获取定位结果
double latitude = location.getLatitude();
double longitude = location.getLongitude();
// 处理定位数据
}
@Override
public void onStatusChanged(int type) {
// 变化回调
}
}
在HarmonyOS Next中,可以通过后台任务管理和位置服务的API实现应用在后台持续获取GPS位置。以下是关键实现步骤和代码示例:
1. 申请权限
在module.json5配置文件中声明位置权限和后台持续任务权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.LOCATION",
"reason": "用于记录运动轨迹"
},
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
"reason": "需要后台持续获取位置"
}
]
}
}
2. 后台任务配置
在module.json5中配置后台任务类型为location:
{
"module": {
"abilities": [
{
"backgroundModes": ["location"]
}
]
}
}
3. 核心实现代码
使用@ohos.location和@ohos.backgroundTaskManager模块:
import location from '@ohos.location';
import backgroundTaskManager from '@ohos.backgroundTaskManager';
// 初始化定位参数
let requestInfo: location.LocationRequest = {
priority: location.LocationRequestPriority.FIRST_FIX, // 高精度定位
scenario: location.LocationScenario.UNSET, // 运动场景
timeInterval: 1, // 1秒间隔
distanceInterval: 0, // 距离间隔为0米,按时间触发
maxAccuracy: 10 // 精度10米以内
};
// 启动持续定位
async function startContinuousLocation() {
try {
// 申请后台任务
await backgroundTaskManager.requestSuspendDelay();
// 开始定位
await location.on('locationChange', requestInfo, (locationData) => {
console.log(`位置更新: ${JSON.stringify(locationData)}`);
// 处理位置数据(存储或上传)
});
} catch (error) {
console.error(`定位失败: ${error.code}, ${error.message}`);
}
}
// 停止定位
function stopContinuousLocation() {
location.off('locationChange');
}
4. 注意事项
- 电量优化:每秒定位会显著增加耗电,建议根据运动速度动态调整频率
- 精度平衡:高精度模式(GNSS)在室内可能失效,可结合网络定位
- 后台保活:需在设置中允许应用的后台活动权限
- 隐私合规:必须提供清晰的权限使用说明
5. 完整示例架构
// 位置服务管理类
class LocationTracker {
private isTracking: boolean = false;
async startTracking() {
if (this.isTracking) return;
// 检查权限
// 启动后台任务
// 开始位置监听
this.isTracking = true;
}
async stopTracking() {
// 停止所有监听
this.isTracking = false;
}
}
此方案可在锁屏和后台状态下维持GPS定位,满足运动轨迹记录需求。实际开发中需测试不同机型的后台策略差异。


