# 开发准备

#### 硬件要求

开发者可根据实际的开发语言，选择对应接口判断当前设备是否支持AR Engine。接口的调用参考如下方式：

ArkTS（arViewController.isARTypeSupported）：

```
import { arEngine, arViewController } from '@kit.AREngine';

let ret: boolean = arViewController.isARTypeSupported(arEngine.ARFeatureType.ARENGINE_FEATURE_TYPE_FACE);
```

C/C++（HMS\_AREngine\_CheckSupported）：

```
#include "ar/ar_engine_core.h"

auto ret = HMS_AREngine_CheckSupported(ARENGINE_FEATURE_TYPE_FACE);
```

若对应接口返回错误码为801或ARENGINE\_ERROR\_DEVICE\_NOT\_SUPPORTED，则表示AR Engine不支持当前设备。

#### 环境搭建

请参考应用开发准备完成基本准备工作。

#### 申请权限

在开发AR应用时，需要先申请相机相关权限，确保应用拥有访问相机硬件及其他功能的权限，需要的权限如下。在申请权限前，请保证符合权限使用的基本原则。

*   使用相机拍摄前，需要申请**ohos.permission.CAMERA**相机权限。
    
*   当需要使用加速计感知设备运动状态时，需要申请**ohos.permission.ACCELEROMETER**加速计权限。
    
*   当需要陀螺仪感知设备位姿信息时，需要申请**ohos.permission.GYROSCOPE**陀螺仪权限。
    

#### 前置准备

推荐使用组件导航(Navigation) (推荐)作为页面路由，使用Navigation的页面生命周期所示方法。

开发者需先创建首页，通过首页选择进入AR Engine场景。

1.  导入所需模块。
    
    ```
    import { abilityAccessCtrl, PermissionRequestResult } from '@kit.AbilityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    ```
    
2.  创建一个基础的页面，具体可参考组件导航(Navigation) (推荐)。
    
    ```
    @Entry
    @Component
    struct Selector {
      pageInfo: NavPathStack = new NavPathStack();
    
      build(): void {
        Navigation(this.pageInfo) {
    
        }
        .mode(NavigationMode.Stack)
        .hideTitleBar(true)
        .hideBackButton(true)
        .hideToolBar(true)
      }
    }
    ```
    
3.  创建sampleButton，封装Button及权限校验功能，使用@Builder装饰，并配置routerMap进行页面跳转。
    
    ```
    @Entry
    @Component
    struct Selector {
      pageInfo: NavPathStack = new NavPathStack();
      private hasPermission: boolean = false;
      @State context: Context = this.getUIContext().getHostContext() as Context;
    
      build(): void {
        // ...
      }
    
      @Builder
      sampleButton(sampleName: string): void {
        Button(sampleName, { type: ButtonType.Normal, stateEffect: true })
          .borderRadius(8)
          .width('50%')
          .height('5%')
          .onClick(async () => {
            if (!this.hasPermission) {
              this.hasPermission = await requestPermissionOnSetting(this.context);
              if (!this.hasPermission) {
                return;
              }
            }
            this.pageInfo.clear();
            this.pageInfo.pushDestinationByName(sampleName, null).catch((error: BusinessError) => {
              console.error(`[pushDestinationByName]failed. Code: ${error.code}.`);
            });
          })
      }
    }
    ```
    
4.  创建requestPermissionOnSetting方法用于校验在进入AR场景时是否已经获取相机权限。
    
    ```
    struct Selector {
      // ...
    }
    
    async function requestPermissionOnSetting(context: Context): Promise<boolean> {
      let requestResult: boolean = false;
      let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
      await atManager.requestPermissionOnSetting(context, ['ohos.permission.CAMERA'])
        .then((data: abilityAccessCtrl.GrantStatus[]) => {
          console.info('data:' + JSON.stringify(data));
          if (data[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
            requestResult = true;
          }
        })
        .catch((err: BusinessError) => {
          console.error('data:' + JSON.stringify(err));
        })
      return requestResult;
    }
    ```
    
5.  在页面上创建按钮，用于进入AR场景。
    
    ```
    build(): void {
      Navigation(this.pageInfo) {
        Column() {
          this.sampleButton('ARWorld'); // 进入ARWorld场景
        }
        .justifyContent(FlexAlign.SpaceEvenly)
        .width('100%')
        .height('100%')
      }
      .mode(NavigationMode.Stack)
      .hideTitleBar(true)
      .hideBackButton(true)
      .hideToolBar(true)
    }
    ```
    
6.  在onAppear中配置应用首次启动时的权限校验方法requestPermissionOnFirstStartup。
    
    ```
    struct Selector {
      // ...
      build(): void {
        Navigation(this.pageInfo) {
          Column() {
            this.sampleButton('ARWorld');
          }
          .justifyContent(FlexAlign.SpaceEvenly)
          .width('100%')
          .height('100%')
        }
        .onAppear(() => {
          this.requestPermissionOnFirstStartup();
        })
        .mode(NavigationMode.Stack)
        .hideTitleBar(true)
        .hideBackButton(true)
        .hideToolBar(true)
      }
    
      @Builder
      sampleButton(sampleName: string): void {
        // ...
      }
    
      private requestPermissionOnFirstStartup(): void {
        abilityAccessCtrl.createAtManager()
          .requestPermissionsFromUser(this.context, ['ohos.permission.CAMERA'])
          .then((data: PermissionRequestResult) => {
            let grantStatus: number[] = data.authResults;
            if (grantStatus[0] === 0) {
              this.hasPermission = true;
              console.info('Succeeded in getting requestPermission.');
            } else {
              this.hasPermission = false;
              console.error('Failed to get requestPermission, user rejected.');
            }
          })
          .catch((err: BusinessError) => {
            console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}.`);
          })
      }
    }
    ```