HarmonyOS 后台长时服务,类型为定位

我使用的地图加sdk。

export class BackgroundUtil {
  /**
   * Start background task.
   *
   * @param context
   */
  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)} `);
      }
    });
  }

  /**
   * Stop background task.
   *
   * @param context
   */
  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)} `);
    }
  }
}

使用长时定位服务时,看起来不是正常调用

HarmonyOS
2024-12-27 14:50:36
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

可参考以下代码:

import {
  abilityAccessCtrl,
  common,
  PermissionRequestResult,
  Permissions,
  WantAgent,
  wantAgent
} from '@kit.AbilityKit';
import PermissionsUtil from '../common/utils/PermissionsUtil';
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import BusinessError from "@ohos.base";
import { geoLocationManager } from '@kit.LocationKit';
import { notificationManager } from '@kit.NotificationKit';
import { TAG } from '@ohos/hypium/src/main/Constant';
import { sensor } from '@kit.SensorServiceKit';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State stepCount: number = 0
  @State isEnableSensor: boolean = false

  @Styles
  ButtonStyle(){
    .width(150)
    .height(35)
    .margin({ top: 20 })
  }

  // 定位能力所需要的权限
  private permissions: Array<Permissions> = ['ohos.permission.APPROXIMATELY_LOCATION', 'ohos.permission.LOCATION'];

  aboutToAppear(): void {
    PermissionsUtil.checkPermissions(this.permissions)
  }

  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: () => {
        this.onCancel()
      },
      confirm: () => {
        this.onAccept()
      }
    }),
    autoCancel: true,
    alignment: DialogAlignment.Center,
    offset: { dx: 0, dy: 200 },
    gridCount: 4,
    showInSubWindow: true,
    isModal: true,
    customStyle: false,
    cornerRadius: 10,
  })

  onCancel() {
    console.info('Callback when the first button is clicked')
  }

  onAccept() {
    console.info('Callback when the second button is clicked')
  }

  startLocationContinuousTask() {
    let wantAgentInfo: wantAgent.WantAgentInfo = {
      // 点击通知后,将要执行的动作列表
      wants: [
        {
          bundleName: "com.example.backgroundtask",
          abilityName: "EntryAbility"
        }
      ],
      // 点击通知后,动作类型
      actionType: wantAgent.OperationType.START_ABILITY,
      // 使用者自定义的一个私有值
      requestCode: 0,
      // 点击通知后,动作执行属性
      wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
    };
    try {
      // 通过wantAgent模块下getWantAgent方法获取WantAgent对象
      wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
        try {
          backgroundTaskManager.startBackgroundRunning(getContext(this) as common.UIAbilityContext,
            backgroundTaskManager.BackgroundMode.LOCATION, wantAgentObj).then(() => {
            console.info("Operation startBackgroundRunning succeeded");
          }).catch((error: BusinessError.BusinessError) => {
            console.error(`Operation startBackgroundRunning failed. code is ${error.code} message is ${error.message}`);
          });
        } catch (error) {
          console.error(` startBackgroundRunning failed. code is ${(error as BusinessError.BusinessError).code} message is ${(error as BusinessError.BusinessError).message}`);
        }
      });
    } catch (error) {
      console.error(`Operation getWantAgent failed. code is ${(error as BusinessError.BusinessError).code} message is ${(error as BusinessError.BusinessError).message}`);
    }
  }

  stopLocationContinuousTask() {
    backgroundTaskManager.stopBackgroundRunning(getContext(this) as common.UIAbilityContext).then(() => {
      console.info(`Succeeded in operationing stopBackgroundRunning.`);
    }).catch((error: BusinessError.BusinessError) => {
      console.error(`Failed to operation stopBackgroundRunning. Code is ${error.code}, message is ${error.message}`);
    });
  }

  startGeoLocation() {
    // 申请通知
    notificationManager.requestEnableNotification()
      .then(() => {
        let requestInfo: geoLocationManager.LocationRequest = {
          'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
          'scenario': geoLocationManager.LocationRequestScenario.UNSET,
          'timeInterval': 0,
          'distanceInterval': 0,
          'maxAccuracy': 0
        };
        let locationChange = (location: geoLocationManager.Location): void => {
          console.log('locationChanger: data: ' + JSON.stringify(location));
          if (this.isEnableSensor) {
            this.once()
          }
        };
        try {
          geoLocationManager.on('locationChange', requestInfo, locationChange);
        } catch (err) {
          if ((err as BusinessError.BusinessError).code == 3301100) {
            if (this.dialogController != null) {
              this.dialogController.open()
            }
          }
        }
      })
  }

  once() {
    try {
      sensor.once(sensor.SensorId.PEDOMETER, (data: sensor.PedometerResponse) => {
        console.info('Succeeded in invoking once. Step count: ' + data.steps);
        this.stepCount = data.steps
      });
    } catch (error) {
      let e: BusinessError.BusinessError = error as BusinessError.BusinessError;
      console.error(`Failed to invoke once. Code: ${e.code}, message: ${e.message}`);
    }
  }

  start() {
    // 请求权限
    const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
    atManager.requestPermissionsFromUser(getContext(this) as common.UIAbilityContext, ['ohos.permission.ACTIVITY_MOTION'], (err: BusinessError.BusinessError, data: PermissionRequestResult) => {
      if (err) {
        console.info(TAG, `requestPermissionsFromUser fail, err->${JSON.stringify(err)}`)
      } else {
        this.isEnableSensor = true
      }
    })
  }

  build() {
    Row() {
      Column() {
        Button("开始定位")
          .ButtonStyle()
          .onClick(() => {
            //开启定位
            this.startGeoLocation()
            //长时任务
            this.startLocationContinuousTask()
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

@CustomDialog
struct CustomDialogExample {
  controller?: CustomDialogController
  cancel: () => void = () => {
  }
  confirm: () => void = () => {
  }
  build() {
    Column() {
      Text('打开定位才可以定位')
        .fontSize(20)
        .height(100)
      Row() {
        Button('关闭')
          .width(100)
          .onClick(() => {
            if (this.controller != undefined) {
              this.controller.close()
            }
          })
          .margin(20)
        Button('设置')
          .width(100)
          .onClick(() => {
            if (this.controller != undefined) {
              let context = getContext(this) as common.UIAbilityContext;
              context.startAbility({
                bundleName: 'com.huawei.hmos.settings',
                abilityName: 'com.huawei.hmos.settings.MainAbility',
                uri: 'location_manager_settings',
              });
              if (this.controller != undefined) {
                this.controller.close()
              }
            }
          })
          .margin(20)
      }
      .margin(20)
    }
  }
}

PermissionsUtil.ets代码:

import { abilityAccessCtrl, bundleManager, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

/**
 * 权限管理工具类
 * 能力:检查权限是否已存在、请求用户授权
 */
class PermissionsUtil {

  /**
   * 校验应用是否被授予定位权限
   * @param permissions
   * @returns
   */
  async checkPermissions(permissions: Array<Permissions>): Promise<void> {
    let applyResult: boolean = false;
    for (let permission of permissions) {
      let grantStatus: abilityAccessCtrl.GrantStatus = await this.checkAccessToken(permission);
      if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
        applyResult = true;
      } else {
        applyResult = false;
      }
    }
    if (!applyResult) {
      this.requestPermissions(permissions);
    }
  }

  async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;

    // 获取应用程序的accessTokenID
    let tokenId: number = 0;
    try {
      let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
      let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
      tokenId = appInfo.accessTokenId;
    } catch (error) {
      let err: BusinessError = error as BusinessError;
      console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
    }

    // 校验应用是否被授予权限
    try {
      grantStatus = await atManager.checkAccessToken(tokenId, permission);
    } catch (error) {
      let err: BusinessError = error as BusinessError;
      console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
    }

    return grantStatus;
  }

  /**
   * 申请用户授权
   * @param permissions
   */
  requestPermissions(permissions: Array<Permissions>): void {
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    atManager.requestPermissionsFromUser(getContext() as common.UIAbilityContext, permissions)
      .then((data: PermissionRequestResult) => {
        console.info('request Permissions success')
      })
      .catch((err: BusinessError) => {
        console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
      })
  }
}

export default new PermissionsUtil();

module.json5文件中申请定位相关权限和后台任务权限

ohos.permission.LOCATION

ohos.permission.APPROXIMATELY_LOCATION

ohos.permission.LOCATION_IN_BACKGROUND

ohos.permission.KEEP_BACKGROUND_RUNNING

{
  "name": "ohos.permission.LOCATION",
  "reason": "$string:EntryAbility_desc",
  "usedScene": {
    "abilities": [
    "EntryAbility"
    ],
  "when": "always"
}
},
{
  "name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:EntryAbility_desc",
"usedScene": {
  "abilities": [
  "EntryAbility"
  ],
  "when": "always"
}
},
{
  "name": "ohos.permission.LOCATION_IN_BACKGROUND",
"reason": "$string:EntryAbility_desc",
"usedScene": {
  "abilities": [
  "EntryAbility"
  ],
  "when": "always"
}
},
{
  "name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
"reason": "$string:EntryAbility_desc",
"usedScene": {
  "abilities": [
  "EntryAbility"
  ],
  "when": "always"
}
},

module.json5配置文件中为需要使用长时任务的UIAbility声明相应的长时任务类型(配置文件中填写长时任务类型的配置项)

参考文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/continuous-task-V5

分享
微博
QQ
微信
回复
2024-12-27 17:45:01
相关问题
后台长时任务启动失败
2525浏览 • 1回复 待解决
后台长时任务启动失败报错码201
2797浏览 • 1回复 待解决
HarmonyOS 后台定位问题
755浏览 • 1回复 待解决
HarmonyOS 定位服务、地图服务
276浏览 • 1回复 待解决
HarmonyOS 定位服务
358浏览 • 1回复 待解决
HarmonyOS 系统定位及语音服务能力
454浏览 • 1回复 待解决
HarmonyOS 后台服务接不到文件
445浏览 • 1回复 待解决
鸿蒙手表后台持续定位不成功
558浏览 • 0回复 待解决
HarmonyOS 设置音效类型MOVIE
272浏览 • 1回复 待解决
HarmonyOS如何退到后台退出socket
819浏览 • 0回复 待解决