OpenHarmony定制系统组合按键(二)

一、开发环境

系统版本:OpenHarmony 4.0.10.13
设备平台:rk3568
SDK版本:fullSDK 4.0.10.13
DevEco Studio版本:4.1.0.400

二、需求背景

定制OpenHarmony 系统组合按键功能,例如仿Android Power + VOL_Up组合键实现截屏功能

为了实现需求,上一文OpenHarmony定制系统组合按键(一)中创建了一个开机自启的后台服务,将用来订阅组合按键事件,本文详细介绍如何订阅系统组合事件

三、ServiceExtensionAbility订阅组合按键

3.1 定义组合按键配置

首先在ServiceExtAbility.ets中定义好组合按键的配置
这里定义了两组:

  • Power + volUp > 截屏
  • Mute + volDown >系统设置
const SCREENSHOT_KEY_OPTIONS: inputConsumer.KeyOptions = {
  preKeys: [KeyCode.KEYCODE_POWER],
  finalKey: KeyCode.KEYCODE_VOLUME_UP,
  isFinalKeyDown: true,
  finalKeyDownDuration: 0
}

const SETTINGS_KEY_OPTIONS: inputConsumer.KeyOptions = {
  preKeys: [KeyCode.KEYCODE_MUTE],
  finalKey: KeyCode.KEYCODE_VOLUME_DOWN,
  isFinalKeyDown: true,
  finalKeyDownDuration: 0
}

3.2 订阅组合按键

在ServiceExtAbility.ets的onCreate()中

export default class ServiceExtAbility extends ServiceExtensionAbility {

  onCreate(want: Want): void {
    let serviceExtensionContext = this.context;
    hilog.info(DOMAIN_NUMBER, TAG, `onCreate, want: ${want.abilityName}`);

    //订阅截屏组合按键
    this.registerScreenshotKeys();

    //订阅打开设置组合按键
    this.registerSettingsKeys();
  };

	//订阅截屏组合按键
	registerScreenshotKeys() {
	    console.info(TAG, "registerScreenshotKeys is called")
	    //订阅截屏组合按键
	    let screenshotCallback = (keyOptions: inputConsumer.KeyOptions) => {
	      console.info(TAG, `screenshotKeyOptions: ${JSON.stringify(keyOptions)}`);
		  //跳转截屏应用
	      this.context.startAbility({
	        bundleName: 'com.ohos.screenshot',
	        abilityName: 'com.ohos.screenshot.ServiceExtAbility',
	        parameters: undefined
	      }).then(() => {
	        console.info(TAG, 'startAbility, then');
	      }).catch((error: BusinessError) => {
	        console.error(TAG, `startAbility, error: ${JSON.stringify(error)}`);
	
	      });
	    }
	
	    try {
	      inputConsumer.on("key", SCREENSHOT_KEY_OPTIONS, screenshotCallback);
	    } catch (error) {
	      console.error(TAG, `Subscribe screenshot failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
	    }
	  }

	//订阅打开设置组合按键
	registerSettingsKeys() {
	    console.info(TAG, "registerSettingsKeys is called")
	    //订阅截屏组合按键
	    let openSettingsCallback = (keyOptions: inputConsumer.KeyOptions) => {
	      console.info(TAG, `registerSettingsKeys: ${JSON.stringify(keyOptions)}`);
	      //跳转系统设置
	      this.context.startAbility({
	        bundleName: 'com.ohos.settings',
	        abilityName: 'com.ohos.settings.MainAbility',
	        parameters: undefined
	      }).then(() => {
	        console.info(TAG, 'startAbility, then');
	      }).catch((error: BusinessError) => {
	        console.error(TAG, `startAbility, error: ${JSON.stringify(error)}`);
	
	      });
	    }
	    try {
	      inputConsumer.on("key", SETTINGS_KEY_OPTIONS, openSettingsCallback);
	    } catch (error) {
	      console.error(TAG, `Subscribe open Settings failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
	    }
	  }
  }

3.3

当service 关闭时也需取消订阅

export default class ServiceExtAbility extends ServiceExtensionAbility {
  ...
  //取消订阅截屏组合按键
  unregisterScreenshotKeys() {
    console.info(TAG, "unregisterScreenshotKeys is called");
    let callback = (keyOptions: inputConsumer.KeyOptions) => {
      console.info(TAG, `keyOptions: ${JSON.stringify(keyOptions)}`);
    }
    try {
      inputConsumer.off("key", SCREENSHOT_KEY_OPTIONS, callback);
      console.info(`Unsubscribe screenshot keys success`);
    } catch (error) {
      console.error(`Execute failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
    }
  }

  //取消订阅打开设置组合按键
  unregisterSettingsKeys() {
    console.info(TAG, "unregisterSettingsKeys is called");
    let callback = (keyOptions: inputConsumer.KeyOptions) => {
      console.info(TAG, `keyOptions: ${JSON.stringify(keyOptions)}`);
    }
    try {
      inputConsumer.off("key", SETTINGS_KEY_OPTIONS, callback);
      console.info(`Unsubscribe open Settings keys success`);
    } catch (error) {
      console.error(`Execute failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
    }
  }
  ...
  onDestroy(): void {
    this.unregisterScreenshotKeys()
    this.unregisterSettingsKeys()
    hilog.info(DOMAIN_NUMBER, TAG, 'onDestroy');
  };
}

效果

Power + volUp > 截屏
请添加图片描述

Power + volDown > 跳转系统设置
请添加图片描述

总结

通过本文已基本实现组合键截屏和跳转设置功能,不过细心的同学肯定也发现了,在响应组合键的同时也响应了单独的音量键,这体验并不好,后文将通过另外一种方式实现需求,并改善这一问题

源码

module.json5

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "ServiceExtAbility",
    "deviceTypes": [
      "default",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ],
    "extensionAbilities": [
      {
        "name": "ServiceExtAbility",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "description": "service",
        "type": "service",
        "exported": true,
        "srcEntry": "./ets/services/ServiceExtAbility.ets"
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.START_ABILITIES_FROM_BACKGROUND"
      },
      {
        "name": "ohos.permission.CAPTURE_SCREEN"
      }
    ]
  }
}

