# 如何设置不同时间策略实现屏幕时间守护

#### 问题现象

如何通过[Screen Time Guard Kit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screen-time-guard-kit-guide)实现限制每天只能使用1个小时的手机？  

#### 背景知识

[守护策略管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screentimeguard-guard-strategy-manage)：当用户希望创建新的屏幕时间守护规则时，可以调用添加管控策略的接口。根据参数中传入的策略，用户可以添加各种策略，如设置各个应用的停用起止时间。一旦策略被创建并启用，系统将根据规则对用户的屏幕使用行为进行监管。

ACL权限申请：使用Screen Time Guard Kit（屏幕时间守护服务）需要申请"ohos.permission.MANAGE_SCREEN_TIME_GUARD"ACL权限，具体参考官网[受限ACL权限申请](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screentimeguard-permission-application)。  

#### 解决方案

准备工作：完成[配置签名](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screentimeguard-app-signature)和[受限ACL权限申请](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screentimeguard-permission-application)。可使用自动签名完成ACL权限调试配置，具体参考[自动签名支持的ACL权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-signing#section5301916183411)。

* 步骤一： Screen Time Guard Kit支持对用户设备的时间管理和应用限制，因此在功能启用前，必须获得用户的明确授权。具体流程参考[请求用户授权](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screentimeguard-request-user-auth)。

  ```
  try {
    const status = await guardService.getUserAuthStatus();
    hilog.info(0x0000, `ScreenTimeGuard:getUserAuthStatus`, `user auth status: ${status}`);
    if (status != guardService.AuthStatus.AUTH_GRANTED) {
      await guardService.requestUserAuth(this.getUIContext().getHostContext() as common.UIAbilityContext);
    }
  } catch (err) {
    const message = (err as BusinessError).message;
    const code = (err as BusinessError).code;
    hilog.error(0x0000, `ScreenTimeGuard:requestUserAuth`,
      `requestUserAuth failed with error code: ${code}, message: ${message}`);
  }
  ```

* 步骤二： [TimeStrategyType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/screentimeguard-guardservice#timestrategytype)时长策略类型有以下3种类型，按照不同的场景配置策略类型，具体配置如下：

  * START_END_TIME_TYPE：管控策略可以设置为起止时间策略，表示策略在一天内配置的起始时间和结束时间内生效。常用于周期性管控，使用场景举例：每天22点到第二天7点，禁止使用XX应用。  
    ![](https://media:301785305066112833)  
    如果为此类型，则TimeStrategy接口中的startTime、endTime必填，totalDuration非必填。

    ```
    // 添加起始时间策略
    try {
      // 先调用startAppPicker获取相应应用的token
      const tokens = await appPicker.startAppPicker(this.getUIContext().getHostContext(), { appTokens: [] });
      const startEndTime: guardService.TimeStrategy = {
        type: guardService.TimeStrategyType.START_END_TIME_TYPE,
        startTime: '08:00',
        endTime: '19:00',
      };
      const info: guardService.AppInfo = {
        appTokens: tokens
      };
      const strategy: guardService.GuardStrategy = {
        name: 'startEndTimeStrategy',
        timeStrategy: startEndTime,
        appInfo: info,
        appRestrictionType: guardService.RestrictionType.BLOCKLIST_TYPE
      };
      await guardService.addGuardStrategy(strategy);
      this.currentStrategy = 'startEndTimeStrategy';
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:addGuardStrategy`,
        `addGuardStrategy failed with error code: ${code}, message: ${message}`);
    }
    ```

  <!-- -->

  * TOTAL_DURATION_TYPE：总时长策略类型，表示一天内策略生效的总时长，从调用startGuardStrategy接口成功后开始计时。使用场景举例：启动策略后1小时内，禁止使用XX应用。  
    ![](https://media:301785305066137834)  
    如果为此类型，则TimeStrategy接口中的startTime、endTime非必填，totalDuration必填。

    ```
    // 添加总时长策略
    try {
      // 先调用startAppPicker获取相应应用的token
      const tokens = await appPicker.startAppPicker(this.getUIContext().getHostContext(), { appTokens: [] });
      const totalDurationTime: guardService.TimeStrategy = {
        type: guardService.TimeStrategyType.TOTAL_DURATION_TYPE,
        totalDuration: 3,
      };
      const info: guardService.AppInfo = {
        appTokens: tokens
      };
      const strategy: guardService.GuardStrategy = {
        name: 'totalDurationTimeStrategy',
        timeStrategy: totalDurationTime,
        appInfo: info,
        appRestrictionType: guardService.RestrictionType.BLOCKLIST_TYPE
      };
      await guardService.addGuardStrategy(strategy);
      this.currentStrategy = 'totalDurationTimeStrategy';
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:addGuardStrategy`,
        `addGuardStrategy failed with error code: ${code}, message: ${message}`);
    }
    ```

  <!-- -->

  * INCLUSIVE_DURATION_TYPE：共享时长策略类型，表示策略关联的所有应用共享同一可用时长配额，超额后所有应用均受时长限制，从调用startGuardStrategy接口成功后开始计时。使用场景举例：每天限制使用指定视频类应用（A应用、B应用）时长2小时。  
    ![](https://media:301785305066164835)  
    如果为此类型，则TimeStrategy接口中的startTime、endTime非必填，totalDuration必填，RestrictionType只支持TRUSTLIST_TYPE。

    ```
    // 添加共享时长策略
    try {
      // 先调用startAppPicker获取相应应用的token
      const tokens = await appPicker.startAppPicker(this.getUIContext().getHostContext(), { appTokens: [] });
      const inclusiveDurationTime: guardService.TimeStrategy = {
        type: guardService.TimeStrategyType.INCLUSIVE_DURATION_TYPE,
        totalDuration: 3,
      };
      const info: guardService.AppInfo = {
        appTokens: tokens
      };
      const strategy: guardService.GuardStrategy = {
        name: 'inclusiveDurationTimeStrategy',
        timeStrategy: inclusiveDurationTime,
        appInfo: info,
        appRestrictionType: guardService.RestrictionType.TRUSTLIST_TYPE
      };
      await guardService.addGuardStrategy(strategy);
      this.currentStrategy = 'inclusiveDurationTimeStrategy';
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:addGuardStrategy`,
        `addGuardStrategy failed with error code: ${code}, message: ${message}`);
    }
    ```

* 步骤三： 确认并生成管控策略后，根据参数中传入的策略名，应用可以启动对应管控策略。具体流程参考[启动策略](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/screentimeguard-start-guard-strategy)。

  ```
  async startGuardStrategy(strategyName: string) {
    try {
      await guardService.startGuardStrategy(strategyName);
      hilog.info(0x0000, `ScreenTimeGuard:startGuardStrategy`, 'success');
      this.getUIContext().getPromptAction().showToast({
        message: 'startGuardStrategy success',
        duration: 2000,
      });
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:startGuardStrategy`,
        `startGuardStrategy failed with error code: ${code}, message: ${message}`);
    }
  }
  ```

完整代码：

```
import { appPicker, guardService } from '@kit.ScreenTimeGuardKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct Index {
  @State currentStrategy?: string = '';

  async aboutToAppear(): Promise<void> {
    try {
      const status = await guardService.getUserAuthStatus();
      hilog.info(0x0000, `ScreenTimeGuard:getUserAuthStatus`, `user auth status: ${status}`);
      if (status != guardService.AuthStatus.AUTH_GRANTED) {
        await guardService.requestUserAuth(this.getUIContext().getHostContext() as common.UIAbilityContext);
      }
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:requestUserAuth`,
        `requestUserAuth failed with error code: ${code}, message: ${message}`);
    }
  }

  async startGuardStrategy(strategyName: string) {
    try {
      await guardService.startGuardStrategy(strategyName);
      hilog.info(0x0000, `ScreenTimeGuard:startGuardStrategy`, 'success');
      this.getUIContext().getPromptAction().showToast({
        message: 'startGuardStrategy success',
        duration: 2000,
      });
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:startGuardStrategy`,
        `startGuardStrategy failed with error code: ${code}, message: ${message}`);
    }
  }

  async stopGuardStrategy(strategyName: string) {
    try {
      await guardService.stopGuardStrategy(strategyName);
      hilog.info(0x0000, `ScreenTimeGuard:stopGuardStrategy`, 'success');
      this.getUIContext().getPromptAction().showToast({
        message: 'stopGuardStrategy success',
        duration: 2000,
      });
    } catch (err) {
      const message = (err as BusinessError).message;
      const code = (err as BusinessError).code;
      hilog.error(0x0000, `ScreenTimeGuard:stopGuardStrategy`,
        `stopGuardStrategy failed with error code: ${code}, message: ${message}`);
    }
  }

  build() {
    Column({ space: 10 }) {
      Text('当前策略：' + this.currentStrategy);

      Button('添加起始时间策略')
        .onClick(async () => {
          try {
            await guardService.removeGuardStrategy('startEndTimeStrategy');
          } catch (err) {
            const message = (err as BusinessError).message;
            const code = (err as BusinessError).code;
            hilog.error(0x0000, `ScreenTimeGuard:removeGuardStrategy`,
              `removeGuardStrategy failed with error code: ${code}, message: ${message}`);
          }
          // 添加起始时间策略
          try {
            // 先调用startAppPicker获取相应应用的token
            const tokens = await appPicker.startAppPicker(this.getUIContext().getHostContext(), { appTokens: [] });
            const startEndTime: guardService.TimeStrategy = {
              type: guardService.TimeStrategyType.START_END_TIME_TYPE,
              startTime: '08:00',
              endTime: '19:00',
            };
            const info: guardService.AppInfo = {
              appTokens: tokens
            };
            const strategy: guardService.GuardStrategy = {
              name: 'startEndTimeStrategy',
              timeStrategy: startEndTime,
              appInfo: info,
              appRestrictionType: guardService.RestrictionType.BLOCKLIST_TYPE
            };
            await guardService.addGuardStrategy(strategy);
            this.currentStrategy = 'startEndTimeStrategy';
          } catch (err) {
            const message = (err as BusinessError).message;
            const code = (err as BusinessError).code;
            hilog.error(0x0000, `ScreenTimeGuard:addGuardStrategy`,
              `addGuardStrategy failed with error code: ${code}, message: ${message}`);
          }
        })

      Button('添加总时长策略')
        .onClick(async () => {
          try {
            await guardService.removeGuardStrategy('totalDurationTimeStrategy');
          } catch (err) {
            const message = (err as BusinessError).message;
            const code = (err as BusinessError).code;
            hilog.error(0x0000, `ScreenTimeGuard:removeGuardStrategy`,
              `removeGuardStrategy failed with error code: ${code}, message: ${message}`);
          }

          // 添加总时长策略
          try {
            // 先调用startAppPicker获取相应应用的token
            const tokens = await appPicker.startAppPicker(this.getUIContext().getHostContext(), { appTokens: [] });
            const totalDurationTime: guardService.TimeStrategy = {
              type: guardService.TimeStrategyType.TOTAL_DURATION_TYPE,
              totalDuration: 3,
            };
            const info: guardService.AppInfo = {
              appTokens: tokens
            };
            const strategy: guardService.GuardStrategy = {
              name: 'totalDurationTimeStrategy',
              timeStrategy: totalDurationTime,
              appInfo: info,
              appRestrictionType: guardService.RestrictionType.BLOCKLIST_TYPE
            };
            await guardService.addGuardStrategy(strategy);
            this.currentStrategy = 'totalDurationTimeStrategy';
          } catch (err) {
            const message = (err as BusinessError).message;
            const code = (err as BusinessError).code;
            hilog.error(0x0000, `ScreenTimeGuard:addGuardStrategy`,
              `addGuardStrategy failed with error code: ${code}, message: ${message}`);
          }
        })

      Button('添加共享时长策略')
        .onClick(async () => {
          try {
            await guardService.removeGuardStrategy('inclusiveDurationTimeStrategy');
          } catch (err) {
            const message = (err as BusinessError).message;
            const code = (err as BusinessError).code;
            hilog.error(0x0000, `ScreenTimeGuard:removeGuardStrategy`,
              `removeGuardStrategy failed with error code: ${code}, message: ${message}`);
          }

          // 添加共享时长策略
          try {
            // 先调用startAppPicker获取相应应用的token
            const tokens = await appPicker.startAppPicker(this.getUIContext().getHostContext(), { appTokens: [] });
            const inclusiveDurationTime: guardService.TimeStrategy = {
              type: guardService.TimeStrategyType.INCLUSIVE_DURATION_TYPE,
              totalDuration: 3,
            };
            const info: guardService.AppInfo = {
              appTokens: tokens
            };
            const strategy: guardService.GuardStrategy = {
              name: 'inclusiveDurationTimeStrategy',
              timeStrategy: inclusiveDurationTime,
              appInfo: info,
              appRestrictionType: guardService.RestrictionType.TRUSTLIST_TYPE
            };
            await guardService.addGuardStrategy(strategy);
            this.currentStrategy = 'inclusiveDurationTimeStrategy';
          } catch (err) {
            const message = (err as BusinessError).message;
            const code = (err as BusinessError).code;
            hilog.error(0x0000, `ScreenTimeGuard:addGuardStrategy`,
              `addGuardStrategy failed with error code: ${code}, message: ${message}`);
          }
        })

      Button('启动当前策略')
        .onClick(() => {
          if (this.currentStrategy) {
            this.startGuardStrategy(this.currentStrategy);
          } else {
            this.getUIContext().getPromptAction().showToast({
              message: '请先设置当前策略',
              duration: 2000,
            });
          }
        })

      Button('停止当前策略')
        .onClick(() => {
          if (this.currentStrategy) {
            this.stopGuardStrategy(this.currentStrategy);
          } else {
            this.getUIContext().getPromptAction().showToast({
              message: '请先设置当前策略',
              duration: 2000,
            });
          }
        })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center);
  }
}
```

