实时导航等场景下,应用可能需要退至后台并持续更新位置信息,如何实现后台持续定位长时任务?
{
"name" : "ohos.permission.LOCATION",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
},
"reason": "$string:location_use"
},
{
"name" : "ohos.permission.APPROXIMATELY_LOCATION",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
},
"reason": "$string:location_use"
},
{
"name" : "ohos.permission.LOCATION_IN_BACKGROUND",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
},
"reason": "$string:location_use"
},
{
"name" : "ohos.permission.KEEP_BACKGROUND_RUNNING",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
},
"reason": "$string:location_use"
} "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": [
"ohos.want.action.home"
]
}
]
}
], 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],
}; // 启动定位之前先申请位置权限 await reqPermissionsFromUser(['ohos.permission.APPROXIMATELY_LOCATION', 'ohos.permission.LOCATION'], this.getUIContext().getHostContext() as common.UIAbilityContext);
let list: Array<string> = ['location']; // 注意长时任务类型
backgroundTaskManager.startBackgroundRunning(this.context, list, wantAgentObj)
.then(async () => {
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.latitude = location.latitude;
this.longitude = location.longitude;
});
} catch (err) {
this.message = JSON.stringify(err);
}
})
.catch((error: BusinessError) => {
console.error(`Failed to Operation startBackgroundRunning. code is ${error.code} message is ${error.message}`);
}); 完整代码:
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { abilityAccessCtrl, common, Permissions, WantAgent, wantAgent } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { geoLocationManager } from '@kit.LocationKit';
async function reqPermissionsFromUser(permissions: Array<Permissions>,
context: common.UIAbilityContext): Promise<boolean> {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
let data = await atManager.requestPermissionsFromUser(context, permissions);
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
return true; // 用户授权,可以继续访问目标操作
}
}
return false; // 授权失败
}
@Entry
@Component
struct Index {
@State message: string = 'ContinuousTask';
@State latitude: number = 0;
@State longitude: number = 0;
// 通过getUIContext().getHostContext()方法,来获取page所在的UIAbility上下文
private context: Context | undefined = this.getUIContext().getHostContext();
startContinuousTask() {
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],
};
try {
// 通过wantAgent模块下getWantAgent方法获取WantAgent对象
wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
try {
let list: Array<string> = ['location']; // 注意长时任务类型
backgroundTaskManager.startBackgroundRunning(this.context, list, wantAgentObj)
.then(async () => {
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.latitude = location.latitude;
this.longitude = location.longitude;
});
} catch (err) {
this.message = JSON.stringify(err);
}
})
.catch((error: BusinessError) => {
console.error(`Failed to Operation startBackgroundRunning. code is ${error.code} message is ${error.message}`);
});
} catch (error) {
console.error(`Failed to Operation startBackgroundRunning. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
}
});
} catch (error) {
console.error(`Failed to Operation getWantAgent. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
}
}
stopContinuousTask() {
backgroundTaskManager.stopBackgroundRunning(this.context).then(async () => {
console.info(`Succeeded in operationing stopBackgroundRunning.`);
}).catch((err: BusinessError) => {
console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
});
}
build() {
Row() {
Column() {
Button('启动后台定位任务')
.width(250)
.height(40)
.onClick(async () => {
// 启动定位之前先申请位置权限
await reqPermissionsFromUser(['ohos.permission.APPROXIMATELY_LOCATION', 'ohos.permission.LOCATION'],
this.getUIContext().getHostContext() as common.UIAbilityContext);
this.startContinuousTask();
});
Button('取消后台长时任务')
.margin({ top: 10, bottom: 10 })
.width(250)
.height(40)
.onClick(() => {
this.stopContinuousTask();
});
Text(`latitude: ${this.latitude}`);
Text(`longitude: ${this.longitude}`);
}
.width('100%');
}
.height('100%');
}
} 合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功