ServiceExtAbility.ets源码

import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
import Want from '@ohos.app.ability.Want';
import hilog from '@ohos.hilog';
import rpc from '@ohos.rpc';
import inputConsumer from '@ohos.multimodalInput.inputConsumer';
import { KeyCode } from '@ohos.multimodalInput.keyCode';
import { BusinessError } from '@ohos.base';

const TAG: string = '[ServiceExtAbility]';
const DOMAIN_NUMBER: number = 0xFF00;

const SCREENSHOT_KEY_OPTIONS: inputConsumer.KeyOptions = {
  preKeys: [KeyCode.KEYCODE_POWER],
  finalKey: KeyCode.KEYCODE_VOLUME_UP,
  isFinalKeyDown: true,
  finalKeyDownDuration: 0
}

const SETTINGS_KEY_OPTIONS: inputConsumer.KeyOptions = {
  preKeys: [KeyCode.KEYCODE_POWER],
  finalKey: KeyCode.KEYCODE_VOLUME_DOWN,
  isFinalKeyDown: true,
  finalKeyDownDuration: 0
}

class ServiceStub extends rpc.RemoteObject {
  constructor(des: string) {
    super(des);
  }
}

export default class ServiceExtAbility extends ServiceExtensionAbility {

  onCreate(want: Want): void {
    let serviceExtensionContext = this.context;
    hilog.info(DOMAIN_NUMBER, TAG, `onCreate, want: ${want.abilityName}`);

    //订阅截屏组合按键
    this.registerScreenshotKeys();

    //订阅打开设置组合按键
    this.registerSettingsKeys();
  };

  registerScreenshotKeys() {
    console.info(TAG, "registerScreenshotKeys is called")
    //订阅截屏组合按键
    let screenshotCallback = (keyOptions: inputConsumer.KeyOptions) => {
      console.info(TAG, `screenshotKeyOptions: ${JSON.stringify(keyOptions)}`);

      this.context.startAbility({
        bundleName: 'com.ohos.screenshot',
        abilityName: 'com.ohos.screenshot.ServiceExtAbility',
        parameters: undefined
      }).then(() => {
        console.info(TAG, 'startAbility, then');
      }).catch((error: BusinessError) => {
        console.error(TAG, `startAbility, error: ${JSON.stringify(error)}`);

      });
    }

    try {
      inputConsumer.on("key", SCREENSHOT_KEY_OPTIONS, screenshotCallback);
    } catch (error) {
      console.error(TAG, `Subscribe screenshot failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
    }
  }

  unregisterScreenshotKeys() {
    console.info(TAG, "unregisterScreenshotKeys is called");
    let callback = (keyOptions: inputConsumer.KeyOptions) => {
      console.info(TAG, `keyOptions: ${JSON.stringify(keyOptions)}`);
    }
    try {
      inputConsumer.off("key", SCREENSHOT_KEY_OPTIONS, callback);
      console.info(`Unsubscribe screenshot keys success`);
    } catch (error) {
      console.error(`Execute failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
    }
  }

  registerSettingsKeys() {
    console.info(TAG, "registerSettingsKeys is called")
    //订阅截屏组合按键
    let openSettingsCallback = (keyOptions: inputConsumer.KeyOptions) => {
      console.info(TAG, `registerSettingsKeys: ${JSON.stringify(keyOptions)}`);
      this.context.startAbility({
        bundleName: 'com.ohos.settings',
        abilityName: 'com.ohos.settings.MainAbility',
        parameters: undefined
      }).then(() => {
        console.info(TAG, 'startAbility, then');
      }).catch((error: BusinessError) => {
        console.error(TAG, `startAbility, error: ${JSON.stringify(error)}`);

      });
    }
    try {
      inputConsumer.on("key", SETTINGS_KEY_OPTIONS, openSettingsCallback);
    } catch (error) {
      console.error(TAG, `Subscribe open Settings failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
    }
  }

  unregisterSettingsKeys() {
    console.info(TAG, "unregisterSettingsKeys is called");
    let callback = (keyOptions: inputConsumer.KeyOptions) => {
      console.info(TAG, `keyOptions: ${JSON.stringify(keyOptions)}`);
    }
    try {
      inputConsumer.off("key", SETTINGS_KEY_OPTIONS, callback);
      console.info(`Unsubscribe open Settings keys success`);
    } catch (error) {
      console.error(`Execute failed, error: ${JSON.stringify(error, [`code`, `message`])}`);
    }
  }

  onRequest(want: Want, startId: number): void {
    hilog.info(DOMAIN_NUMBER, TAG, `onRequest, want: ${want.abilityName}`);
  };

  onConnect(want: Want): rpc.RemoteObject {
    hilog.info(DOMAIN_NUMBER, TAG, `onConnect, want: ${want.abilityName}`);
    // 返回ServiceExtImpl对象,客户端获取后便可以与ServiceExtensionAbility进行通信
    return new ServiceStub('ServiceExtAbilityService');
  };

  onDisconnect(want: Want): void {
    hilog.info(DOMAIN_NUMBER, TAG, `onDisconnect, want: ${want.abilityName}`);
  };

  onDestroy(): void {
    this.unregisterScreenshotKeys()
    this.unregisterSettingsKeys()
    hilog.info(DOMAIN_NUMBER, TAG, 'onDestroy');
  };
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值