diff --git a/CODEOWNERS b/CODEOWNERS index 81d411b4860e6baaff515d258356e6c6e84b2a56..290a26ec5a16959c3d13f5862973fed533bffe6b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,18 +1,19 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - + +- Copyright (c) 2021-2022 Huawei Device Co., Ltd. +- Licensed under the Apache License, Version 2.0 (the "License"); +- you may not use this file except in compliance with the License. +- You may obtain a copy of the License at +* +- http://www.apache.org/licenses/LICENSE-2.0 +* +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +*/ + zh-cn/device-dev/kernel/ @Austin23 zh-cn/device-dev/website.md @Austin23 zh-cn/device-dev/faqs/ @Austin23 @@ -133,340 +134,476 @@ zh-cn/application-dev/ability/ @RayShih @littlejerry1 @gwang2008 @ccllee @chengx zh-cn/application-dev/IDL/ @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen zh-cn/application-dev/device-usage-statistics/ @RayShih @shuaytao @wangzhen107 @inter515 zh-cn/application-dev/ui/ @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/notification/ @RayShih -zh-cn/application-dev/windowmanager/ @ge-yafang -zh-cn/application-dev/webgl/ @ge-yafang -zh-cn/application-dev/media/ @zengyawen -zh-cn/application-dev/security/ @zengyawen -zh-cn/application-dev/connectivity/ @zengyawen -zh-cn/application-dev/connectivity/ipc-rpc-overview.md @qinxiaowang -zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md @qinxiaowang -zh-cn/application-dev/connectivity/subscribe-remote-state.md @qinxiaowang -zh-cn/application-dev/telephony/ @zengyawen -zh-cn/application-dev/dfx/ @zengyawen -zh-cn/application-dev/database/ @ge-yafang -zh-cn/application-dev/napi/drawing_guidelines.md @ge-yafang -zh-cn/application-dev/napi/native-window-guidelines.md @ge-yafang -zh-cn/application-dev/napi/mindspore-lite-guidelines.md @ge-yafang -zh-cn/application-dev/napi/rawfile_guidelines.md @HelloCrease +zh-cn/application-dev/notification/ @RayShih @jayleehw @li-weifeng2 @currydavids +zh-cn/application-dev/windowmanager/ @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee +zh-cn/application-dev/webgl/ @zengyawen @zhangqiang183 @wind_zj @zxg-gitee +zh-cn/application-dev/media/audio-overview.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-playback.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-recorder.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-renderer.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-stream-manager.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-capturer.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/opensles-playback.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/opensles-capture.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-interruptmode.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-volume-manager.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/audio-routing-manager.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/video-playback.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/video-recorder.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/avsession-overview.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/avsession-guidelines.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/image.md @zengyawen @zhangqiang183 @wind_zj @zxg-gitee +zh-cn/application-dev/media/camera.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/media/remote-camera.md @zengyawen @liuyuehua1 @saga2020 @currydavids +zh-cn/application-dev/security/accesstoken-overview.md @zengyawen @nianCode @nianCode @jinhaihw +zh-cn/application-dev/security/accesstoken-guidelines.md @zengyawen @nianCode @nianCode @jinhaihw +zh-cn/application-dev/security/permission-verify-guidelines.md @zengyawen @nianCode @nianCode @jinhaihw +zh-cn/application-dev/security/permission-list.md @zengyawen @zengyawen @nianCode @nianCode @jinhaihw +zh-cn/application-dev/security/userauth-overview.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/userauth-guidelines.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/huks-overview.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/huks-guidelines.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/cryptoFramework-overview.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/cryptoFramework-guidelines.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/hapsigntool-overview.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/hapsigntool-guidelines.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/security/app-provision-structure.md @zengyawen @gaoyong @niejiteng @jumozhanjiang +zh-cn/application-dev/connectivity/net-mgmt-overview.md @zengyawen @zhang-hai-feng @jyh926 @gaoxi785 +zh-cn/application-dev/connectivity/http-request.md @zengyawen @zhang-hai-feng @jyh926 @gaoxi785 +zh-cn/application-dev/connectivity/websocket-connection.md @zengyawen @zhang-hai-feng @jyh926 @gaoxi785 +zh-cn/application-dev/connectivity/socket-connection.md @zengyawen @zhang-hai-feng @jyh926 @gaoxi785 +zh-cn/application-dev/connectivity/ipc-rpc-overview.md @RayShih @xuepianpian @zhaopeng_gitee @vagrant_world +zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md @RayShih @xuepianpian @zhaopeng_gitee @vagrant_world +zh-cn/application-dev/connectivity/subscribe-remote-state.md @RayShih @xuepianpian @zhaopeng_gitee @vagrant_world +zh-cn/application-dev/telephony/ @zengyawen @zhang-hai-feng @jyh926 @gaoxi785 +zh-cn/application-dev/dfx/hiappevent-overview.md @zengyawen @stone2050 @stesen @elsen-liu +zh-cn/application-dev/dfx/hiappevent-guidelines.md @zengyawen @stone2050 @stesen @elsen-liu +zh-cn/application-dev/dfx/hitracemeter-overview.md @zengyawen @stone2050 @stesen @elsen-liu +zh-cn/application-dev/dfx/hitracemeter-guidelines.md @zengyawen @stone2050 @stesen @elsen-liu +zh-cn/application-dev/dfx/hitracechain-overview.md @zengyawen @stone2050 @stesen @elsen-liu +zh-cn/application-dev/dfx/hitracechain-guidelines.md @zengyawen @stone2050 @stesen @elsen-liu +zh-cn/application-dev/dfx/errormanager-guidelines.md @littlejerry1 @ccllee @chengxingzhen @RayShih +zh-cn/application-dev/dfx/errormanager-guidelines.md @littlejerry1 @ccllee @chengxingzhen @RayShih +zh-cn/application-dev/key-features/multi-device-app-dev/ @lingminghw @crazyracing0726 +zh-cn/application-dev/database/ @ge-yafang @feng-aiwen @gong-a-shi @logic42 +zh-cn/application-dev/napi/native-window-guidelines.md @ge-yafang @zhangqiang183 @zhouyaoying @zxg-gitee +zh-cn/application-dev/napi/mindspore-lite-guidelines.md @ge-yafang @grbuzhidao @jianghui58 @auraxu +zh-cn/application-dev/napi/rawfile_guidelines.md @ningningW zh-cn/application-dev/background-agent-scheduled-reminder/ @RayShih -zh-cn/application-dev/background-task-management/ @RayShih -zh-cn/application-dev/work-scheduler/ @HelloCrease -zh-cn/application-dev/internationalization/ @HelloCrease -zh-cn/application-dev/device/usb-overview.md @ge-yafang -zh-cn/application-dev/device/usb-guidelines.md @ge-yafang -zh-cn/application-dev/device/device-location-overview.md @zengyawen -zh-cn/application-dev/device/device-location-info.md @zengyawen -zh-cn/application-dev/device/device-location-geocoding.md @zengyawen -zh-cn/application-dev/device/sensor-overview.md @HelloCrease -zh-cn/application-dev/device/sensor-guidelines.md @HelloCrease -zh-cn/application-dev/device/vibrator-overview.md @HelloCrease -zh-cn/application-dev/device/vibrator-guidelines.md @HelloCrease -zh-cn/application-dev/device/sample-server-overview.md @HelloCrease -zh-cn/application-dev/device/sample-server-guidelines.md @HelloCrease -zh-cn/application-dev/reference/arkui-js/ @HelloCrease -zh-cn/application-dev/reference/arkui-ts/ @HelloCrease -zh-cn/application-dev/reference/native-apis @RayShih -zh-cn/application-dev/reference/native-lib @RayShih +zh-cn/application-dev/background-task-management/ @ningningW @wangwenli_wolf @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/work-scheduler/ @ningningW +zh-cn/application-dev/internationalization/ @ningningW @Buda-Liu @budda-wang @yangqing3 +zh-cn/application-dev/device/usb-overview.md @ge-yafang @jasonyujia @andeszhang @liuhonggang123 +zh-cn/application-dev/device/usb-guidelines.md @ge-yafang @jasonyujia @andeszhang @liuhonggang123 +zh-cn/application-dev/device/device-location-overview.md @RayShih +zh-cn/application-dev/device/device-location-info.md @RayShih +zh-cn/application-dev/device/device-location-geocoding.md @RayShih +zh-cn/application-dev/device/sensor-overview.md @ningningW @hellohyh001 @butterls @star-wind-snow-and-rain +zh-cn/application-dev/device/sensor-guidelines.md @ningningW @hellohyh001 @butterls @star-wind-snow-and-rain +zh-cn/application-dev/device/vibrator-overview.md @ningningW @hellohyh001 @butterls @star-wind-snow-and-rain +zh-cn/application-dev/device/vibrator-guidelines.md @ningningW @hellohyh001 @butterls @star-wind-snow-and-rain +zh-cn/application-dev/device/sample-server-overview.md @ningningW @hughes802 @zhangzhengxue @mamba-ting +zh-cn/application-dev/device/sample-server-guidelines.md @ningningW @hughes802 @zhangzhengxue @mamba-ting +zh-cn/application-dev/reference/arkui-js/ @HelloCrease @huaweimaxuchu @niulihua @tomatodevboy +zh-cn/application-dev/reference/arkui-ts/ @HelloCrease @huaweimaxuchu @niulihua @tomatodevboy +zh-cn/application-dev/reference/native-lib @zengyawen @gongjunsong @liwentao_uiw @BlackStone zh-cn/application-dev/quick-start/start-overview.md @ge-yafang zh-cn/application-dev/quick-start/start-with-ets-stage.md @ge-yafang zh-cn/application-dev/quick-start/start-with-ets-fa.md @ge-yafang -zh-cn/application-dev/quick-start/start-with-js-fa.md @ge-yafang -zh-cn/application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md @ge-yafang -zh-cn/application-dev/quick-start/package-structure.md @RayShih -zh-cn/application-dev/quick-start/basic-resource-file-categories.md @RayShih -zh-cn/application-dev/quick-start/syscap.md @RayShih -zh-cn/application-dev/napi/napi-guidelines.md @RayShih -zh-cn/application-dev/napi/drawing-guidelines.md @ge-yafang -zh-cn/application-dev/napi/rawfile-guidelines.md @HelloCrease +zh-cn/application-dev/quick-start/start-with-js-fa.md @ge-yafang +zh-cn/application-dev/quick-start/application-package-overview.md @RayShih +zh-cn/application-dev/quick-start/application-package-structure-stage.md @RayShih +zh-cn/application-dev/quick-start/application-package-structure-fa.md @RayShih +zh-cn/application-dev/quick-start/har-structure.md @RayShih +zh-cn/application-dev/quick-start/multi-hap-objective.md @RayShih +zh-cn/application-dev/quick-start/multi-hap-build-view.md @RayShih +zh-cn/application-dev/quick-start/multi-hap-release-deployment.md @RayShih +zh-cn/application-dev/quick-start/multi-hap-rules.md @RayShih +zh-cn/application-dev/quick-start/multi-hap-principles.md @RayShih +zh-cn/application-dev/quick-start/application-package-install-uninstall.md @RayShih +zh-cn/application-dev/quick-start/application-configuration-file-overview-stage.md @RayShih +zh-cn/application-dev/quick-start/app-configuration-file.md @RayShih +zh-cn/application-dev/quick-start/module-configuration-file.md @RayShih +zh-cn/application-dev/quick-start/application-configuration-file-overview-fa.md @RayShih +zh-cn/application-dev/quick-start/app-structure.md @RayShih +zh-cn/application-dev/quick-start/deviceconfig-structure.md @RayShih +zh-cn/application-dev/quick-start/module-structure.md @RayShih +zh-cn/application-dev/quick-start/resource-categories-and-access.md @RayShih +zh-cn/application-dev/quick-start/arkts-get-started.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-basic-ui-description.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-state-mgmt-concepts.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-state-mgmt-page-level.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-state-mgmt-application-level.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-dynamic-ui-elememt-building.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-rendering-control.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/quick-start/arkts-restrictions-and-extensions.md @gaoyong @niejiteng @jumozhanjiang @HelloCrease +zh-cn/application-dev/napi/napi-guidelines.md @RayShih @huaweimaxuchu @niulihua @tomatodevboy +zh-cn/application-dev/napi/drawing-guidelines.md @zengyawen @zhangqiang183 @wind_zj @zxg-gitee +zh-cn/application-dev/napi/rawfile-guidelines.md @ningningW @Buda-Liu @budda-wang @yangqing3 zh-cn/application-dev/reference/js-service-widget-ui/ @HelloCrease zh-cn/application-dev/faqs/ @zengyawen -zh-cn/application-dev/file-management/ @qinxiaowang -zh-cn/application-dev/application-test/ @HelloCrease -zh-cn/application-dev/device-usage-statistics/ @HelloCrease +zh-cn/application-dev/file-management/ @zengyawen +zh-cn/application-dev/application-test/ @ningningW +zh-cn/application-dev/device-usage-statistics/ @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-application-context.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-commonEvent.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-emitter.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-notification.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-reminderAgent.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-eventhub.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-Bundle.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-deviceUsageStatistics.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-zlib.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-animator.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-mediaquery.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-prompt.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-router.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-display.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-screenshot.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-window.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-effectKit.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-application-WindowExtensionAbility.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-screen.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-windowAnimationManager.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-webgl.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-webgl2.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-audio.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-camera.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-image.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-media.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-medialibrary.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-i18n.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-intl.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-resource-manager.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-backgroundTaskManager.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-workScheduler.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-WorkSchedulerExtensionAbility.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-config-policy.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-enterprise-device-manager.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-abilityAccessCtrl.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-huks.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-useriam-userauth.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-cipher.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-data-ability.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-DataShareResultSet.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-ValuesBucket.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-dataSharePredicates.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-dataShare.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-application-DataShareExtensionAbility.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-distributed-data.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-distributedobject.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-preferences.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-storage.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-system-storage.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-rdb.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-settings.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-data-resultset.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-document.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-environment.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-fileio.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-filemanager.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-statfs.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-storage-statistics.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-volumemanager.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-contact.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-call.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-observer.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-radio.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-sim.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-sms.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-telephony-data.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-net-connection.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-http.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-request.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-socket.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-webSocket.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-bluetooth.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-nfcTag.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-nfcTech.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-tagSession.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-connectedTag.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-rpc.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-wifi.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-wifiext.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-faultLogger.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hiappevent.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hichecker.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hidebug.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hilog.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hitracechain.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hitracemeter.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-inputmethod.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-inputmethodengine.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-pasteboard.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-screen-lock.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-system-time.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-wallpaper.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-timer.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-battery-info.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-brightness.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-device-info.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-device-manager.md -zh-cn/application-dev/reference/apis/js-apis-geolocation.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-inputconsumer.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-inputdevice.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-inputeventclient.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-inputmonitor.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-power.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-runninglock.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-sensor.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-system-sensor.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-system-parameter.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-thermal.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-update.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-usb.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-colorSpaceManager.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-vibrator.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-appAccount.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-distributed-account.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-osAccount.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-convertxml.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-process.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-uri.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-url.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-util.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-arraylist.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-deque.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hashmap.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-hashset.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-lightweightmap.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-lightweightset.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-linkedlist.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-list.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-plainarray.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-queue.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-stack.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-treemap.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-treeset.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-vector.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-worker.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-xml.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-testRunner.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-uitest.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-hisysevent.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-privacyManager.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-EnterpriseAdminExtensionAbility.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-animator.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-uiappearance.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-useriam-faceauth.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-userfilemanager.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-buffer.md @zengyawen -zh-cn/application-dev/reference/apis/development-intro.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-accessibility-extension-context.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-application-applicationContext.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-bundle-AbilityInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-ApplicationInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-BundleInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-BundleInstaller.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-CustomizeData.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-defaultAppManager.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-Bundle-distributedBundle.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-ElementName.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-ExtensionAbilityInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-HapModuleInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-Bundle-InnerBundleManager.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-LauncherAbilityInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-Metadata.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-ModuleInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-PermissionDef.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-remoteAbilityInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-ShortcutInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bytrace.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-cardEmulation.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-dispatchInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-distributedMissionManager.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-inputevent.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-keycode.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-keyevent.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-logs.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-mouseevent.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-nfcController.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-nfctech.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-pointer.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-securityLabel.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-system-app.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-system-battery.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-bluetooth.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-system-brightness.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-configuration.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-system-device.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-fetch.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-file.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-system-location.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-system-mediaquery.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-system-network.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-notification.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-system-package.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-system-prompt.md @HelloCrease @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-system-request.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-system-router.md @HelloCrease @qieqiewl @tomatodevboy @niulihua -zh-cn/application-dev/reference/apis/js-apis-system-timer.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-system-vibrate.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-touchevent.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-accessibility-config.md @RayShih -zh-cn/application-dev/reference/apis/js-apis-Bundle-BundleStatusCallback.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-bundle-PackInfo.md @RayShih @shuaytao @wangzhen107 @inter515 -zh-cn/application-dev/reference/apis/js-apis-enterpriseDeviceManager-DeviceSettingsManager.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-fileAccess.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-fileExtensionInfo.md @qinxiaowang -zh-cn/application-dev/reference/apis/js-apis-net-ethernet.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-net-policy.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-net-sharing.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-net-statistics.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-tlsSocket.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-reminderAgentManager.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-hiviewdfx-hiappevent.md @zengyawen -zh-cn/application-dev/reference/apis/js-apis-deviceUsageStatistics.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-resourceschedule-deviceUsageStatistics.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-cooperate.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-webview.md @HelloCrease -zh-cn/application-dev/reference/apis/js-apis-ability-context.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-ability-errorCode.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-ability-wantConstant.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-abilityDelegatorRegistry.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-abilityrunninginfo.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-abilitystagecontext.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-accessibility.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-ability.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilityConstant.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilityDelegator.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilityDelegatorArgs.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilityLifecycleCallback.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilityManager.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilityMonitor.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-abilitystage.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-AccessibilityExtensionAbility.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-applicationContext.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-context.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-EnvironmentCallback.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-MissionSnapshot.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-StartOptions.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-staticSubscriberExtensionAbility.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-application-Want.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-appmanager.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-configuration.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-configurationconstant.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-Context.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-continuation-continuationExtraParams.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-continuation-continuationManager.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-continuation-continuationResult.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-dataAbilityHelper.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-DataUriUtils.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-errorManager.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-extension-context.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-extensionrunninginfo.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-featureAbility.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formbindingdata.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formerror.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formextension.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formextensioncontext.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formhost.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formInfo.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-formprovider.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-inputmethod-extension-ability.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-inputmethod-extension-context.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-inputmethod-subtype.md @ge-yafang -zh-cn/application-dev/reference/errorcodes/errcode-inputmethod-framework.md @ge-yafang -zh-cn/application-dev/reference/errorcodes/errcode-usb.md @ge-yafang -zh-cn/application-dev/reference/errorcodes/errorcode-datashare.md @ge-yafang +zh-cn/application-dev/reference/apis/js-apis-ability-context.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-ability-errorCode.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-ability-wantConstant.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-abilityAccessCtrl.md @nianCode @zengyawen @shuqinglin2 @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-abilityDelegatorRegistry.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-abilityrunninginfo.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-abilitystagecontext.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-accessibility-extension-context.md @mupceet @RayShih @mupceet @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-animator.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-appAccount.md @nianCode @zengyawen @JiDong-CS @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-application-ability.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilityConstant.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilityDelegator.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilityDelegatorArgs.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilityLifecycleCallback.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilityManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilityMonitor.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-abilitystage.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-AccessibilityExtensionAbility.md @mupceet @RayShih @mupceet @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-applicationContext.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-context.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-DataShareExtensionAbility.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-application-EnvironmentCallback.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-MissionSnapshot.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-StartOptions.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-staticSubscriberExtensionAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-Want.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-WindowExtensionAbility.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-appmanager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-arraylist.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-audio.md @liuyuehua1 @zengyawen @magekkkk @currydavids +zh-cn/application-dev/reference/apis/js-apis-backgroundTaskManager.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-battery-info.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-bluetooth.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-brightness.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-buffer.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-bundle-AbilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-ApplicationInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-BundleInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-BundleInstaller.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-CustomizeData.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-Bundle-distributedBundle.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-ElementName.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-HapModuleInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-Bundle-InnerBundleManager.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-LauncherAbilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-ModuleInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-PermissionDef.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-remoteAbilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundle-ShortcutInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-Bundle.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bytrace.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-call.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-camera.md @liuyuehua1 @zengyawen @nongwa @currydavids +zh-cn/application-dev/reference/apis/js-apis-cardEmulation.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-commonEvent.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-configuration.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-configurationconstant.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-connectedTag.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-contact.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-Context.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-continuation-continuationExtraParams.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-continuation-continuationManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-continuation-continuationResult.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-convertxml.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-data-ability.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-dataShare.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-dataSharePredicates.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-DataShareResultSet.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-distributedobject.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-preferences.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-rdb.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-resultset.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-storage.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-data-ValuesBucket.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-dataAbilityHelper.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-DataUriUtils.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-deque.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-device-info.md @mupceet @zengyawen @handyohos @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-device-manager.md @intermilano @RayShih @william-ligang @liuhonggang123 +zh-cn/application-dev/reference/apis/js-apis-deviceUsageStatistics.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-display.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-distributed-account.md @nianCode @zengyawen @JiDong-CS @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-distributed-data.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-distributedMissionManager.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-document.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-effectKit.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-emitter.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-EnterpriseAdminExtensionAbility.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-environment.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-errorManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-eventhub.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-extension-context.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-extensionrunninginfo.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-faultLogger.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-featureAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-fileio.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-formbindingdata.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-formerror.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-formextension.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-formextensioncontext.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-formhost.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-formInfo.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-formprovider.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-geolocation.md @cheng_guohong @RayShih @cheng_guohong @xiangkejin123 +zh-cn/application-dev/reference/apis/js-apis-hashmap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-hashset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-hiappevent.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-hichecker.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-hidebug.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-hilog.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-hisysevent.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-hitracechain.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-hitracemeter.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-http.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-huks.md @gaoyong @zengyawen @niejiteng @jumozhanjiang +zh-cn/application-dev/reference/apis/js-apis-i18n.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-image.md @zhangqiang183 @zengyawen @chenyuheng @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-inputconsumer.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-inputdevice.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-inputevent.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-inputeventclient.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-inputmethod-extension-ability.md @feng-aiwen @ge-yafang @SuperShrimp @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-inputmethod-extension-context.md @feng-aiwen @ge-yafang @SuperShrimp @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-inputmethod.md @feng-aiwen @ge-yafang @SuperShrimp @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-inputmethodengine.md @feng-aiwen @ge-yafang @SuperShrimp @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-inputmonitor.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-intl.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-keycode.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-keyevent.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-lightweightmap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-lightweightset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-linkedlist.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-list.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-logs.md @huaweimaxuchu @ningningW @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-media.md @liuyuehua1 @zengyawen @xxb-wzy @currydavids +zh-cn/application-dev/reference/apis/js-apis-medialibrary.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-mediaquery.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-missionManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-mouseevent.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-net-connection.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-nfcController.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-nfcTag.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-notification.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-observer.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-osAccount.md @nianCode @zengyawen @JiDong-CS @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-particleAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-pasteboard.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-permissionrequestresult.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-plainarray.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-pointer.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-power.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-privacyManager.md @nianCode @zengyawen @shuqinglin2 @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-process.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-processrunninginformation.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-prompt.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-queue.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-radio.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-reminderAgent.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-request.md @feng-aiwen @zengyawen @nagexiucai @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-resource-manager.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-router.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-rpc.md @xuepianpian @RayShih @zhaopeng_gitee @vagrant_world +zh-cn/application-dev/reference/apis/js-apis-runninglock.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-screen-lock.md @feng-aiwen @ge-yafang @wangzhangjun @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-screen.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-screenshot.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-securityLabel.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-sensor.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain +zh-cn/application-dev/reference/apis/js-apis-service-extension-ability.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-service-extension-context.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-settings.md @tetex @ge-yafang @cnzhaoxiaohu @anning7 +zh-cn/application-dev/reference/apis/js-apis-sim.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-sms.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-socket.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-stack.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-statfs.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-storage-statistics.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-system-app.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-system-battery.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-system-bluetooth.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-system-brightness.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-system-cipher.md @gaoyong @zengyawen @niejiteng @jumozhanjiang +zh-cn/application-dev/reference/apis/js-apis-system-configuration.md @Buda-Liu @ningningW @budda-wang @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-system-device.md @mupceet @zengyawen @handyohos @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-system-fetch.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-system-file.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-system-location.md @cheng_guohong @RayShih @cheng_guohong @xiangkejin123 +zh-cn/application-dev/reference/apis/js-apis-system-mediaquery.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-system-network.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-system-notification.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-system-package.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-system-parameter.md @mupceet @zengyawen @handyohos @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-system-prompt.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-system-request.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-system-router.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-system-sensor.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain +zh-cn/application-dev/reference/apis/js-apis-system-storage.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-system-time.md @feng-aiwen @ge-yafang @illybyy @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-system-timer.md @feng-aiwen @ge-yafang @illybyy @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-system-vibrate.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain +zh-cn/application-dev/reference/apis/js-apis-telephony-data.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-testRunner.md @inter515 @littlejerry1 @RayShih @inter515 @jiyong +zh-cn/application-dev/reference/apis/js-apis-thermal.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-timer.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-touchevent.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-treemap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-treeset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-uitest.md @inter515 @ningningW @inter515 @jiyong +zh-cn/application-dev/reference/apis/js-apis-update.md @hughes802 @ningningW @zhangzhengxue @mamba-ting +zh-cn/application-dev/reference/apis/js-apis-uri.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-url.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-usb.md @jasonyujia @ge-yafang @andeszhang @liuhonggang123 +zh-cn/application-dev/reference/apis/js-apis-useriam-userauth.md @gaoyong @zengyawen @niejiteng @jumozhanjiang +zh-cn/application-dev/reference/apis/js-apis-util.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-vector.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-vibrator.md @hellohyh001 @ningningW @butterls @star-wind-snow-and-rain +zh-cn/application-dev/reference/apis/js-apis-volumemanager.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-wallpaper.md @feng-aiwen @ge-yafang @wangzhangjun @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-wantAgent.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-webgl.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-webgl2.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-webSocket.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-wifi.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-wifiext.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-window.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-windowAnimationManager.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-worker.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-workScheduler.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-WorkSchedulerExtensionAbility.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-xml.md @gongjunsong @ge-yafang @flyingwolf @BlackStone +zh-cn/application-dev/reference/apis/js-apis-zlib.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-webview.md @bigpumpkin @HelloCrease @litao33 @zhang-xinyue15 +zh-cn/application-dev/reference/apis/js-apis-ability-ability.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-ability-abilityResult.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-ability-Want.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-accessibility-config.md @mupceet @RayShih @mupceet @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-accessibility-GesturePath.md @mupceet @RayShih @mupceet @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-accessibility-GesturePoint.md @mupceet @RayShih @mupceet @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-accessibility.md @mupceet @RayShih @mupceet @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-app-ability-appRecovery.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-appControl.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-configuration.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-configurationConstant.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-application-quickFixManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen +zh-cn/application-dev/reference/apis/js-apis-avsession.md @liuyuehua1 @zengyawen @saga2020 @currydavids +zh-cn/application-dev/reference/apis/js-apis-batteryStatistics.md @aqxyjay @zengyawen @aqxyjay @alien0208 +zh-cn/application-dev/reference/apis/js-apis-Bundle-BundleStatusCallback.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-abilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-applicationInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-bundleInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-dispatchInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-elementName.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-extensionAbilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-hapModuleInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-launcherAbilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-metadata.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-packInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-permissionDef.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-remoteAbilityInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager-shortcutInfo.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleManager.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-bundleMonitor.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-colorSpaceManager.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee +zh-cn/application-dev/reference/apis/js-apis-commonEventManager.md @jayleehw @RayShih @li-weifeng2 @currydavids +zh-cn/application-dev/reference/apis/js-apis-configPolicy.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-cooperate.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md @gaoyong @zengyawen @niejiteng @jumozhanjiang +zh-cn/application-dev/reference/apis/js-apis-curve.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-defaultAppManager.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-distributedKVStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 +zh-cn/application-dev/reference/apis/js-apis-enterprise-adminManager.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-enterprise-dateTimeManager.md @Buda-Liu @ningningW @budda-wang @yangqing3 +zh-cn/application-dev/reference/apis/js-apis-fileAccess.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-fileExtensionInfo.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-freeInstall.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-geoLocationManager.md @cheng_guohong @RayShih @cheng_guohong @xiangkejin123 +zh-cn/application-dev/reference/apis/js-apis-hiviewdfx-hiappevent.md @stone2050 @zengyawen @stesen @elsen-liu +zh-cn/application-dev/reference/apis/js-apis-inputmethod-subtype.md @feng-aiwen @ge-yafang @SuperShrimp @murphy1984 +zh-cn/application-dev/reference/apis/js-apis-installer.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-launcherBundleManager.md @shuaytao @RayShih @wangzhen107 @inter515 +zh-cn/application-dev/reference/apis/js-apis-matrix4.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy +zh-cn/application-dev/reference/apis/js-apis-net-ethernet.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-net-sharing.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 +zh-cn/application-dev/reference/apis/js-apis-nfctech.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-promptAction.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-reminderAgentManager.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-resourceschedule-backgroundTaskManager.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-resourceschedule-deviceUsageStatistics.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-resourceschedule-workScheduler.md @wangwenli_wolf @ningningW @tangtiantian2021 @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-stationary.md @mayunteng_1 @ningningW @cococoler @alien0208 +zh-cn/application-dev/reference/apis/js-apis-system-capability.md taiyipei taiyipei BlackStone +zh-cn/application-dev/reference/apis/js-apis-system-parameterV9.md @mupceet @zengyawen @handyohos @nan-xiansen +zh-cn/application-dev/reference/apis/js-apis-tagSession.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-usb-deprecated.md @cheng_guohong @RayShih @cheng_guohong @quanli125 +zh-cn/application-dev/reference/apis/js-apis-userFileManager.md @panqinxu @zengyawen @bubble_mao @jinhaihw +zh-cn/application-dev/reference/apis/js-apis-useriam-faceauth.md @gaoyong @zengyawen @niejiteng @jumozhanjiang + +zh-cn/application-dev/reference/errorcodes/errorcode-ability.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-access-token.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-accessibility.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-account.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-animator.md @HelloCrease +zh-cn/application-dev/reference/errorcodes/errorcode-app-account.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-audio.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-avsession.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-backgroundTaskMgr.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-batteryStatistics.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-brightness.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-buffer.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-bundle.md @RayShih zh-cn/application-dev/reference/errorcodes/errorcode-colorspace-manager.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-CommonEventService.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-containers.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-data-rdb.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-datashare.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-device-manager.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-DeviceUsageStatistics.md @ningningW zh-cn/application-dev/reference/errorcodes/errorcode-display.md @ge-yafang -zh-cn/application-dev/reference/errorcodes/errorcode-distributed-data_object.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-distributed-dataObject.md @ge-yafang zh-cn/application-dev/reference/errorcodes/errorcode-distributedKVStore.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-DistributedNotificationService.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-DistributedSchedule.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-enterpriseDeviceManager.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-faultlogger.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-filemanagement.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-geoLocationManager.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-hiappevent.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-hisysevent.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-hiviewdfx-hidebug.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-huks.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-i18n.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-inputmethod-framework.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-multimodalinput.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-nfc.md @RayShih zh-cn/application-dev/reference/errorcodes/errorcode-pasteboard.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-power.md @zengyawen zh-cn/application-dev/reference/errorcodes/errorcode-preferences.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-promptAction.md @HelloCrease +zh-cn/application-dev/reference/errorcodes/errorcode-reminderAgentManager.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-request.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-resource-manager.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-router.md @HelloCrease +zh-cn/application-dev/reference/errorcodes/errorcode-rpc.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-runninglock.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-sensor.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-system-parameterV9.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-thermal.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-uitest.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-universal.md @RayShih +zh-cn/application-dev/reference/errorcodes/errorcode-update.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-usb.md @ge-yafang +zh-cn/application-dev/reference/errorcodes/errorcode-useriam.md @zengyawen +zh-cn/application-dev/reference/errorcodes/errorcode-vibrator.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-webview.md @HelloCrease zh-cn/application-dev/reference/errorcodes/errorcode-window.md @ge-yafang -zh-cn/application-dev/reference/apis/js-apis-application-quickFixManager.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-missionManager.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-particleAbility.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-permissionrequestresult.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-processrunninginformation.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-service-extension-ability.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-service-extension-context.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen -zh-cn/application-dev/reference/apis/js-apis-wantAgent.md @RayShih @littlejerry1 @gwang2008 @ccllee @chengxingzhen - +zh-cn/application-dev/reference/errorcodes/errorcode-workScheduler.md @ningningW +zh-cn/application-dev/reference/errorcodes/errorcode-zlib.md @RayShih diff --git a/README.md b/README.md index 0b1fe4ea284ed5df055c0031d96d3cfb759948a3..602a868e0c5966d52b77eff891a6f32232c7d579 100644 --- a/README.md +++ b/README.md @@ -18,15 +18,15 @@ This repository stores device and application development documents provided by - master: the latest version. - - OpenHarmony 3.2 Beta1. [Learn more](en/release-notes/OpenHarmony-v3.2-beta1.md) + - OpenHarmony 3.2 Beta3. [Learn more](en/release-notes/OpenHarmony-v3.2-beta3.md) - OpenHarmony 3.1 Release. [Learn more](en/release-notes/OpenHarmony-v3.1-release.md) - This version is upgraded to OpenHarmony 3.1.1 LTS. [Learn more](en/release-notes/OpenHarmony-v3.1.1-release.md) + This version is upgraded to OpenHarmony 3.1.3 Release. [Learn more](en/release-notes/OpenHarmony-v3.1.3-release.md) - OpenHarmony 3.0 LTS. [Learn more](en/release-notes/OpenHarmony-v3.0-LTS.md) - This version is upgraded to OpenHarmony 3.0.5 LTS. [Learn more](en/release-notes/OpenHarmony-v3.0.5-LTS.md) + This version is upgraded to OpenHarmony 3.0.6 LTS. [Learn more](en/release-notes/OpenHarmony-v3.0.6-LTS.md) - OpenHarmony 2.2 Beta2. [Learn more](en/release-notes/OpenHarmony-v2.2-beta2.md) @@ -34,14 +34,14 @@ This repository stores device and application development documents provided by ### Historical Stable Versions -OpenHarmony_v1.x_release: OpenHarmony v1.1.4 LTS. [Learn more](en/release-notes/OpenHarmony-v1-1-4-LTS.md) +OpenHarmony_v1.x_release: OpenHarmony v1.1.5 LTS. [Learn more](en/release-notes/OpenHarmony-v1.1.5-LTS.md) [More versions](en/release-notes/) ## Third-Party Open-Source Software and License Notice -Third-party license: [Third-Party Open-Source Software and License Notice](en/contribute/third-party-open-source-software-and-license-notice.md) +Third-party license: [Third-Party Open-Source Software and License Notice](en/contribute/open-source-software-and-license-notice.md) ## Contribution diff --git a/en/OpenHarmony-Overview.md b/en/OpenHarmony-Overview.md index 75dc8b66607121be43c3bcfa13398ecee5b76401..5fbc55f9a12d9c774f7a7295d68cb7b2659852cd 100644 --- a/en/OpenHarmony-Overview.md +++ b/en/OpenHarmony-Overview.md @@ -146,7 +146,7 @@ The following table describes the subsystems of OpenHarmony. For details about t ## Supported Development Boards -Currently, the OpenHarmony community supports 17 types of development boards, which are listed in [Development Boards Supported](device-dev/dev-board-on-the-master.md). The following table describes three of them, which are the first three integrated into the OpenHarmony master. You can visit http://ci.openharmony.cn/dailys/dailybuilds to obtain daily builds. +Currently, the OpenHarmony community supports 22 types of development boards, which are listed in [Development Boards Supported](device-dev/dev-board-on-the-master.md). The following table describes three of them, which are the first three integrated into the OpenHarmony master. You can visit http://ci.openharmony.cn/dailys/dailybuilds to obtain daily builds. | System Type| Board Model| Chip Model|
Function Description and Use Case
| Application Scenario| Code Repository | | -------- | -------- | -------- | -------- | -------- | -------- | @@ -156,11 +156,9 @@ Currently, the OpenHarmony community supports 17 types of development boards, wh ## Getting Started -- [Getting Started for Device Development](device-dev/quick-start/quickstart-ide-lite-overview.md) +- [Getting Started for Device Development](device-dev/quick-start/quickstart-overview.md) - [Getting Started for Application Development](application-dev/quick-start/start-overview.md) - - ## Code Repository Addresses OpenHarmony project: [https://gitee.com/openharmony](https://gitee.com/openharmony) @@ -173,6 +171,8 @@ OpenHarmony archived projects: [https://gitee.com/openharmony-retired](https://g ## OpenHarmony Documentation +[Official website](https://www.openharmony.cn/) + [Chinese version](https://gitee.com/openharmony/docs/tree/master/zh-cn) [English version](https://gitee.com/openharmony/docs/tree/master/en) @@ -197,7 +197,7 @@ For details about how to contribute, see [How to contribute](contribute/how-to-c OpenHarmony complies with Apache License Version 2.0. For details, see the LICENSE in each repository. -OpenHarmony uses third-party open-source software and licenses. For details, see [Third-Party Open-Source Software](https://gitee.com/openharmony/docs/blob/master/en/contribute/third-party-open-source-software-and-license-notice.md). +OpenHarmony uses third-party open-source software and licenses. For details, see [Open Source Software and License Notice](https://gitee.com/openharmony/docs/blob/master/en/contribute/open-source-software-and-license-notice.md). ## Contact Info diff --git a/en/application-dev/ability/ability-brief.md b/en/application-dev/ability/ability-brief.md index f0eb1ad833dfd7e21d275d48d40715221c542a50..867e2c750a7d98b7964b037dcb809954fb5b40fb 100644 --- a/en/application-dev/ability/ability-brief.md +++ b/en/application-dev/ability/ability-brief.md @@ -1,21 +1,25 @@ # Ability Framework Overview -An ability is the abstraction of a functionality that an application can provide. It is the minimum unit for the system to schedule applications. An application can contain one or more `Ability` instances. +Ability is the basic abstraction of applications in OpenHarmony. + +Each ability is an application component that provides an independent service and is the minimum unit for the system to schedule an application. An application can contain one or more **Ability** instances. The ability framework model has two forms: -- FA model, which applies to application development using API version 8 and earlier versions. In the FA model, there is Feature Ability (FA) and Particle Ability (PA). The FA supports Page abilities, and the PA supports Service, Data, and Form abilities. -- Stage model, which is introduced since API version 9. In the stage model, there is `PageAbility` and `ExtensionAbility`. `ExtensionAbility` is further extended to `ServiceExtensionAbility`, `FormExtensionAbility`, `DataShareExtensionAbility`, and more. +- FA model, which is available for application development using API version 8 and earlier versions. In the FA model, there are PageAbility, ServiceAbility, DataAbility, and FormAbility. +- Stage model, which is introduced since API version 9. In the stage model, there are two classes: UIAbility and ExtensionAbility. ExtensionAbility is further extended to ServiceExtensionAbility, FormExtensionAbility, DataShareExtensionAbility, and more. + +Starting from API version 9, the stage model is recommended. The stage model is designed to make it easier to develop complex applications in the distributed environment. The table below lists the design differences between the two models. | Item | FA Model | Stage Model | | -------------- | ------------------------------------------------------------ | -------------------------------------------------------- | -| Development mode | Web-like APIs are provided. The UI development is the same as that of the stage model. | Object-oriented development mode is provided. The UI development is the same as that of the FA model. | -| Engine instance | Each ability in a process exclusively uses a JS VM engine instance. | Multiple abilities in a process share one JS VM engine instance. | -| Intra-process object sharing| Not supported. | Supported. | -| Bundle description file | The `config.json` file is used to describe the HAP and component information. Each component must use a fixed file name.| The `module.json5` file is used to describe the HAP and component information. The entry file name can be specified.| -| Component | Four types of components are provided: Page ability (used for UI page display), Service ability (used to provide services), Data ability (used for data sharing), and Form ability (used to provide widgets).| Two types of components are provided: Ability (used for UI page display) and Extension (scenario-based service extension). | +| Application component development mode | Web-like development | Object-oriented development | +| Engine instance | Each **Ability** instance exclusively occupies a VM instance. | Multiple **Ability** instances share a VM instance. | +| Intra-process object sharing| Not supported | Supported | +| Bundle description file | The **config.json** file is used to describe the HAP and component information. Each component must use a fixed file name.| The **module.json5** file is used to describe the HAP and component information. The entry file name can be specified.| +| Component | Four types of components are provided: PageAbility (used for UI page display), ServiceAbility (used to provide services), DataAbility (used for data sharing), and FormAbility (used to provide widgets).| Two types of components are provided: UIAbility (used for UI page display) and ExtensionAbility (scenario-based service extension). | In addition, the following differences exist in the development process: diff --git a/en/application-dev/ability/context-userguide.md b/en/application-dev/ability/context-userguide.md index d5cd52e64ed5064ded90efea7d60898e1c2ee96c..17fd6b5eb780f656ada33e94a6d1584ebbc55e5c 100644 --- a/en/application-dev/ability/context-userguide.md +++ b/en/application-dev/ability/context-userguide.md @@ -96,13 +96,13 @@ Obtain the context by calling **context.getApplicationContext()** in **Ability** **Example** ```javascript -import AbilityStage from "@ohos.application.AbilityStage"; +import Ability from "@ohos.application.Ability"; var lifecycleid; -export default class MyAbilityStage extends AbilityStage { +export default class MainAbility extends Ability { onCreate() { - console.log("MyAbilityStage onCreate") + console.log("MainAbility onCreate") let AbilityLifecycleCallback = { onAbilityCreate(ability){ console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability)); @@ -141,11 +141,11 @@ export default class MyAbilityStage extends AbilityStage { // 2. Use applicationContext to register and listen for the ability lifecycle in the application. lifecycleid = applicationContext.registerAbilityLifecycleCallback(AbilityLifecycleCallback); console.log("registerAbilityLifecycleCallback number: " + JSON.stringify(lifecycleid)); - } + }, onDestroy() { let applicationContext = this.context.getApplicationContext(); applicationContext.unregisterAbilityLifecycleCallback(lifecycleid, (error, data) => { - console.log("unregisterAbilityLifecycleCallback success, err: " + JSON.stringify(error)); + console.log("unregisterAbilityLifecycleCallback success, err: " + JSON.stringify(error)); }); } } @@ -211,7 +211,13 @@ export default class MainAbility extends Ability { let context = this.context; console.log("[Demo] MainAbility bundleName " + context.abilityInfo.bundleName) - windowStage.setUIContent(this.context, "pages/index", null) + windowStage.loadContent("pages/index", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }); } onWindowStageDestroy() { @@ -237,7 +243,7 @@ For details, see [FormExtensionContext](../reference/apis/js-apis-formextensionc ### Obtaining the Context on an ArkTS Page -In the stage model, in the `onWindowStageCreate` lifecycle of an ability, you can call `SetUIContent` of `WindowStage` to load an ArkTS page. In some scenarios, you need to obtain the context on the page to call related APIs. +In the stage model, in the onWindowStageCreate lifecycle of an ability, you can call **SetUIContent** of **WindowStage** to load an ArkTS page. In some scenarios, you need to obtain the context on the page to call related APIs. **How to Obtain** @@ -245,7 +251,7 @@ Use the API described in the table below to obtain the context associated with a | API | Description | | :------------------------------------ | :--------------------------- | -| getContext(component: Object): Object | Obtains the `Context` object associated with a component on the page.| +| getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.| **Example** diff --git a/en/application-dev/ability/fa-brief.md b/en/application-dev/ability/fa-brief.md index 598ff0f5a79488925cc63d5b29afb0eaa86877aa..3788fe994f9f984449c28bdb6f15ff96adb29c21 100644 --- a/en/application-dev/ability/fa-brief.md +++ b/en/application-dev/ability/fa-brief.md @@ -1,30 +1,36 @@ # FA Model Overview ## Overall Architecture -The development of an OpenHarmony application is essentially the development of one or more abilities. By scheduling abilities and managing their lifecycle, OpenHarmony implements application scheduling. -The Feature Ability (FA) model applies to application development using API version 8 and earlier versions. In this model, there are Page, Service, Data, and Form abilities. -- The Page ability implements the ArkUI and provides the capability of interacting with users. -- The Service ability does not have a UI. It runs in the background and provides custom services for other abilities to invoke. -- The Data ability does not have a UI. It runs in the background and enables other abilities to insert, delete, and query data. -- The Form ability provides a widget, which is a UI display mode. +Ability is the entry for application development in OpenHarmony. -## Lifecycle +The core of ability development is the processing on ability lifecycle callbacks. -Among all abilities, the Page ability has the most complex lifecycle, because it has a UI and acts as a touchpoint for interacting with users. +The Feature Ability (FA) model can be used only for application development using API version 8 and earlier versions. In this model, there are PageAbility, ServiceAbility, DataAbility, and FormAbility. +- PageAbility implements the ArkUI and provides the capability for interacting with users. +- ServiceAbility does not have a UI. It runs in the background and provides custom services for other abilities to invoke. +- DataAbility does not have a UI. It runs in the background and enables other abilities to insert, delete, and query data. +- FormAbility is used to implement widgets, a new UI display form available on OpenHarmony devices. -**The following figure shows the lifecycle of the Page ability.** +> Note: Starting from API version 9, the stage model is recommended for application development. -![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png) +## Lifecycle -The other abilities do not involve the foreground/background switchover and the **onShow** callback. -You can override the lifecycle callbacks in **app.js/app.ets** to process application logic. +Among all abilities, PageAbility has the most complex lifecycle, because it has a UI and acts as a touchpoint for interacting with users. +**The following figure shows the lifecycle of PageAbility.** -Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks. +![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png) +The other abilities do not involve foreground and background switch or the **onShow** and **onHide** callbacks. +You can override the lifecycle callbacks in **app.js** or **app.ets** to process application logic. + +The **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the callbacks covering the entire lifecycle. ## Process and Thread Model -An application exclusively uses an independent process, and an ability exclusively uses an independent thread. When an ability is started for the first time, an application process as well as a thread for this ability is created. After the application is started, other abilities in the application are started, and a thread is created for every of these started abilities. Each ability is bound to an independent JSRuntime instance. In this way, abilities are isolated from each other. + +Each application runs in a process. In the FA model, each ability runs in an independent VM. + +When an ability is started, an application process as well as a thread for this ability is created. For an application that has multiple abilities, each ability runs in an independent thread. In the FA model, each ability is bound to an independent VM instance. In this way, abilities are isolated from each other. ![fa-threading-model](figures/fa-threading-model.png) diff --git a/en/application-dev/ability/fa-dataability.md b/en/application-dev/ability/fa-dataability.md index 36eda5d9210681106a9476bdc87de28f4d06406c..e3fd895c2a3530aa0f8aa85919657a62f3f72c06 100644 --- a/en/application-dev/ability/fa-dataability.md +++ b/en/application-dev/ability/fa-dataability.md @@ -32,19 +32,19 @@ Example URIs: **Table 1** Data ability lifecycle APIs |API|Description| |:------|:------| -|onInitialized?(info: AbilityInfo): void|Called during ability initialization to initialize the relational database (RDB).| -|update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Updates data in the database.| -|query?(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Queries data in the database.| -|delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Deletes one or more data records from the database.| -|normalizeUri?(uri: string, callback: AsyncCallback\): void|Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.| -|batchInsert?(uri: string, valueBuckets: Array\, callback: AsyncCallback\): void|Inserts multiple data records into the database.| -|denormalizeUri?(uri: string, callback: AsyncCallback\): void|Converts a normalized URI generated by **normalizeUri** into a denormalized URI.| -|insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback\): void|Inserts a data record into the database.| -|openFile?(uri: string, mode: string, callback: AsyncCallback\): void|Opens a file.| -|getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback\>): void|Obtains the MIME type of a file.| -|getType?(uri: string, callback: AsyncCallback\): void|Obtains the MIME type matching the data specified by the URI.| -|executeBatch?(ops: Array\, callback: AsyncCallback\>): void|Operates data in the database in batches.| -|call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback\): void|Calls a custom API.| +|onInitialized(info: AbilityInfo): void|Called during ability initialization to initialize the relational database (RDB).| +|update(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Updates data in the database.| +|query(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Queries data in the database.| +|delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Deletes one or more data records from the database.| +|normalizeUri(uri: string, callback: AsyncCallback\): void|Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.| +|batchInsert(uri: string, valueBuckets: Array\, callback: AsyncCallback\): void|Inserts multiple data records into the database.| +|denormalizeUri(uri: string, callback: AsyncCallback\): void|Converts a normalized URI generated by **normalizeUri** into a denormalized URI.| +|insert(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback\): void|Inserts a data record into the database.| +|openFile(uri: string, mode: string, callback: AsyncCallback\): void|Opens a file.| +|getFileTypes(uri: string, mimeTypeFilter: string, callback: AsyncCallback\>): void|Obtains the MIME type of a file.| +|getType(uri: string, callback: AsyncCallback\): void|Obtains the MIME type matching the data specified by the URI.| +|executeBatch(ops: Array\, callback: AsyncCallback\>): void|Operates data in the database in batches.| +|call(method: string, arg: string, extras: PacMap, callback: AsyncCallback\): void|Calls a custom API.| ## How to Develop @@ -55,6 +55,7 @@ Example URIs: The following code snippet shows how to create a Data ability: ```javascript + import featureAbility from '@ohos.ability.featureAbility' import dataAbility from '@ohos.data.dataAbility' import dataRdb from '@ohos.data.rdb' @@ -66,7 +67,8 @@ Example URIs: export default { onInitialized(abilityInfo) { console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName) - dataRdb.getRdbStore(STORE_CONFIG, 1, (err, store) => { + let context = featureAbility.getContext() + dataRdb.getRdbStore(context, STORE_CONFIG, 1, (err, store) => { console.info('DataAbility getRdbStore callback') store.executeSql(SQL_CREATE_TABLE, []) rdbStore = store diff --git a/en/application-dev/ability/fa-formability.md b/en/application-dev/ability/fa-formability.md index c1cadebe652dbd9f195e96ed1dec221df0eff849..377d5e4b8faeda387f4eda5a6506d103c3d76395 100644 --- a/en/application-dev/ability/fa-formability.md +++ b/en/application-dev/ability/fa-formability.md @@ -1,49 +1,49 @@ # FA Widget Development ## Widget Overview -A widget is a set of UI components used to display important information or operations for an application. It provides users with direct access to a desired application service, without requiring them to open the application. +A widget is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first. -A widget displays brief information about an application on the UI of another application (host application, currently system applications only) and provides basic interactive functions such as opening a UI page or sending a message. +A widget usually appears as a part of the UI of another application (which currently can only be a system application) and provides basic interactive features such as opening a UI page or sending a message. -Basic concepts: -- Widget provider: an atomic service that controls what and how content is displayed in a widget and interacts with users. -- Widget host: an application that displays the widget content and controls the position where the widget is displayed in the host application. -- Widget Manager: a resident agent that manages widgets added to the system and provides functions such as periodic widget update. +Before you get started, it would be helpful if you have a basic understanding of the following concepts: +- Widget provider: an atomic service that provides the widget content to display and controls how widget components are laid out and how they interact with users. +- Widget host: an application that displays the widget content and controls the widget location. +- Widget Manager: a resident agent that provides widget management features such as periodic widget updates. > **NOTE** > -> The widget host and provider do not keep running all the time. The Widget Manager starts the widget provider to obtain widget information when a widget is added, deleted, or updated. +> The widget host and provider do not need to be running all the time. The Widget Manager will start the widget provider to obtain widget information when a widget is added, deleted, or updated. -You only need to develop widget content as the widget provider. The system automatically handles the work done by the widget host and Widget Manager. +You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager. -The widget provider controls the widget content to display, component layout, and click events bound to components. +The widget provider controls the widget content to display, the layout of components used in the widget, and click events bound to the components. ## Development Overview -In FA widget development, you need to carry out the following operations as a widget provider based on the [Feature Ability (FA) model](fa-brief.md). +Carry out the following operations to develop the widget provider based on the [FA model](fa-brief.md): -- Develop the lifecycle callbacks in **LifecycleForm**. -- Create a **FormBindingData** instance. -- Update a widget through **FormProvider**. -- Develop the widget UI pages. +1. Implement lifecycle callbacks by using the **LifecycleForm** APIs. +2. Create a **FormBindingData** instance. +3. Update a widget by using the **FormProvider** APIs. +4. Develop the widget UI pages. ## Available APIs -The table below describes the lifecycle callbacks provided in **LifecycleForm**. +The table below describes the **LifecycleForm** APIs, which represent the lifecycle callbacks of a widget (known as a **Form** instance). **Table 1** LifecycleForm APIs | API | Description | | :----------------------------------------------------------- | :------------------------------------------- | -| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a **Form** instance (widget) has been created. | +| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created. | | onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.| | onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. | | onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. | | onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. | -| onDestroy(formId: string): void | Called to notify the widget provider that a **Form** instance (widget) has been destroyed. | -| onAcquireFormState?(want: Want): formInfo.FormState | Called when the widget provider receives the status query result of a widget. | +| onDestroy(formId: string): void | Called to notify the widget provider that a widget has been destroyed. | +| onAcquireFormState?(want: Want): formInfo.FormState | Called to instruct the widget provider to receive the status query result of a widget. | -For details about the **FormProvider** APIs, see [FormProvider](../reference/apis/js-apis-formprovider.md). +The table below describes the **FormProvider** APIs. For details, see [FormProvider](../reference/apis/js-apis-formprovider.md). **Table 2** FormProvider APIs @@ -56,9 +56,9 @@ For details about the **FormProvider** APIs, see [FormProvider](../reference/api ## How to Develop -### Creating LifecycleForm +### Implementing Lifecycle Callbacks -To create a widget in the FA model, you need to implement the lifecycles of **LifecycleForm**. The sample code is as follows: +To create an FA widget, you need to implement lifecycle callbacks using the **LifecycleForm** APIs. The sample code is as follows: 1. Import the required modules. @@ -68,7 +68,7 @@ To create a widget in the FA model, you need to implement the lifecycles of **Li import formProvider from '@ohos.application.formProvider' ``` -2. Implement the lifecycle callbacks of **LifecycleForm**. +2. Implement lifecycle callbacks for the widget. ```javascript export default { @@ -87,7 +87,7 @@ To create a widget in the FA model, you need to implement the lifecycles of **Li console.log('FormAbility onCastToNormal'); }, onUpdate(formId) { - // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update. + // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. console.log('FormAbility onUpdate'); let obj = { "title": "titleOnUpdate", @@ -119,19 +119,19 @@ To create a widget in the FA model, you need to implement the lifecycles of **Li ### Configuring the Widget Configuration File -Configure the **config.json** file for the widget. +The widget configuration file is named **config.json**. Find the **config.json** file for the widget and edit the file depending on your need. -- The **js** module in the **config.json** file provides the JavaScript resources of the widget. The internal structure is described as follows: +- The **js** module in the **config.json** file provides JavaScript resources of the widget. The internal structure is described as follows: | Field| Description | Data Type| Default | | -------- | ------------------------------------------------------------ | -------- | ------------------------ | | name | Name of a JavaScript component. The default value is **default**. | String | No | | pages | Route information about all pages in the JavaScript component, including the page path and page name. The value is an array, in which each element represents a page. The first element in the array represents the home page of the JavaScript FA.| Array | No | | window | Window-related configurations. | Object | Yes | - | type | Type of the JavaScript component. Available values are as follows:
**normal**: indicates that the JavaScript component is an application instance.
**form**: indicates that the JavaScript component is a widget instance.| String | Yes (initial value: **normal**)| + | type | Type of the JavaScript component.
**normal**: indicates an application instance.
**form**: indicates a widget instance.| String | Yes (initial value: **normal**)| | mode | Development mode of the JavaScript component. | Object | Yes (initial value: left empty) | - A configuration example is as follows: + Example configuration: ```json "js": [{ @@ -145,27 +145,27 @@ Configure the **config.json** file for the widget. }] ``` -- The **abilities** module in the **config.json** file corresponds to the **LifecycleForm** of the widget. The internal structure is described as follows: +- The **abilities** module in the **config.json** file corresponds to **LifecycleForm** of the widget. The internal structure is described as follows: | Field | Description | Data Type | Default | | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ | | name | Class name of the widget. The value is a string with a maximum of 127 bytes. | String | No | | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) | | isDefault | Whether the widget is a default one. Each ability has only one default widget.
**true**: The widget is the default one.
**false**: The widget is not the default one.| Boolean | No | - | type | Type of the widget. Available values are as follows:
**JS**: indicates a JavaScript-programmed widget. | String | No | - | colorMode | Color mode of the widget. Available values are as follows:
**auto**: The widget adopts the auto-adaptive color mode.
**dark**: The widget adopts the dark color mode.
**light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)| - | supportDimensions | Grid styles supported by the widget. Available values are as follows:
**1 * 2**: indicates a grid with one row and two columns.
**2 * 2**: indicates a grid with two rows and two columns.
**2 * 4**: indicates a grid with two rows and four columns.
**4 * 4**: indicates a grid with four rows and four columns.| String array| No | + | type | Type of the widget.
**JS**: indicates a JavaScript-programmed widget. | String | No | + | colorMode | Color mode of the widget.
**auto**: The widget adopts the auto-adaptive color mode.
**dark**: The widget adopts the dark color mode.
**light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)| + | supportDimensions | Grid styles supported by the widget.
**1 * 2**: indicates a grid with one row and two columns.
**2 * 2**: indicates a grid with two rows and two columns.
**2 * 4**: indicates a grid with two rows and four columns.
**4 * 4**: indicates a grid with four rows and four columns.| String array| No | | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No | - | updateEnabled | Whether the widget can be updated periodically. Available values are as follows:
**true**: The widget can be updated periodically, depending on the update way you select, either at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** is preferentially recommended.
**false**: The widget cannot be updated periodically.| Boolean | No | - | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.
This parameter has a lower priority than **updateDuration**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) | - | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.
If the value is **0**, this field does not take effect.
If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes.
This parameter has a higher priority than **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) | + | updateEnabled | Whether the widget can be updated periodically.
**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.
**false**: The widget cannot be updated periodically.| Boolean | No | + | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.
**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) | + | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.
If the value is **0**, this field does not take effect.
If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes.
**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) | | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) | | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) | | jsComponentName | Component name of the widget. The value is a string with a maximum of 127 bytes. | String | No | | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) | | customizeData | Custom information about the widget. | Object array | Yes (initial value: left empty) | - A configuration example is as follows: + Example configuration: ```json "abilities": [{ @@ -197,7 +197,7 @@ Configure the **config.json** file for the widget. ### Persistently Storing Widget Data -Mostly, the widget provider is started only when it needs to obtain information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget. +A widget provider is usually started when it is needed to provide information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget. ```javascript onCreate(want) { @@ -219,35 +219,35 @@ Mostly, the widget provider is started only when it needs to obtain information } ``` -You should override **onDestroy** to delete widget data. +You should override **onDestroy** to implement widget data deletion. ```javascript onDestroy(formId) { console.log('FormAbility onDestroy'); - // You need to implement the code for deleting the persistent widget instance. + // You need to implement the code for deleting the persistent widget data. // The deleteFormInfo API is not implemented here. deleteFormInfo(formId); } ``` -For details about the persistence method, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). +For details about how to implement persistence data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). -Note that the **Want** passed by the widget host to the widget provider contains a flag that indicates whether the requested widget is a temporary one. +The **Want** passed by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary. -- Normal widget: a widget that will be persistently used by the widget host +- Normal widget: a widget persistently used by the widget host -- Temporary widget: a widget that is temporarily used by the widget host +- Temporary widget: a widget temporarily used by the widget host -Data of a temporary widget is not persistently stored. If the widget framework is killed and restarted, data of a temporary widget will be deleted. However, the widget provider is not notified of which widget is deleted, and still keeps the data. Therefore, the widget provider should implement data clearing. In addition, the widget host may convert a temporary widget into a normal one. If the conversion is successful, the widget provider should process the widget ID and store the data persistently. This prevents the widget provider from deleting persistent data when clearing temporary widgets. +Data of a temporary widget will be deleted on the Widget Manager if the widget framework is killed and restarted. The widget provider, however, is not notified of the deletion and still keeps the data. Therefore, the widget provider needs to clear the data of temporary widgets proactively if the data has been kept for a long period of time. If the widget host has converted a temporary widget into a normal one, the widget provider should change the widget data from temporary storage to persistent storage. Otherwise, the widget data may be deleted by mistake. ### Updating Widget Data -When a widget application initiates a data update upon a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The code snippet is as follows: +When an application initiates a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The code snippet is as follows: ```javascript onUpdate(formId) { - // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update. + // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. console.log('FormAbility onUpdate'); let obj = { "title": "titleOnUpdate", @@ -267,9 +267,9 @@ You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programme > **NOTE** > -> Currently, only the JavaScript-based web-like development paradigm can be used to develop the widget UI. +> Only the JavaScript-based web-like development paradigm is supported when developing the widget UI. - - In the HML file: + - HML file: ```html
@@ -284,7 +284,7 @@ You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programme
``` - - In the CSS file: + - CSS file: ```css .container { @@ -325,7 +325,7 @@ You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programme } ``` - - In the JSON file: + - JSON file: ```json { "data": { @@ -352,18 +352,18 @@ Now you've got a widget shown below. You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows: -1. Set **onclick** in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file. +1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file. 2. For the router event, set the following attributes: - - **action**: **"router"**. + - **action**: **router**, which indicates a router event. - **abilityName**: target ability name, for example, **com.example.entry.MainAbility**, which is the default main ability name in DevEco Studio for the FA model. - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the FA model, **featureAbility.getWant()** can be used to obtain **want** and its **parameters** field. 3. For the message event, set the following attributes: - - **action**: **"message"**. + - **action**: **message**, which indicates a message event. - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**. The code snippet is as follows: - - In the HML file: + - HML file: ```html
@@ -378,7 +378,7 @@ The code snippet is as follows:
``` - - In the JSON file: + - JSON file: ```json { "data": { diff --git a/en/application-dev/ability/fa-serviceability.md b/en/application-dev/ability/fa-serviceability.md index 3bafb0bc097f0277f88ff4489c2731afdad6569e..3cd2620cfdde502f879e1321e782f2d872e0a77d 100644 --- a/en/application-dev/ability/fa-serviceability.md +++ b/en/application-dev/ability/fa-serviceability.md @@ -1,64 +1,69 @@ # Service Ability Development ## When to Use -A Service ability is used to run tasks in the background, such as playing music or downloading files. It does not provide a UI for user interaction. Service abilities can be started by other applications or abilities and can remain running in the background even after the user switches to another application. +A Service ability is used to run tasks in the background, such as playing music or downloading files. It does not provide a UI for user interaction. Service abilities can be started by other applications or abilities and can keep running in the background even after the user switches to another application. -## Available APIs +## Lifecycle APIs **Table 1** Service ability lifecycle APIs |API|Description| |:------|:------| -|onStart?(): void|Called to initialize a Service ability being created. This callback is invoked only once in the entire lifecycle of a Service ability. The **Want** object passed to this callback must be null.| -|onCommand?(want: Want, startId: number): void|Called every time a Service ability is created on a client. You can collect calling statistics and perform initialization operations in this callback.| +|onStart?(): void|Called to initialize a Service ability when the Service ability is being created. This callback is invoked only once in the entire lifecycle of a Service ability.| +|onCommand?(want: Want, startId: number): void|Called every time a Service ability is created on the client. You can collect calling statistics and perform initialization operations in this callback.| |onConnect?(want: Want): rpc.RemoteObject|Called when another ability is connected to the Service ability.| |onDisconnect?(want: Want): void|Called when another ability is disconnected from the Service ability.| |onStop?(): void|Called when the Service ability is being destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners.| +The differences between **onCommand()** and **onConnect()** are as follows: + - The **onCommand()** callback is triggered each time the client starts the Service ability by calling **startAbility** or **startAbilityForResult**. + - The **onConnect()** callback is triggered each time the client establishes a new connection with the Service ability by calling **connectAbility**. + ## How to Develop ### Creating and Registering a Service Ability -1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests. +1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests. - ```javascript - export default { - onStart() { - console.log('ServiceAbility onStart'); - }, - onCommand(want, startId) { - console.log('ServiceAbility onCommand'); - }, - onConnect(want) { - console.log('ServiceAbility OnConnect'); - return new FirstServiceAbilityStub('test'); - }, - onDisconnect(want) { - console.log('ServiceAbility OnDisConnect'); - }, - onStop() { - console.log('ServiceAbility onStop'); - }, - } + ```ts + export default { + onStart() { + console.log('ServiceAbility onStart'); + }, + onCommand(want, startId) { + console.log('ServiceAbility onCommand'); + }, + onConnect(want) { + console.log('ServiceAbility OnConnect'); + // Below lists the implementation of ServiceAbilityStub. + return new ServiceAbilityStub('test'); + }, + onDisconnect(want) { + console.log('ServiceAbility OnDisConnect'); + }, + onStop() { + console.log('ServiceAbility onStop'); + } + } ``` 2. Register a Service ability. Declare the Service ability in the **config.json** file by setting its **type** attribute to **service**. - ```javascript + ```json { - "module": { - "abilities": [ - { - "name": ".ServiceAbility", - "type": "service", - "visible": true - ... - } - ] + "module": { + "abilities": [ + { + "name": ".ServiceAbility", + "type": "service", + "visible": true ... - } + } + ] ... + } + ... } ``` @@ -68,333 +73,261 @@ A Service ability is used to run tasks in the background, such as playing music The **Ability** class provides the **startAbility()** API for you to start another Service ability by passing a **Want** object. -To set information about the target Service ability, you can first construct a **Want** object with the **bundleName** and **abilityName** parameters specified. The meanings of the parameters are as follows: +To set information about the target Service ability, you can first construct a **Want** object with the **bundleName** and **abilityName** parameters specified. -- **bundleName** indicates the name of the bundle to which the target ability belongs. -- **abilityName** indicates the target ability name. +- **bundleName** specifies the bundle name of the target application. +- **abilityName** specifies the target ability name. The following code snippet shows how to start a Service ability running on the local device: -```javascript -import featureAbility from '@ohos.ability.featureAbility'; -let promise = featureAbility.startAbility( +```ts +import featureAbility from '@ohos.ability.featureAbility' + +featureAbility.startAbility( { want: { bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility", - }, + abilityName: "com.jstest.service.ServiceAbility" + } } -); +).then((err) => { + console.log("startService success"); +}).catch (err => { + console.log("startService FAILED"); +}); ``` -After the preceding code is executed, the **startAbility()** API is called to start the Service ability. -- If the Service ability is not running, the system calls **onStart()** to initialize the Service ability, and then calls **onCommand()** on the Service ability. +In the preceding code, the **startAbility()** API is used to start the Service ability. +- If the Service ability is not running, the system initializes the Service ability, and calls **onStart()** and **onCommand()** on the Service ability in sequence. - If the Service ability is running, the system directly calls **onCommand()** on the Service ability. -The following code snippet shows how to start a Service ability running on the remote device. For details about **getRemoteDeviceId()**, see [Connecting to a Remote Service Ability](#connecting-to-a-remote-service-ability). +The following code snippet shows how to start a Service ability running on the remote device. For details, see [Connecting to a Remote Service Ability](#connecting-to-a-remote-service-ability). + +```ts +import featureAbility from '@ohos.ability.featureAbility' -```javascript -import featureAbility from '@ohos.ability.featureAbility'; -let promise = featureAbility.startAbility( +featureAbility.startAbility( { want: { - deviceId: getRemoteDeviceId(), // Remote device ID + deviceId: remoteDeviceId, // Remote device ID. bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility", - }, + abilityName: "com.jstest.service.ServiceAbility" + } } -); +).then((err) => { + console.log("startService success"); +}).catch (err => { + console.log("startService FAILED"); +}); ``` ### Stopping a Service Ability -Once created, the Service ability keeps running in the background. The system does not stop or destroy it unless memory resources must be reclaimed. + In normal cases, a Service ability can be stopped by itself or by the system. + - The Service ability can call **particleAbility.terminateSelf()** to stop itself. + - If the application process where the Service ability is located exits, the Service ability is reclaimed along with the process. + - If the Service ability is only accessed through **connectAbility()** (the **onCommand()** callback has never been triggered), the system stops the Service ability when the last connection to the Service ability is disconnected. ### Connecting to a Local Service Ability -If you need to connect a Service ability to a Page ability or to a Service ability in another application, you must first implement the **IAbilityConnection** API for the connection. A Service ability allows other abilities to connect to it through **connectAbility()**. +If a Service ability wants to interact with a Page ability or a Service ability in another application, you must first create a connection. A Service ability allows other abilities to connect to it through **connectAbility()**. You can use either of the following methods to connect to a Service ability: 1. Using the IDL to automatically generate code - Use OpenHarmony Interface Definition Language (IDL) to automatically generate the corresponding client, server, and **IRemoteObject** code. For details, see “Development Using TS" in [OpenHarmony IDL Specifications and User Guide](../IDL/idl-guidelines.md). + Use OpenHarmony Interface Definition Language (IDL) to automatically generate the corresponding client, server, and **IRemoteObject** code. For details, see [Development Using TS](../IDL/idl-guidelines.md#development-using-ts). 2. Writing code in the corresponding file - When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the API. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails. + When using **connectAbility()**, pass the **Want** and **ConnectOptions** objects of the target Service ability, where **ConnectOptions** encapsulates the following three callbacks that need to be implemented. + - **onConnect()**: callback used for processing when the Service ability is connected. + - **onDisconnect()**: callback used for processing when the Service ability is disconnected. + - **onFailed()**: callback used for processing when the connection to the Service ability fails. The following code snippet shows how to implement the callbacks: - ```javascript + ```ts import prompt from '@system.prompt' var option = { onConnect: function onConnectCallback(element, proxy) { - console.log(`onConnectLocalService onConnectDone`) + console.log(`onConnectLocalService onConnectDone`); if (proxy === null) { prompt.showToast({ message: "Connect service failed" - }) - return + }); + return; } - let data = rpc.MessageParcel.create() - let reply = rpc.MessageParcel.create() - let option = new rpc.MessageOption() - data.writeInterfaceToken("connect.test.token") - proxy.sendRequest(0, data, reply, option) + // After obtaining the proxy of the Service ability, the calling ability can communicate with the Service ability. + let data = rpc.MessageParcel.create(); + let reply = rpc.MessageParcel.create(); + let option = new rpc.MessageOption(); + data.writeString("InuptString"); + proxy.sendRequest(0, data, reply, option); prompt.showToast({ message: "Connect service success" - }) + }); }, onDisconnect: function onDisconnectCallback(element) { - console.log(`onConnectLocalService onDisconnectDone element:${element}`) + console.log(`onConnectLocalService onDisconnectDone element:${element}`); prompt.showToast({ message: "Disconnect service success" - }) + }); }, onFailed: function onFailedCallback(code) { - console.log(`onConnectLocalService onFailed errCode:${code}`) + console.log(`onConnectLocalService onFailed errCode:${code}`); prompt.showToast({ message: "Connect local service onFailed" - }) + }); } - } + }; ``` The following code snippet shows how to connect to a local Service ability: - ```javascript - import featureAbility from '@ohos.ability.featureAbility'; - let connId = featureAbility.connectAbility( - { - bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility", - }, - { - onConnect: onConnectCallback, - onDisconnect: onDisconnectCallback, - onFailed: onFailedCallback, - }, - ); + ```ts + import featureAbility from '@ohos.ability.featureAbility' + + let want = { + bundleName: "com.jstest.service", + abilityName: "com.jstest.service.ServiceAbility" + }; + let connectId = featureAbility.connectAbility(want, option); ``` - When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides a default implementation of **IRemoteObject**. You can extend **rpc.RemoteObject** to implement your own class of **IRemoteObject**. + When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides the default implementation of **IRemoteObject**. You can inherit **rpc.RemoteObject** to create a custom implementation class for interaction with the Service ability. For details, see the [RPC API Reference](..\reference\apis\js-apis-rpc.md). - The following code snippet shows how the Service ability instance returns itself to the calling ability: + The following code snippet shows how the Service ability returns itself to the calling ability: - ```javascript - import rpc from "@ohos.rpc"; + ```ts + import rpc from "@ohos.rpc" - class FirstServiceAbilityStub extends rpc.RemoteObject { - constructor(des: any) { - if (typeof des === 'string') { - super(des) - } else { - return + class ServiceAbilityStub extends rpc.RemoteObject { + constructor(des: any) { + if (typeof des === 'string') { + super(des); + } else { + console.log("Error, the input param is not string"); + return; + } + } + + onRemoteRequest(code: number, data: any, reply: any, option: any) { + console.log("onRemoteRequest called"); + // Execute the service logic. + if (code === 1) { + // Sort the input strings. + let string = data.readString(); + console.log(`Input string = ${string}`); + let result = Array.from(string).sort().join(''); + console.log(`Output result = ${result}`); + reply.writeString(result); + } else { + console.log(`Unknown request code`); + } + return true; } } - onRemoteRequest(code: number, data: any, reply: any, option: any) { - console.log(printLog + ` onRemoteRequest called`) - if (code === 1) { - let string = data.readString() - console.log(printLog + ` string=${string}`) - let result = Array.from(string).sort().join('') - console.log(printLog + ` result=${result}`) - reply.writeString(result) - } else { - console.log(printLog + ` unknown request code`) + export default { + onStart() { + console.log('ServiceAbility onStart'); + }, + onCommand(want, startId) { + console.log('ServiceAbility onCommand'); + }, + onConnect(want) { + console.log('ServiceAbility OnConnect'); + return new ServiceAbilityStub('ServiceAbilityRemoteObject'); + }, + onDisconnect(want) { + console.log('ServiceAbility OnDisConnect'); + }, + onStop() { + console.log('ServiceAbility onStop'); } - return true; } ``` ### Connecting to a Remote Service Ability ->**NOTE** -> ->This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. - -If you need to connect a Service ability to a Page ability or another Service ability on a remote device, you must first implement the **IAbilityConnection** interface for the connection. A Service ability allows abilities on another device to connect to it through **connectAbility()**. - -When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the API. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails. +This feature applies only to system applications. The method of creating a **ConnectOptions** object for connecting to a remote Service ability is similar to that for connecting to a local Service ability. The differences are as follows: + - The application must apply for the data synchronization permission from the user. + - **Want** of the target Service ability must contain the remote device ID. -The following code snippet shows how to implement the callbacks: - -```ts -import prompt from '@system.prompt' - -var option = { - onConnect: function onConnectCallback(element, proxy) { - console.log(`onConnectRemoteService onConnectDone`) - if (proxy === null) { - prompt.showToast({ - message: "Connect service failed" - }) - return - } - let data = rpc.MessageParcel.create() - let reply = rpc.MessageParcel.create() - let option = new rpc.MessageOption() - data.writeInterfaceToken("connect.test.token") - proxy.sendRequest(0, data, reply, option) - prompt.showToast({ - message: "Connect service success" - }) - }, - onDisconnect: function onDisconnectCallback(element) { - console.log(`onConnectRemoteService onDisconnectDone element:${element}`) - prompt.showToast({ - message: "Disconnect service success" - }) - }, - onFailed: function onFailedCallback(code) { - console.log(`onConnectRemoteService onFailed errCode:${code}`) - prompt.showToast({ - message: "Connect local service onFailed" - }) - } +> **NOTE** +> +> The **getTrustedDeviceList** API of **DeviceManager** is open only to system applications. Currently, only system applications can connect to a remote Service ability. +> +> For details about the API definition, see [Device Management](..\reference\apis\js-apis-device-manager.md). + +The data synchronization permission is required in the cross-device scenario. Configure the permission in the **config.json** file. + +```json +{ + ... + "module": { + ... + "reqPermissions": [{ + "name": "ohos.permission.DISTRIBUTED_DATASYNC" + }] + } } ``` -The **Want** of the target Service ability must contain the remote **deviceId**, which can be obtained from **DeviceManager**. The sample code is as follows: +The **DISTRIBUTED_DATASYNC** permission is user granted. Therefore, your application, when being started, must display a dialog box to request the permission. The sample code is as follows: ```ts -import deviceManager from '@ohos.distributedHardware.deviceManager'; +import abilityAccessCtrl from "@ohos.abilityAccessCtrl" +import bundle from '@ohos.bundle' -// For details about the implementation of dmClass, see the implementation in Distributed Demo in Samples. -let dmClass; - -function getRemoteDeviceId() { - if (typeof dmClass === 'object' && dmClass != null) { - let list = dmClass.getTrustedDeviceListSync(); - if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { - console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); - return; +async function RequestPermission() { + console.info('RequestPermission begin'); + let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"]; + let bundleFlag = 0; + let tokenID = undefined; + let userID = 100; + let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); + tokenID = appInfo.accessTokenId; + let atManager = abilityAccessCtrl.createAtManager(); + let requestPermissions: Array = []; + for (let i = 0;i < array.length; i++) { + let result = await atManager.verifyAccessToken(tokenID, array[i]); + console.info("verifyAccessToken result:" + JSON.stringify(result)); + if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + requestPermissions.push(array[i]); } - console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); - return list[0].deviceId; - } else { - console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); } -} -``` - -The following code snippet shows how to connect to a remote Service ability: - -```ts -import featureAbility from '@ohos.ability.featureAbility'; -let connId = featureAbility.connectAbility( - { - deviceId: getRemoteDeviceId(), - bundleName: "ohos.samples.etsDemo", - abilityName: "ohos.samples.etsDemo.ServiceAbility", - }, - { - onConnect: onConnectCallback, - onDisconnect: onDisconnectCallback, - onFailed: onFailedCallback, - }, -); -``` -In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows: - -```ts -import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; -import bundle from '@ohos.bundle'; -async function RequestPermission() { - console.info('RequestPermission begin'); - let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"]; - let bundleFlag = 0; - let tokenID = undefined; - let userID = 100; - let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); - tokenID = appInfo.accessTokenId; - let atManager = abilityAccessCtrl.createAtManager(); - let requestPermissions: Array = []; - for (let i = 0;i < array.length; i++) { - let result = await atManager.verifyAccessToken(tokenID, array[i]); - console.info("verifyAccessToken result:" + JSON.stringify(result)); - if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { - } else { - requestPermissions.push(array[i]); + console.info("requestPermissions:" + JSON.stringify(requestPermissions)); + if (requestPermissions.length == 0 || requestPermissions == []) { + return; } - } - console.info("requestPermissions:" + JSON.stringify(requestPermissions)); - if (requestPermissions.length == 0 || requestPermissions == []) { - return; - } - let context = featureAbility.getContext(); - context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{ - console.info("data:" + JSON.stringify(data)); - }); - console.info('RequestPermission end'); + let context = featureAbility.getContext(); + context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{ + console.info("data:" + JSON.stringify(data)); + }); + console.info('RequestPermission end'); } ``` -When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides a default implementation of **IRemoteObject**. You can extend **rpc.RemoteObject** to implement your own class of **IRemoteObject**. +To obtain the device ID, import the **@ohos.distributedHardware.deviceManager** module, which provides **getTrustedDeviceList** to obtain the remote device ID. For details about how to use the API, see [Device Management](..\reference\apis\js-apis-device-manager.md). -The following code snippet shows how the Service ability instance returns itself to the calling ability: +To connect to a remote Service ability, you only need to define **deviceId** in **Want**. The sample code is as follows: ```ts -import rpc from "@ohos.rpc"; - -class FirstServiceAbilityStub extends rpc.RemoteObject { - constructor(des: any) { - if (typeof des === 'string') { - super(des) - } else { - return - } - } - - onRemoteRequest(code: number, data: any, reply: any, option: any) { - console.log(printLog + ` onRemoteRequest called`) - if (code === 1) { - let string = data.readString() - console.log(printLog + ` string=${string}`) - let result = Array.from(string).sort().join('') - console.log(printLog + ` result=${result}`) - reply.writeString(result) - } else { - console.log(printLog + ` unknown request code`) - } - return true; - } -} +import featureAbility from '@ohos.ability.featureAbility' -export default { - onStart() { - console.info('ServiceAbility onStart'); - }, - onStop() { - console.info('ServiceAbility onStop'); - }, - onConnect(want) { - console.log("ServiceAbility onConnect"); - try { - let value = JSON.stringify(want); - console.log("ServiceAbility want:" + value); - } catch(error) { - console.log("ServiceAbility error:" + error); - } - return new FirstServiceAbilityStub("first ts service stub"); - }, - onDisconnect(want) { - console.log("ServiceAbility onDisconnect"); - let value = JSON.stringify(want); - console.log("ServiceAbility want:" + value); - }, - onCommand(want, startId) { - console.info('ServiceAbility onCommand'); - let value = JSON.stringify(want); - console.log("ServiceAbility want:" + value); - console.log("ServiceAbility startId:" + startId); - } +let want = { + deviceId: remoteDeviceId, + bundleName: "com.jstest.service", + abilityName: "com.jstest.service.ServiceAbility" }; +let connectId = featureAbility.connectAbility(want, option); ``` + +The other implementations are the same as those for the connection to a local Service ability. For details, see the sample code provided under [Connecting to a Local Service Ability](#connecting-to-a-local-service-ability). diff --git a/en/application-dev/ability/figures/favsstage.png b/en/application-dev/ability/figures/favsstage.png index 13b1766da57d89f206068dbb03741ba1f0ae96ff..4e5980fc1df4634d4ea1ff23158e79d62637f8ba 100644 Binary files a/en/application-dev/ability/figures/favsstage.png and b/en/application-dev/ability/figures/favsstage.png differ diff --git a/en/application-dev/ability/stage-ability.md b/en/application-dev/ability/stage-ability.md index 3457aa29249a7c569053a09b6374cf03ce0d8868..d09585b25531556cfbee2ab5cbd45c72191aa8a4 100644 --- a/en/application-dev/ability/stage-ability.md +++ b/en/application-dev/ability/stage-ability.md @@ -1,6 +1,6 @@ # Ability Development ## When to Use -Ability development in the [stage model](stage-brief.md) is significantly different from that in the FA model. The stage model requires you to declare the application package structure in the `module.json5` and `app.json5` files during application development. For details about the configuration file, see [Application Package Structure Configuration File](../quick-start/stage-structure.md). To develop an ability based on the stage model, implement the following logic: +Ability development in the [stage model](stage-brief.md) is significantly different from that in the FA model. The stage model requires you to declare the application package structure in the **module.json5** and **app.json5** files during application development. For details about the configuration file, see [Application Package Structure Configuration File](../quick-start/stage-structure.md). To develop an ability based on the stage model, implement the following logic: - Create an ability that supports screen viewing and human-machine interaction. You must implement the following scenarios: ability lifecycle callbacks, obtaining ability configuration, requesting permissions, and notifying environment changes. - Start an ability. You need to implement ability startup on the same device, on a remote device, or with a specified UI page. - Call abilities. For details, see [Call Development](stage-call.md). @@ -8,15 +8,15 @@ Ability development in the [stage model](stage-brief.md) is significantly differ - Continue the ability on another device. For details, see [Ability Continuation Development](stage-ability-continuation.md). ### Launch Type -An ability can be launched in the **standard**, **singleton**, or **specified** mode, as configured by `launchType` in the `module.json5` file. Depending on the launch type, the action performed when the ability is started differs, as described below. +An ability can be launched in the **standard**, **singleton**, or **specified** mode, as configured by **launchType** in the **module.json5** file. Depending on the launch type, the action performed when the ability is started differs, as described below. | Launch Type | Description |Action | | ----------- | ------- |---------------- | -| standard | Standard mode. | A new instance is started each time an ability starts.| -| singleton | Singleton mode. | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.| +| standard | Standard mode | A new instance is started each time an ability starts.| +| singleton | Singleton mode | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.| | specified | Instance-specific| The internal service of an ability determines whether to create multiple instances during running.| -By default, the singleton mode is used. The following is an example of the `module.json5` file: +By default, the singleton mode is used. The following is an example of the **module.json5** file: ```json { "module": { @@ -30,7 +30,7 @@ By default, the singleton mode is used. The following is an example of the `modu ``` ## Creating an Ability ### Available APIs -The table below describes the APIs provided by the `AbilityStage` class, which has the `context` attribute. For details about the APIs, see [AbilityStage](../reference/apis/js-apis-application-abilitystage.md). +The table below describes the APIs provided by the **AbilityStage** class, which has the **context** attribute. For details about the APIs, see [AbilityStage](../reference/apis/js-apis-application-abilitystage.md). **Table 1** AbilityStage APIs |API|Description| @@ -39,7 +39,7 @@ The table below describes the APIs provided by the `AbilityStage` class, which h |onAcceptWant(want: Want): string|Called when a specified ability is started.| |onConfigurationUpdated(config: Configuration): void|Called when the global configuration is updated.| -The table below describes the APIs provided by the `Ability` class. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md). +The table below describes the APIs provided by the **Ability** class. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md). **Table 2** Ability APIs @@ -47,19 +47,19 @@ The table below describes the APIs provided by the `Ability` class. For details |:------|:------| |onCreate(want: Want, param: AbilityConstant.LaunchParam): void|Called when an ability is created.| |onDestroy(): void|Called when the ability is destroyed.| -|onWindowStageCreate(windowStage: window.WindowStage): void|Called when a `WindowStage` is created for the ability. You can use the `window.WindowStage` APIs to implement operations such as page loading.| -|onWindowStageDestroy(): void|Called when the `WindowStage` is destroyed for the ability.| +|onWindowStageCreate(windowStage: window.WindowStage): void|Called when a **WindowStage** is created for the ability. You can use the **window.WindowStage** APIs to implement operations such as page loading.| +|onWindowStageDestroy(): void|Called when the **WindowStage** is destroyed for the ability.| |onForeground(): void|Called when the ability is switched to the foreground.| |onBackground(): void|Called when the ability is switched to the background.| -|onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void|Called when the ability launch type is set to `singleton`.| +|onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void|Called when the ability launch type is set to **singleton**.| |onConfigurationUpdated(config: Configuration): void|Called when the configuration of the environment where the ability is running is updated.| ### Implementing AbilityStage and Ability Lifecycle Callbacks -To create Page abilities for an application in the stage model, you must implement the `AbilityStage` class and ability lifecycle callbacks, and use the `Window` APIs to set the pages. The sample code is as follows: -1. Import the `AbilityStage` module. +To create Page abilities for an application in the stage model, you must implement the **AbilityStage** class and ability lifecycle callbacks, and use the **Window** class to set the pages. The sample code is as follows: +1. Import the **AbilityStage** module. ``` import AbilityStage from "@ohos.application.AbilityStage" ``` -2. Implement the `AbilityStage` class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**. +2. Implement the **AbilityStage** class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**. ```ts export default class MyAbilityStage extends AbilityStage { onCreate() { @@ -67,13 +67,13 @@ To create Page abilities for an application in the stage model, you must impleme } } ``` -3. Import the `Ability` module. +3. Import the **Ability** module. ```js import Ability from '@ohos.application.Ability' ``` -4. Implement the lifecycle callbacks of the `Ability` class. The default relative path generated by the APIs is **entry\src\main\ets\MainAbility\MainAbility.ts**. +4. Implement the lifecycle callbacks of the **Ability** class. The default relative path generated by the APIs is **entry\src\main\ets\MainAbility\MainAbility.ts**. - In the `onWindowStageCreate(windowStage)` API, use `loadContent` to set the application page to be loaded. For details about how to use the `Window` APIs, see [Window Development](../windowmanager/application-window-stage.md). + In the **onWindowStageCreate(windowStage)** API, use **loadContent** to set the application page to be loaded. For details about how to use the **Window** APIs, see [Window Development](../windowmanager/application-window-stage.md). ```ts export default class MainAbility extends Ability { onCreate(want, launchParam) { @@ -108,9 +108,9 @@ To create Page abilities for an application in the stage model, you must impleme } ``` ### Obtaining AbilityStage and Ability Configurations -Both the `AbilityStage` and `Ability` classes have the `context` attribute. An application can obtain the context of an `Ability` instance through `this.context` to obtain the configuration details. +Both the **AbilityStage** and **Ability** classes have the **context** attribute. An application can obtain the context of an **Ability** instance through **this.context** to obtain the configuration details. -The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the `context` attribute in the `AbilityStage` class. The sample code is as follows: +The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **AbilityStage** class. The sample code is as follows: ```ts import AbilityStage from "@ohos.application.AbilityStage" @@ -130,7 +130,7 @@ export default class MyAbilityStage extends AbilityStage { } ``` -The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the `context` attribute in the `Ability` class. The sample code is as follows: +The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **Ability** class. The sample code is as follows: ```ts import Ability from '@ohos.application.Ability' export default class MainAbility extends Ability { @@ -149,9 +149,9 @@ export default class MainAbility extends Ability { } ``` ### Requesting Permissions -If an application needs to obtain user privacy information or use system capabilities, for example, obtaining location information or using the camera to take photos or record videos, it must request the respective permission from consumers. During application development, you need to specify the involved sensitive permissions, declare the required permissions in `module.json5`, and use the `requestPermissionsFromUser` API to request the permission from consumers in the form of a dialog box. The following uses the permission for calendar access as an example. +If an application needs to obtain user privacy information or use system capabilities, for example, obtaining location information or using the camera to take photos or record videos, it must request the respective permission from consumers. During application development, you need to specify the involved sensitive permissions, declare the required permissions in **module.json5**, and use the **requestPermissionsFromUser** API to request the permission from consumers in the form of a dialog box. The following uses the permission for calendar access as an example. -Declare the required permission in the `module.json5` file. +Declare the required permission in the **module.json5** file. ```json "requestPermissions": [ { @@ -170,13 +170,13 @@ context.requestPermissionsFromUser(permissions).then((data) => { }) ``` ### Notifying of Environment Changes -Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single `Ability` instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. For details on the configuration, see [Configuration](../reference/apis/js-apis-configuration.md). +Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single **Ability** instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. For details on the configuration, see [Configuration](../reference/apis/js-apis-configuration.md). -For an application in the stage model, when the configuration changes, its abilities are not restarted, but the `onConfigurationUpdated(config: Configuration)` callback is triggered. If the application needs to perform processing based on the change, you can overwrite `onConfigurationUpdated`. Note that the `Configuration` object in the callback contains all the configurations of the current ability, not only the changed configurations. +For an application in the stage model, when the configuration changes, its abilities are not restarted, but the **onConfigurationUpdated(config: Configuration)** callback is triggered. If the application needs to perform processing based on the change, you can overwrite **onConfigurationUpdated**. Note that the **Configuration** object in the callback contains all the configurations of the current ability, not only the changed configurations. -The following example shows the implementation of the `onConfigurationUpdated` callback in the `AbilityStage` class. The callback is triggered when the system language and color mode are changed. +The following example shows the implementation of the **onConfigurationUpdated** callback in the **AbilityStage** class. The callback is triggered when the system language and color mode are changed. ```ts -import Ability from '@ohos.application.Ability' +import AbilityStage from '@ohos.application.AbilityStage' import ConfigurationConstant from '@ohos.application.ConfigurationConstant' export default class MyAbilityStage extends AbilityStage { @@ -188,7 +188,7 @@ export default class MyAbilityStage extends AbilityStage { } ``` -The following example shows the implementation of the `onConfigurationUpdated` callback in the `Ability` class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change. +The following example shows the implementation of the **onConfigurationUpdated** callback in the **Ability** class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change. ```ts import Ability from '@ohos.application.Ability' import ConfigurationConstant from '@ohos.application.ConfigurationConstant' @@ -209,7 +209,7 @@ export default class MainAbility extends Ability { ``` ## Starting an Ability ### Available APIs -The `Ability` class has the `context` attribute, which belongs to the `AbilityContext` class. The `AbilityContext` class has the `abilityInfo`, `currentHapModuleInfo`, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md). +The **Ability** class has the **context** attribute, which belongs to the **AbilityContext** class. The **AbilityContext** class has the **abilityInfo**, **currentHapModuleInfo**, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md). **Table 3** AbilityContext APIs |API|Description| @@ -223,7 +223,7 @@ The `Ability` class has the `context` attribute, which belongs to the `AbilityCo |startAbilityForResultWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the execution result and account ID.| |startAbilityForResultWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the execution result and account ID.| ### Starting an Ability on the Same Device -An application can obtain the context of an `Ability` instance through `this.context` and then use the `startAbility` API in the `AbilityContext` class to start the ability. The ability can be started by specifying `Want`, `StartOptions`, and `accountId`, and the operation result can be returned using a callback or `Promise` instance. The sample code is as follows: +An application can obtain the context of an **Ability** instance through **this.context** and then use the **startAbility** API in the **AbilityContext** class to start the ability. The ability can be started by specifying **Want**, **StartOptions**, and **accountId**, and the operation result can be returned using a callback or **Promise** instance. The sample code is as follows: ```ts let context = this.context var want = { @@ -239,7 +239,7 @@ context.startAbility(want).then(() => { ``` ### Starting an Ability on a Remote Device ->This feature applies only to system applications, since the `getTrustedDeviceListSync` API of the `DeviceManager` class is open only to system applications. +>This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. In the cross-device scenario, you must specify the ID of the remote device. The sample code is as follows: ```ts let context = this.context @@ -254,7 +254,7 @@ context.startAbility(want).then(() => { console.error("Failed to start remote ability with error: " + JSON.stringify(error)) }) ``` -Obtain the ID of a specified device from `DeviceManager`. The sample code is as follows: +Obtain the ID of a specified device from **DeviceManager**. The sample code is as follows: ```ts import deviceManager from '@ohos.distributedHardware.deviceManager'; function getRemoteDeviceId() { @@ -271,11 +271,11 @@ function getRemoteDeviceId() { } } ``` -Request the permission `ohos.permission.DISTRIBUTED_DATASYNC` from consumers. This permission is used for data synchronization. For details about the sample code for requesting the permission, see [Requesting Permissions](##requesting-permissions). +Request the permission **ohos.permission.DISTRIBUTED_DATASYNC** from consumers. This permission is used for data synchronization. For details about the sample code for requesting the permission, see [Requesting Permissions](#requesting-permissions). ### Starting an Ability with the Specified Page -If the launch type of an ability is set to `singleton` and the ability has been started, the `onNewWant` callback is triggered when the ability is started again. You can pass start options through the `want`. For example, to start an ability with the specified page, use the `uri` or `parameters` parameter in the `want` to pass the page information. Currently, the ability in the stage model cannot directly use the `router` capability. You must pass the start options to the custom component and invoke the `router` method to display the specified page during the custom component lifecycle management. The sample code is as follows: +If the launch type of an ability is set to **singleton** and the ability has been started, the **onNewWant** callback is triggered when the ability is started again. You can pass start options through the **want**. For example, to start an ability with the specified page, use the **uri** or **parameters** parameter in the **want** to pass the page information. Currently, the ability in the stage model cannot directly use the **router** capability. You must pass the start options to the custom component and invoke the **router** method to display the specified page during the custom component lifecycle management. The sample code is as follows: -When using `startAbility` to start an ability again, use the `uri` parameter in the `want` to pass the page information. +When using **startAbility** to start an ability again, use the **uri** parameter in the **want** to pass the page information. ```ts async function reStartAbility() { try { @@ -291,7 +291,7 @@ async function reStartAbility() { } ``` -Obtain the `want` parameter that contains the page information from the `onNewWant` callback of the ability. +Obtain the **want** parameter that contains the page information from the **onNewWant** callback of the ability. ```ts import Ability from '@ohos.application.Ability' @@ -302,7 +302,7 @@ export default class MainAbility extends Ability { } ``` -Obtain the `want` parameter that contains the page information from the custom component and process the route based on the URI. +Obtain the **want** parameter that contains the page information from the custom component and process the route based on the URI. ```ts import router from '@ohos.router' @@ -315,7 +315,7 @@ struct Index { console.info('Index onPageShow') let newWant = globalThis.newWant if (newWant.hasOwnProperty("uri")) { - router.push({ uri: newWant.uri }); + router.push({ url: newWant.uri }); globalThis.newWant = undefined } } diff --git a/en/application-dev/ability/stage-brief.md b/en/application-dev/ability/stage-brief.md index 427495774aa06066f6fd38c972ef59eafb102cf3..2cf186f82db342e02523ee4645521ea72fbd1f6f 100644 --- a/en/application-dev/ability/stage-brief.md +++ b/en/application-dev/ability/stage-brief.md @@ -2,7 +2,7 @@ ## Design Ideas -The stage model is designed to make it easier to develop complex applications in the distributed environment. +The stage model is designed to provide a better application development mode in the distributed environment. The following figure shows the design ideas of the stage model. @@ -10,18 +10,17 @@ The following figure shows the design ideas of the stage model. The stage model is designed based on the following considerations: -- **Balance between application capabilities and overall system power consumption** +- Efficient management of application processes - On a running device, resources are preferentially guaranteed for foreground applications, on the prerequisites that the overall power consumption requirements of the system are met. The stage model balances the application capabilities and overall system power consumption through ability and UI separation, strict background control, scenario-based service mechanism, and single-process model. + As the device memory becomes larger, the number of processes concurrently running in the system increases. If the number of concurrent processes reaches several hundreds, the overall power consumption and performance of the system will be adversely affected without effective management measures. To restrict the behavior of background processes, the stage model uses four measures: transient task, continuous task, agent task, and Work Scheduler task. With these measures, foreground processes will obtain guaranteed resources, thereby delivering a better user experience. -- **Native support for component continuation and collaboration** +- Native support for cross-device migration and multi-device collaboration - OpenHarmony natively supports distributed deployment. Therefore, its application framework must be designed for easier component migration and collaboration. The stage model achieves this design objective by providing features such as separation between ability and UI as well as integration of UI display and service capabilities. + OpenHarmony is a native distributed OS. Its application framework must be designed for easier component migration and collaboration across devices. The stage model achieves this design objective by providing features such as separation between ability and UI as well as integration of UI display and service capabilities. -- **Support for multiple device types and window forms** - - To support multiple device types and facilitate the implementation of different window forms, the component manager and window manager must be decoupled at the architecture layer for easier tailoring. To achieve this goal, the stage model redefines the ability lifecycle and implements unidirectional dependency for the component manager and window manager. +- Different window forms for various device types + The stage model redefines the ability lifecycle. In terms of architecture, the component manager and window manager are decoupled. This facilitates adaptation between window forms and device types. ## Basic Concepts @@ -29,40 +28,42 @@ The following figure shows the basic concepts in the stage model. ![stageconcept](figures/stageconcept.png) -- **HAP**: Harmony Ability Package, also called module, which is the basic unit for building, distributing, and loading OpenHarmony applications. Each HAP has a unique name, which is called **moduleName**, in an application. +- **HAP**: basic unit for building, distributing, and loading OpenHarmony applications. Each HAP corresponds to a module in the development state. In an application, **moduleName** uniquely identifies a module. - **Bundle**: an OpenHarmony application identified by **appid**. A bundle can contain multiple HAP files. Each application has a **bundleName**. However, **bundleName** must be used together with **appid** and other information to uniquely identify an application. -- **AbilityStage**: runtime class of an HAP. It is created when the HAP is loaded to the process for the first time and is visible to developers in the runtime. -- **Application**: runtime class of a bundle, which is invisible to developers in the runtime. -- **Context**: base class that the context classes of **Ability** and **ExtensionAbility** classes inherit. This class provides various capabilities that can be invoked by developers in the runtime, and various information such as the bundle name, module name, and path. -- **Ability**: class that provides lifecycle callbacks, holds the **AbilityContext** class, and supports component continuation and collaboration. -- **ExtensionAbility**: general name of scenario-based service extension abilities. The system defines multiple scenario-based **ExtensionAbility** classes, each of which has its own **ExtensionContext**. +- **AbilityStage**: runtime object of an HAP. It is created when the HAP is loaded to the process for the first time and is visible to developers in the runtime. +- **Application**: runtime object of a bundle. It is invisible to developers in the runtime. +- **Context**: base class that provides APIs in the runtime to obtain information such as the bundle name, module name, and path. The **Context** classes of the Ability and ExtensionAbility components inherit from this class. +- **Ability**: provides lifecycle callbacks, holds the ability context, and supports cross-device component migration and multi-device collaboration. +- **ExtensionAbility**: general name of scenario-based Extension abilities. The system defines multiple scenario-based **ExtensionAbility** classes, each of which has its own **ExtensionContext**. - **WindowStage**: local window manager. -- **Window**: basic unit managed by the window manager. It has an ArkUI engine instance. -- **ArkUI Page**: ArkUI development framework page. +- **Window**: application window, which holds an ArkUI engine instance. +- **ArkUI Page**: UI developed based on ArkUI. ## Lifecycle -The ability and ability stage lifecycles are the rudiments of the basic process of an application. For details about how these lifecycles differ from those in the FA model, see [Ability Framework Overview](ability-brief.md). This section focuses on the ability lifecycle transition and the scheduling relationships between the ability, ability stage, and window stage. +The ability and ability stage are key objects in the application lifecycle. + +For details about the lifecycle differences between the stage model and FA model, see [Ability Framework Overview](ability-brief.md). This section focuses on the ability lifecycle transition and the scheduling relationships between the ability, ability stage, and window stage. ![stageabilitylifecyclecallback](figures/stageabilitylifecyclecallback.png) -To implement device-specific tailoring and multi-window scalability, OpenHarmony decouples the component manager from the window manager. The ability lifecycle defined in the stage model includes only the creation, destruction, foreground, and background states. The gain focus and lose focus states that are closely related to UI content are defined in the window stage. This implements weak coupling between the abilities and windows. On the service side, the window manager notifies the component manager of the foreground and background changes, so the component manager only senses the foreground and background changes but not the focus changes. +To implement device adaptation and multi-window scalability, OpenHarmony decouples the component manager from the window manager. -There are two lifecycle states related to **WindowStage** in **Ability**: **onWindowStageCreate** and **onWindowStageDestroy**. They are valid only for devices with the window display capability. **onWindowStageCreate** is invoked when a window stage is created, where you can call **loadContent** to set pages to be loaded for the ability. **onWindowStageDestroy** is invoked when the window stage is destroyed, where you can release resources. +The ability lifecycle defined in the stage model includes only the creation, destruction, foreground, and background states. The gain focus and lose focus states that are closely related to UI are defined in the window stage. This implements weak coupling between the abilities and windows. On the service side, the window manager notifies the component manager of the foreground and background state changes, so the component manager only senses the foreground and background state changes but not the focus changes. + +There are two lifecycle states related to the window stage in **Ability**: **onWindowStageCreate** and **onWindowStageDestroy**. They are valid only for devices with the display capability. **onWindowStageCreate** is invoked when a window stage is created, where you can call **loadContent** to set pages to be loaded for the ability. **onWindowStageDestroy** is invoked when the window stage is destroyed, where you can release resources. ## Ability Instances and Missions Abilities can be started in any of the following modes: -+ **Singleton**: For each type of ability, only one instance exists in the application process. **Ability1** in the figure below is started in singleton mode. - -+ **Standard**: Each time **startAbility** is called, an instance of the specified ability type is created in the application process. **Ability2** in the figure below is started in standard mode. +* **Singleton**: For each type of ability, only one instance exists in the application process. **Ability1** in the figure below is started in singleton mode. +* **Standard**: Each time **startAbility** is called, an instance of the specified ability type is created in the application process. **Ability2** in the figure below is started in standard mode. +* **Specified**: Before creating an **Ability** instance, you can create a key for the instance. Each time **startAbility** is called, the system asks the application which ability instance (corresponding to a key) will be used. **Ability3** in the figure below is started in specified mode. -+ **Specified**: Before creating an **Ability** instance, you can create a key for the instance. Each time **startAbility** is called, the system asks the application which ability instance (corresponding to a key) will be used. **Ability3** in the figure below is started in specified mode. - -Each ability instance corresponds to a mission in **Launcher Recent**. +Each **Ability** instance corresponds to a mission in **Recents**. The mission corresponding to an ability instance has a snapshot of the ability instance. After the ability instance is destroyed, the ability class information and snapshot are retained in the mission until the user deletes the information or the storage space reaches the upper limit. @@ -70,33 +71,37 @@ The mission corresponding to an ability instance has a snapshot of the ability i ## ExtensionAbility Mechanism -Different from the ability used for page display, the extension ability provides a restricted service running environment. It has the following features: +Different from the ability used for UI display, ExtensionAbility provides a restricted running environment. + +ExtensionAbility has the following features: -- Its process runs independently from the main process and shares the same storage sandbox with the main process. There is no inter-process communication (IPC) between the process and the main process. +- Its process runs independently from the main process but shares the same storage sandbox with the main process. There is no inter-process communication (IPC) between the ExtensionAbility process and the main process. - It has an independent context that provides scenario-specific APIs. - It is created by the system, rather than by applications. -- The lifecycles of the extension ability and process are managed by the system. +- The lifecycles of the ExtensionAbility component and process are managed by the system. -The following figure uses the widget scenario as an example. You can inherit from the **FormExtensionAbility** base class to provide the widget details. The lifecycle of the **FormExtensionAbility** instance and that of the extension ability process where the instance is located are managed by **FormManagerService**, which is a system service. +The following figure uses the widget an example. **FormExtensionAbility** is the base class. You can inherit from this class to provide widget information. The lifecycle of the **FormExtensionAbility** instance and that of the ExtensionAbility process where the instance is located are managed by a system service named **FormManagerService**. ![ExtensionAbility](figures/ExtensionAbility.png) ## Process Model -All OpenHarmony applications are designed to meet the single-process model. In the single-process model, all processes in the application are created and managed by the system. Each application supports a maximum of three types of processes: +OpenHarmony forces strong control policies on application processes. No APIs are provided to configure multiple processes. All application processes are created and managed by the system. + +The processes of an application can be classified into three types: -- Main process: runs all ability components, pages, and service logic. +- Main process: runs the **UIAbility** component, UI, and service logic. - Extension process: runs classes derived from **ExtensionAbility** in the application. The lifecycle of this process is managed by a scenario-specific system service. - Render process: created for the WebView and used to load the WebView rendering library. -The following figure shows the process model of an application. + The following figure shows the process model of an application. -![stageprocessmodel](figures/stageprocessmodel.png) + ![stageprocessmodel](figures/stageprocessmodel.png) ## Application Package Structure diff --git a/en/application-dev/ability/stage-call.md b/en/application-dev/ability/stage-call.md index 390e1b6c3ce5393956d0a7801f362ab7f49578a4..5c29001e5c62f4059121247e9a044474111527c3 100644 --- a/en/application-dev/ability/stage-call.md +++ b/en/application-dev/ability/stage-call.md @@ -2,9 +2,9 @@ ## When to Use Ability call is an extension of the ability capability. It enables an ability to be invoked by and communicate with external systems. The ability invoked can be either started in the foreground or created and run in the background. You can use the ability call to implement data sharing between two abilities (caller ability and callee ability) through inter-process communication (IPC). -The core API used for the ability call is `startAbilityByCall`, which differs from `startAbility` in the following ways: - - `startAbilityByCall` supports ability startup in the foreground and background, whereas `startAbility` supports ability startup in the foreground only. - - The caller ability can use the `Caller` object returned by `startAbilityByCall` to communicate with the callee ability, but `startAbility` does not provide the communication capability. +The core API used for the ability call is **startAbilityByCall**, which differs from **startAbility** in the following ways: + - **startAbilityByCall** supports ability startup in the foreground and background, whereas **startAbility** supports ability startup in the foreground only. + - The caller ability can use the **Caller** object returned by **startAbilityByCall** to communicate with the callee ability, but **startAbility** does not provide the communication capability. Ability call is usually used in the following scenarios: - Communicating with the callee ability @@ -15,17 +15,17 @@ Ability call is usually used in the following scenarios: |:------|:------| |Caller ability|Ability that triggers the ability call.| |Callee ability|Ability invoked by the ability call.| -|Caller |Object returned by `startAbilityByCall` and used by the caller ability to communicate with the callee ability.| +|Caller |Object returned by **startAbilityByCall** and used by the caller ability to communicate with the callee ability.| |Callee |Object held by the callee ability to communicate with the caller ability.| |IPC |Inter-process communication.| The ability call process is as follows: - - The caller ability uses `startAbilityByCall` to obtain a `Caller` object and uses `call()` of the `Caller` object to send data to the callee ability. - - The callee ability, which holds a `Callee` object, uses `on()` of the `Callee` object to register a callback. This callback is invoked when the callee ability receives data from the caller ability. + - The caller ability uses **startAbilityByCall** to obtain a **Caller** object and uses **call()** of the **Caller** object to send data to the callee ability. + - The callee ability, which holds a **Callee** object, uses **on()** of the **Callee** object to register a callback. This callback is invoked when the callee ability receives data from the caller ability. ![stage-call](figures/stage-call.png) > **NOTE**
-> The launch type of the callee ability must be `singleton`. +> The launch type of the callee ability must be **singleton**. > Currently, only system applications can use the ability call. ## Available APIs @@ -34,30 +34,29 @@ The table below describes the ability call APIs. For details, see [Ability](../r **Table 2** Ability call APIs |API|Description| |:------|:------| -|startAbilityByCall(want: Want): Promise\|Starts an ability in the foreground (through the `want` configuration) or background (default) and obtains the `Caller` object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-service-extension-context.md#serviceextensioncontextstartabilitybycall).| +|startAbilityByCall(want: Want): Promise\|Starts an ability in the foreground (through the **want** configuration) or background (default) and obtains the **Caller** object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-service-extension-context.md#serviceextensioncontextstartabilitybycall).| |on(method: string, callback: CalleeCallBack): void|Callback invoked when the callee ability registers a method.| |off(method: string): void|Callback invoked when the callee ability deregisters a method.| |call(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability.| |callWithResult(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability and obtains the agreed sequenceable data returned by the callee ability.| -|release(): void|Releases the `Caller` object.| -|onRelease(callback: OnReleaseCallBack): void|Callback invoked when the `Caller` object is released.| +|release(): void|Releases the **Caller** object.| +|on(type: "release", callback: OnReleaseCallback): void|Callback invoked when the **Caller** object is released.| ## How to Develop The procedure for developing the ability call is as follows: 1. Create a callee ability. + 2. Access the callee ability. -> **NOTE** -> -> The code snippets provided in the **How to Develop** section are used to show specific development steps. They may not be able to run independently. + ### Creating a Callee Ability -For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use `on()` to register a listener. When data does not need to be received, use `off()` to deregister the listener. +For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. **1. Configure the ability launch type.** - Set `launchType` of the callee ability to `singleton` in the `module.json5` file. + Set **launchType** of the callee ability to **singleton** in the **module.json5** file. |JSON Field|Description| |:------|:------| -|"launchType"|Ability launch type. Set this parameter to `singleton`.| +|"launchType"|Ability launch type. Set this parameter to **singleton**.| An example of the ability configuration is as follows: ```json @@ -73,7 +72,7 @@ An example of the ability configuration is as follows: ``` **2. Import the Ability module.** ```ts -import Ability from '@ohos.application.Ability' +import Ability from '@ohos.app.ability.UIAbility' ``` **3. Define the agreed sequenceable data.** @@ -101,9 +100,9 @@ export default class MySequenceable { } } ``` -**4. Implement `Callee.on` and `Callee.off`.** +**4. Implement Callee.on and Callee.off.** - The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the `MSG_SEND_METHOD` listener is registered in `onCreate` of the ability and deregistered in `onDestroy`. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The code snippet is as follows: + The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the ability and deregistered in **onDestroy**. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The code snippet is as follows: ```ts const TAG: string = '[CalleeAbility]' const MSG_SEND_METHOD: string = 'CallSendMsg' @@ -143,16 +142,16 @@ export default class CalleeAbility extends Ability { ### Accessing the Callee Ability **1. Import the Ability module.** ```ts -import Ability from '@ohos.application.Ability' +import Ability from '@ohos.app.ability.UIAbility' ``` -**2. Obtain the `Caller` object.** +**2. Obtain the Caller object.** - The `context` attribute of the ability implements `startAbilityByCall` to obtain the `Caller` object for communication. The following example uses `this.context` to obtain the `context` attribute of the ability, uses `startAbilityByCall` to start the callee ability, obtain the `Caller` object, and register the `onRelease` listener of the caller ability. You need to implement processing based on service requirements. The code snippet is as follows: + The **context** attribute of the ability implements **startAbilityByCall** to obtain the **Caller** object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the **Caller** object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. The code snippet is as follows: ```ts // Register the onRelease listener of the caller ability. private regOnRelease(caller) { try { - caller.onRelease((msg) => { + caller.on("release", (msg) => { console.log(`caller onRelease is called ${msg}`) }) console.log('caller register OnRelease succeed') @@ -193,7 +192,7 @@ async onButtonGetRemoteCaller() { caller = data console.log('get remote caller success') // Register the onRelease listener of the caller ability. - caller.onRelease((msg) => { + caller.on("release", (msg) => { console.log(`remote caller onRelease is called ${msg}`) }) console.log('remote caller register OnRelease succeed') @@ -203,7 +202,7 @@ async onButtonGetRemoteCaller() { }) } ``` - Obtain the ID of the peer device from `DeviceManager`. Note that the `getTrustedDeviceListSync` API is open only to system applications. The code snippet is as follows: + Obtain the ID of the peer device from **DeviceManager**. Note that the **getTrustedDeviceListSync** API is open only to system applications. The code snippet is as follows: ```ts import deviceManager from '@ohos.distributedHardware.deviceManager'; var dmClass; @@ -248,7 +247,7 @@ async onButtonCall() { } ``` - In the following, `CallWithResult` is used to send data `originMsg` to the callee ability and assign the data processed by the `CallSendMsg` method to `backMsg`. The code snippet is as follows: + In the following, **CallWithResult** is used to send data **originMsg** to the callee ability and assign the data processed by the **CallSendMsg** method to **backMsg**. The code snippet is as follows: ```ts const MSG_SEND_METHOD: string = 'CallSendMsg' originMsg: string = '' @@ -268,9 +267,9 @@ async onButtonCallWithResult(originMsg, backMsg) { } } ``` -**4. Release the `Caller` object.** +**4. Release the Caller object.** - When the `Caller` object is no longer required, use `release()` to release it. The code snippet is as follows: + When the **Caller** object is no longer required, use **release()** to release it. The code snippet is as follows: ```ts releaseCall() { try { diff --git a/en/application-dev/connectivity/Readme-EN.md b/en/application-dev/connectivity/Readme-EN.md index 16bf40cf8467bc805d3b485ca46d6f0fa295b3bc..578e2a3c56c8a1f6cce377eb39ef9a7756d74491 100755 --- a/en/application-dev/connectivity/Readme-EN.md +++ b/en/application-dev/connectivity/Readme-EN.md @@ -1,11 +1,11 @@ # Connectivity - Network Management - - [Network Management Overview](net-mgmt-overview.md) - - [HTTP Data Request](http-request.md) - - [WebSocket Connection](websocket-connection.md) - - [Socket Connection](socket-connection.md) + - [Network Management Overview](net-mgmt-overview.md) + - [HTTP Data Request](http-request.md) + - [WebSocket Connection](websocket-connection.md) + - [Socket Connection](socket-connection.md) - IPC & RPC - - [IPC & RPC Overview](ipc-rpc-overview.md) - - [IPC & RPC Development](ipc-rpc-development-guideline.md) - - [Subscribing to State Changes of a Remote Object](subscribe-remote-state.md) + - [IPC & RPC Overview](ipc-rpc-overview.md) + - [IPC & RPC Development](ipc-rpc-development-guideline.md) + - [Subscribing to State Changes of a Remote Object](subscribe-remote-state.md) diff --git a/en/application-dev/database/database-mdds-guidelines.md b/en/application-dev/database/database-mdds-guidelines.md index 8cec5ca111cd814d599d159ab7b333259f669ea8..73f785de4ddccaa1e10c6049066a5f3908d85fc6 100644 --- a/en/application-dev/database/database-mdds-guidelines.md +++ b/en/application-dev/database/database-mdds-guidelines.md @@ -6,20 +6,20 @@ The Distributed Data Service (DDS) implements synchronization of application dat ## Available APIs -For details about the APIs, see [Distributed Data Management](../reference/apis/js-apis-distributed-data.md). +For details about the APIs, see [Distributed KV Store](../reference/apis/js-apis-distributedKVStore.md). **Table 1** APIs provided by the DDS -| API | Description | -| ------------------------------------------------------------ | ----------------------------------------------- | -| createKVManager(config: KVManagerConfig, callback: AsyncCallback<KVManager>): void
createKVManager(config: KVManagerConfig): Promise<KVManager> | Creates a **KVManager** object for database management.| -| getKVStore<TextendsKVStore>(storeId: string, options: Options, callback: AsyncCallback<T>): void
getKVStore<TextendsKVStore>(storeId: string, options: Options): Promise<T> | Obtains a KV store with the specified **Options** and **storeId**.| -| put(key: string, value: Uint8Array\|string\|number\|boolean, callback: AsyncCallback<void>): void
put(key: string, value: Uint8Array\|string\|number\|boolean): Promise<void> | Inserts and updates data. | -| delete(key: string, callback: AsyncCallback<void>): void
delete(key: string): Promise<void> | Deletes data. | -| get(key: string, callback: AsyncCallback<Uint8Array\|string\|boolean\|number>): void
get(key: string): Promise<Uint8Array\|string\|boolean\|number> | Queries data. | -| on(event: 'dataChange', type: SubscribeType, observer: Callback<ChangeNotification>): void
on(event: 'syncComplete', syncCallback: Callback<Array<[string,number]>>): void | Subscribes to data changes in the KV store. | -| sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: number): void | Triggers database synchronization in manual mode. | +| API | Description | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| createKVManager(config: KVManagerConfig, callback: AsyncCallback<KVManager>): void
createKVManager(config: KVManagerConfig): Promise<KVManager> | Creates a **KvManager** object for database management. | +| getKVStore<TextendsKVStore>(storeId: string, options: Options, callback: AsyncCallback<T>): void
getKVStore<TextendsKVStore>(storeId: string, options: Options): Promise<T> | Creates and obtains a KV store.| +| put(key: string, value: Uint8Array\|string\|number\|boolean, callback: AsyncCallback<void>): void
put(key: string, value: Uint8Array\|string\|number\|boolean): Promise<void> | Inserts and updates data. | +| delete(key: string, callback: AsyncCallback<void>): void
delete(key: string): Promise<void> | Deletes data. | +| get(key: string, callback: AsyncCallback<Uint8Array\|string\|boolean\|number>): void
get(key: string): Promise<Uint8Array\|string\|boolean\|number> | Queries data. | +| on(event: 'dataChange', type: SubscribeType, observer: Callback<ChangeNotification>): void
on(event: 'syncComplete', syncCallback: Callback<Array<[string,number]>>): void | Subscribes to data changes in the KV store. | +| sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: number): void | Triggers database synchronization in manual mode. | ## How to Develop @@ -28,23 +28,25 @@ The following uses a single KV store as an example to describe the development p 1. Import the distributed data module. ```js - import distributedData from '@ohos.data.distributedData'; + import distributedKVStore from '@ohos.data.distributedKVStore'; ``` + 2. Apply for the required permission if data synchronization is required. Add the permission required (FA model) in the **config.json** file. The sample code is as follows: ```json - { - "module": { - "reqPermissions": [ - { - "name": "ohos.permission.DISTRIBUTED_DATASYNC" - } - ] - } - } + { + "module": { + "reqPermissions": [ + { + "name": "ohos.permission.DISTRIBUTED_DATASYNC" + } + ] + } + } ``` + For the apps based on the stage model, see [Declaring Permissions](../security/accesstoken-guidelines.md#stage-model). This permission must also be granted by the user when the application is started for the first time. The sample code is as follows: @@ -52,7 +54,7 @@ The following uses a single KV store as an example to describe the development p ```js // FA model import featureAbility from '@ohos.ability.featureAbility'; - + function grantPermission() { console.info('grantPermission'); let context = featureAbility.getContext(); @@ -62,21 +64,21 @@ The following uses a single KV store as an example to describe the development p console.info('failed: ${error}'); }) } - + grantPermission(); - + // Stage model import Ability from '@ohos.application.Ability'; - + let context = null; - + function grantPermission() { class MainAbility extends Ability { onWindowStageCreate(windowStage) { let context = this.context; } } - + let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC']; context.requestPermissionsFromUser(permissions).then((data) => { console.log('success: ${data}'); @@ -84,14 +86,14 @@ The following uses a single KV store as an example to describe the development p console.log('failed: ${error}'); }); } - + grantPermission(); ``` -3. Create a **kvManager** instance based on the specified **kvManagerConfig** object. +3. Create a **KvManager** instance based on the specified **KvManagerConfig** object. 1. Create a **kvManagerConfig** object based on the application context. - 2. Create a **kvManager** instance. + 2. Create a **KvManager** instance. The sample code is as follows: @@ -99,7 +101,7 @@ The following uses a single KV store as an example to describe the development p // Obtain the context of the FA model. import featureAbility from '@ohos.ability.featureAbility'; let context = featureAbility.getContext(); - + // Obtain the context of the stage model. import AbilityStage from '@ohos.application.Ability'; let context = null; @@ -108,27 +110,23 @@ The following uses a single KV store as an example to describe the development p context = this.context; } } - + let kvManager; try { const kvManagerConfig = { bundleName: 'com.example.datamanagertest', - userInfo: { - context:context, - userId: '0', - userType: distributedData.UserType.SAME_USER_ID - } + context:context, } - distributedData.createKVManager(kvManagerConfig, function (err, manager) { + distributedKVStore.createKVManager(kvManagerConfig, function (err, manager) { if (err) { - console.log('Failed to create KVManager: ${error}'); + console.error(`Failed to create KVManager.code is ${err.code},message is ${err.message}`); return; } console.log('Created KVManager successfully'); kvManager = manager; }); } catch (e) { - console.log('An unexpected error occurred. Error: ${e}'); + console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`); } ``` @@ -147,34 +145,38 @@ The following uses a single KV store as an example to describe the development p encrypt: false, backup: false, autoSync: false, - kvStoreType: distributedData.KVStoreType.SINGLE_VERSION, - securityLevel: distributedData.SecurityLevel.S0 + kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, + securityLevel: distributedKVStore.SecurityLevel.S1 }; kvManager.getKVStore('storeId', options, function (err, store) { if (err) { - console.log('Failed to get KVStore: ${err}'); + console.error(`Failed to get KVStore: code is ${err.code},message is ${err.message}`); return; } - console.log('Got KVStore successfully'); + console.log('Obtained KVStore successfully'); kvStore = store; }); } catch (e) { - console.log('An unexpected error occurred. Error: ${e}'); + console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`); } ``` > **NOTE**
> > For data synchronization between networked devices, you are advised to open the distributed KV store during application startup to obtain the database handle. With this database handle (`kvStore` in this example), you can perform operations, such as inserting data into the KV store, without creating the KV store repeatedly during the lifecycle of the handle. - + 5. Subscribe to changes in the distributed data. The following is the sample code for subscribing to the data changes of a single KV store: ```js - kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) { - console.log("dataChange callback call data: ${data}"); - }); + try{ + kvStore.on('dataChange', distributedKVStore.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) { + console.log(`dataChange callback call data: ${data}`); + }); + }catch(e){ + console.error(`An unexpected error occured.code is ${e.code},message is ${e.message}`); + } ``` 6. Write data to the single KV store. @@ -188,15 +190,15 @@ The following uses a single KV store as an example to describe the development p const KEY_TEST_STRING_ELEMENT = 'key_test_string'; const VALUE_TEST_STRING_ELEMENT = 'value-test-string'; try { - kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err, data) { + kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) { if (err != undefined) { - console.log('Failed to put data: ${error}'); + console.error(`Failed to put.code is ${err.code},message is ${err.message}`); return; } console.log('Put data successfully'); }); - } catch (e) { - console.log('An unexpected error occurred. Error: ${e}'); + }catch (e) { + console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`); } ``` @@ -211,18 +213,22 @@ The following uses a single KV store as an example to describe the development p const KEY_TEST_STRING_ELEMENT = 'key_test_string'; const VALUE_TEST_STRING_ELEMENT = 'value-test-string'; try { - kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err, data) { + kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) { if (err != undefined) { - console.log('Failed to put data: ${error}'); + console.error(`Failed to put.code is ${err.code},message is ${err.message}`); return; } console.log('Put data successfully'); - kvStore.get(KEY_TEST_STRING_ELEMENT, function (err, data) { - console.log('Got data successfully: ${data}'); + kvStore.get(KEY_TEST_STRING_ELEMENT, function (err,data) { + if (err != undefined) { + console.error(`Failed to get data.code is ${err.code},message is ${err.message}`); + return; + } + console.log(`Obtained data successfully:${data}`); }); }); - } catch (e) { - console.log('An unexpected error occurred. Error: ${e}'); + }catch (e) { + console.error(`Failed to get.code is ${e.code},message is ${e.message}`); } ``` @@ -233,7 +239,7 @@ The following uses a single KV store as an example to describe the development p > **NOTE**
> > The APIs of the `deviceManager` module are system interfaces. - + The following is the example code for synchronizing data in a single KV store: ```js @@ -254,9 +260,9 @@ The following uses a single KV store as an example to describe the development p } try{ // 1000 indicates that the maximum delay is 1000 ms. - kvStore.sync(deviceIds, distributedData.SyncMode.PUSH_ONLY, 1000); + kvStore.sync(deviceIds, distributedKVStore.SyncMode.PUSH_ONLY, 1000); } catch (e) { - console.log('An unexpected error occurred. Error: ${e}'); + console.error(`An unexpected error occurred. code is ${e.code},message is ${e.message}`); } } }); diff --git a/en/application-dev/database/database-preference-guidelines.md b/en/application-dev/database/database-preference-guidelines.md index c4f6250f5ae91a645fe6aba6b81ec98df8eb2329..897be371287a22f8efe7a8571feec93458d1ba5f 100644 --- a/en/application-dev/database/database-preference-guidelines.md +++ b/en/application-dev/database/database-preference-guidelines.md @@ -28,26 +28,29 @@ Obtain a **Preferences** instance for data operations. A **Preferences** instanc | --------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | ohos.data.preferences | getPreferences(context: Context, name: string): Promise\ | Obtains a **Preferences** instance.| -### Accessing Data +### Processing Data -Call the **put()** method to add or modify data in a **Preferences** instance. +Call **put()** to add or modify data in a **Preferences** instance. -Call the **get()** method to read data from a **Preferences** instance. +Call **get()** to read data from a **Preferences** instance. Call **getAll()** to obtain an **Object** instance that contains all KV pairs in a **Preferences** instance. -**Table 2** APIs for accessing **Preferences** data +Call **delete()** to delete the KV pair of the specified key from the **Preferences** instance. + +**Table 2** APIs for processing **Preferences** data | Class | API | Description | | ----------- | ---------------------------------------------------------- | ------------------------------------------------------------ | | Preferences | put(key: string, value: ValueType): Promise\ | Writes data to the **Preferences** instance. The value to write can be a number, a string, a Boolean value, or an array of numbers, strings, or Boolean values.| | Preferences | get(key: string, defValue: ValueType): Promise\ | Obtains data from the **Preferences** instance. The value to read can be a number, a string, a Boolean value, or an array of numbers, strings, or Boolean values.| -| Preferences | getAll(): Promise | Obtains an **Object** instance that contains all KV pairs in the **Preferences** instance. | +| Preferences | getAll(): Promise\ | Obtains an **Object** instance that contains all KV pairs in the **Preferences** instance. | +| Preferences | delete(key: string): Promise\ | Deletes the KV pair of the specified key from the **Preferences** instance. | ### Storing Data Persistently -Call the **flush()** method to write the cached data back to its text file for persistent storage. +Call **flush()** to write the cached data back to its text file for persistent storage. **Table 4** API for data persistence @@ -68,7 +71,7 @@ You can subscribe to data changes. When the value of the subscribed key is chang ### Deleting Data -Use the following APIs to delete a **Preferences** instance or data file. +You can use the following APIs to delete a **Preferences** instance or data file. **Table 6** APIs for deleting **Preferences** @@ -130,7 +133,7 @@ Use the following APIs to delete a **Preferences** instance or data file. 3. Write data. - Use the **preferences.put()** method to write data to the **Preferences** instance. + Use **preferences.put()** to write data to the **Preferences** instance. ```js let putPromise = preferences.put('startup', 'auto'); @@ -143,7 +146,7 @@ Use the following APIs to delete a **Preferences** instance or data file. 4. Read data. - Use the **preferences.get()** method to read data. + Use **preferences.get()** to read data. ```js let getPromise = preferences.get('startup', 'default'); @@ -156,7 +159,7 @@ Use the following APIs to delete a **Preferences** instance or data file. 5. Store data persistently. - Use the **flush()** method to flush data from the **Preferences** instance to its file. + Use **flush()** to flush data from the **Preferences** instance to its file. ```js preferences.flush(); @@ -177,7 +180,7 @@ Use the following APIs to delete a **Preferences** instance or data file. console.info("Failed to put the value of 'startup'. Cause: " + err); return; } - console.info("Put the value of 'startup' successfully."); + console.info("Put the value of 'startup' successfully."); preferences.flush(function (err) { if (err) { console.info("Failed to flush data. Cause: " + err); @@ -190,7 +193,7 @@ Use the following APIs to delete a **Preferences** instance or data file. 7. Delete the specified file. - Use the **deletePreferences** method to delete the **Preferences** instance and its persistent file and backup and corrupted files. After the specified files are deleted, the application cannot use that instance to perform any data operation. Otherwise, data inconsistency will be caused. The deleted data and files cannot be restored. + Use **deletePreferences()** to delete the **Preferences** instance and its persistent file and backup and corrupted files. After the specified files are deleted, the application cannot use that instance to perform any data operation. Otherwise, data inconsistency will be caused. The deleted data and files cannot be restored. ```js let proDelete = data_preferences.deletePreferences(context, 'mystore'); diff --git a/en/application-dev/database/database-relational-guidelines.md b/en/application-dev/database/database-relational-guidelines.md index 70fb8cbbee58dd51b8edacf8f7d6bc58e874859d..53e3ca5aeaa25ecea55f3e27272043e6b533e594 100644 --- a/en/application-dev/database/database-relational-guidelines.md +++ b/en/application-dev/database/database-relational-guidelines.md @@ -11,14 +11,14 @@ Most of the RDB store APIs are asynchronous interfaces, which can use a callback ### Creating or Deleting an RDB Store -The table below describes the APIs available for creating and deleting an RDB store. +The following table describes the APIs for creating and deleting an RDB store. **Table 1** APIs for creating and deleting an RDB store | API | Description | | ------------------------------------------------------------ | ------------------------------------------------------------ | -| getRdbStore(context: Context, config: StoreConfig, version: number): Promise<RdbStore> | Obtains an RDB store. This API uses a promise to return the result. You can set parameters for the RDB store based on service requirements and call APIs to perform data operations.
- **context**: context of the application or function.
- **config**: configuration of the RDB store.
- **version**: version of the RDB store.| -| deleteRdbStore(context: Context, name: string): Promise<void> | Deletes an RDB store. This API uses a promise to return the result.
- **context**: context of the application or function.
- **name**: name of the RDB store to delete.| +| getRdbStoreV9(context: Context, config: StoreConfigV9, version: number): Promise<RdbStoreV9> | Obtains an **RdbStoreV9** instance. This API uses a promise to return the result. You can set parameters for the RDB store based on service requirements and call APIs to perform data operations.
- **context**: context of the application or function.
- **config**: configuration of the RDB store.
- **version**: version of the RDB store. Currently, automatic RDB upgrades and downgrades performed based on **version** is not supported.| +| deleteRdbStoreV9(context: Context, name: string): Promise<void> | Deletes an RDB store. This API uses a promise to return the result.
- **context**: context of the application or function.
- **name**: name of the RDB store to delete.| ### Managing Data in an RDB Store @@ -31,31 +31,31 @@ The RDB provides APIs for inserting, deleting, updating, and querying data in th **Table 2** API for inserting data - | Class | API | Description | - | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | - | RdbStore | insert(table: string, values: ValuesBucket): Promise<number> | Inserts a row of data into a table. This API uses a promise to return the result.
If the operation is successful, the row ID will be returned; otherwise, **-1** will be returned.
- **table**: name of the target table.
- **values**: data to be inserted into the table.| + | Class | API | Description | + | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | + | RdbStoreV9 | insert(table: string, values: ValuesBucket): Promise<number> | Inserts a row of data into a table. This API uses a promise to return the result.
If the operation is successful, the row ID will be returned; otherwise, **-1** will be returned.
- **table**: name of the target table.
- **values**: data to be inserted into the table.| - **Updating Data** - Call the **update()** method to pass new data and specify the update conditions by using **RdbPredicates**. If the data is updated, the number of rows of the updated data will be returned; otherwise, **0** will be returned. + Call **update()** to update data based on the passed data and the conditions specified by **RdbPredicatesV9**. If the data is updated, the number of rows of the updated data will be returned; otherwise, **0** will be returned. **Table 3** API for updating data - | Class | API | Description | - | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | - | RdbStore | update(values: ValuesBucket, predicates: RdbPredicates): Promise<number> | Updates data based on the specified **RdbPredicates** object. This API uses a promise to return the result.
the number of rows updated.
- **values**: data to update, which is stored in **ValuesBucket**.
- **predicates**: conditions for updating data.| + | Class | API | Description | + | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | + | RdbStoreV9 | update(values: ValuesBucket, predicates: RdbPredicatesV9): Promise<number> | Updates data based on the specified **RdbPredicatesV9** object. This API uses a promise to return the number of rows updated.
- **values**: data to update, which is stored in **ValuesBucket**.
- **predicates**: conditions for updating data. | - **Deleting Data** - Call the **delete()** method to delete data meeting the conditions specified by **RdbPredicates**. If the data is deleted, the number of rows of the deleted data will be returned; otherwise, **0** will be returned. + Call **delete()** to delete the data that meets the conditions specified by **RdbPredicatesV9**. If the data is deleted, the number of rows of the deleted data will be returned; otherwise, **0** will be returned. **Table 4** API for deleting data - | Class | API | Description | - | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | - | RdbStore | delete(predicates: RdbPredicates): Promise<number> | Deletes data from the RDB store based on the specified **RdbPredicates** object. This API uses a promise to return
the number of rows updated.
- **predicates**: conditions for deleting data.| + | Class | API | Description | + | ---------- | ---------------------------------------------------------- | ------------------------------------------------------------ | + | RdbStoreV9 | delete(predicates: RdbPredicatesV9): Promise<number> | Deletes data from the RDB store based on the specified **RdbPredicatesV9** object. This API uses a promise to return the number of rows updated.
- **predicates**: conditions for deleting data. | - **Querying Data** @@ -67,62 +67,66 @@ The RDB provides APIs for inserting, deleting, updating, and querying data in th **Table 5** APIs for querying data - | Class | API | Description | - | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | - | RdbStore | query(predicates: RdbPredicates, columns?: Array<string>): Promise<ResultSet> | Queries data from the RDB store based on specified conditions. This API uses a promise to return the result.
- **predicates**: conditions for querying data.
- **columns**: columns to query. If this parameter is not specified, the query applies to all columns.| - | RdbStore | querySql(sql: string, bindArgs?: Array<ValueType>): Promise<ResultSet> | Queries data using the specified SQL statement. This API uses a promise to return the result.
- **sql**: SQL statement.
- **bindArgs**: arguments in the SQL statement.| - | RdbStore | remoteQuery(device: string, table: string, predicates: RdbPredicates, columns: Array<string>): Promise<ResultSet> | Queries data from the database of a remote device based on specified conditions. This API uses a promise to return the result.
- **device**: network ID of the remote device.
- **table**: name of the table to be queried.
- **predicates**: **RdbPredicates** that specifies the query condition.
- **columns**: columns to query. If this parameter is not specified, the query applies to all columns.| +| Class | API | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbStoreV9 | query(predicates: RdbPredicatesV9, columns?: Array<string>): Promise<ResultSetV9> | Queries data from the RDB store based on specified conditions. This API uses a promise to return the result.
- **predicates**: conditions for querying data.
- **columns**: columns to query. If this parameter is not specified, the query applies to all columns.| +| RdbStoreV9 | querySql(sql: string, bindArgs?: Array<ValueType>): Promise<ResultSetV9> | Queries data using the specified SQL statement. This API uses a promise to return the result.
- **sql**: SQL statement.
- **bindArgs**: arguments in the SQL statement.| +| RdbStoreV9 | remoteQuery(device: string, table: string, predicates: RdbPredicatesV9, columns: Array<string>): Promise<ResultSetV9> | Queries data from the database of a remote device based on specified conditions. This API uses a promise to return the result.
- **device**: network ID of the remote device.
- **table**: name of the table to be queried.
- **predicates**: **RdbPredicatesV9** that specifies the query conditions.
- **columns**: columns to query. If this parameter is not specified, the query applies to all columns.| ### Using Predicates -The RDB provides **RdbPredicates** for you to set database operation conditions. +The **RDB** module provides **RdbPredicatesV9** for you to set database operation conditions. -The following lists common predicates. For more information about predicates, see [**RdbPredicates**](../reference/apis/js-apis-data-rdb.md#rdbpredicates). +The following table lists common predicates. For more information about predicates, see [**RdbPredicates**](../reference/apis/js-apis-data-rdb.md#rdbpredicates). **Table 6** APIs for using RDB store predicates -| Class | API | Description | -| ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbPredicates | equalTo(field: string, value: ValueType): RdbPredicates | Sets an **RdbPredicates** to match the field with data type **ValueType** and value equal to the specified value.
- **field**: column name in the database table.
- **value**: value to match the **RdbPredicates**.
- **RdbPredicates**: **RdbPredicates** object that matches the specified field.| -| RdbPredicates | notEqualTo(field: string, value: ValueType): RdbPredicates | Sets an **RdbPredicates** to match the field with data type **ValueType** and value not equal to the specified value.
- **field**: column name in the database table.
- **value**: value to match the **RdbPredicates**.
- **RdbPredicates**: **RdbPredicates** object that matches the specified field.| -| RdbPredicates | or(): RdbPredicates | Adds the OR condition to the **RdbPredicates**.
- **RdbPredicates**: **RdbPredicates** with the OR condition.| -| RdbPredicates | and(): RdbPredicates | Adds the AND condition to the **RdbPredicates**.
- **RdbPredicates**: **RdbPredicates** with the AND condition.| -| RdbPredicates | contains(field: string, value: string): RdbPredicates | Sets an **RdbPredicates** to match a string containing the specified value.
- **field**: column name in the database table.
- **value**: value to match the **RdbPredicates**.
- **RdbPredicates**: **RdbPredicates** object that matches the specified field.| +| Class | API | Description | +| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbPredicatesV9 | equalTo(field: string, value: ValueType): RdbPredicatesV9 | Sets an **RdbPredicatesV9** to search for the data that is equal to the specified value.
- **field**: column name in the database table.
- **value**: value to match.
- **RdbPredicatesV9**: **RdbPredicatesV9** object created. | +| RdbPredicatesV9 | notEqualTo(field: string, value: ValueType): RdbPredicatesV9 | Sets an **RdbPredicatesV9** to search for the data that is not equal to the specified value.
- **field**: column name in the database table.
- **value**: value to match.
- **RdbPredicatesV9**: **RdbPredicatesV9** object created. | +| RdbPredicatesV9 | or(): RdbPredicatesV9 | Adds the OR condition to the **RdbPredicatesV9**.
- **RdbPredicatesV9**: **RdbPredicatesV9** with the OR condition. | +| RdbPredicatesV9 | and(): RdbPredicatesV9 | Adds the AND condition to the **RdbPredicatesV9**.
- **RdbPredicatesV9**: **RdbPredicatesV9** with the AND condition. | +| RdbPredicatesV9 | contains(field: string, value: string): RdbPredicatesV9 | Sets an **RdbPredicatesV9** to search for the data that contains the specified value.
- **field**: column name in the database table.
- **value**: value to match.
- **RdbPredicatesV9**: **RdbPredicatesV9** object created. | ### Using the Result Set -A result set can be regarded as a row of data in the queried results. It allows you to traverse and access the data you have queried. +You can use the APIs provided by **ResultSetV9** to traverse and access the data you have queried. A result set can be regarded as a row of data in the queried result. For details about how to use result set APIs, see [Result Set](../reference/apis/js-apis-data-resultset.md). -> **NOTICE**
+> **NOTICE** +> > After a result set is used, you must call the **close()** method to close it explicitly. **Table 7** APIs for using the result set -| Class | API | Description | -| --------- | ---------------------------------------------------- | ------------------------------------------ | -| ResultSet | goToFirstRow(): boolean | Moves to the first row of the result set. | -| ResultSet | getString(columnIndex: number): string | Obtains the value in the form of a string based on the specified column and current row. | -| ResultSet | getBlob(columnIndex: number): Uint8Array | Obtains the value in the form of a byte array based on the specified column and the current row.| -| ResultSet | getDouble(columnIndex: number): number | Obtains the value in the form of double based on the specified column and current row. | -| ResultSet | getLong(columnIndex: number): number | Obtains the value in the form of a long integer based on the specified column and current row. | -| ResultSet | close(): void | Closes the result set. | +| Class | API | Description | +| ----------- | ---------------------------------------- | ------------------------------------------ | +| ResultSetV9 | goToFirstRow(): boolean | Moves to the first row of the result set. | +| ResultSetV9 | getString(columnIndex: number): string | Obtains the value in the form of a string based on the specified column and current row. | +| ResultSetV9 | getBlob(columnIndex: number): Uint8Array | Obtains the value in the form of a byte array based on the specified column and the current row.| +| ResultSetV9 | getDouble(columnIndex: number): number | Obtains the value in the form of double based on the specified column and current row. | +| ResultSetV9 | getLong(columnIndex: number): number | Obtains the value in the form of a long integer based on the specified column and current row. | +| ResultSetV9 | close(): void | Closes the result set. | ### Setting Distributed Tables ->**CAUTION**
ohos.permission.DISTRIBUTED_DATASYNC is required for using the **setDistributedTables**, **obtainDistributedTableName**, **sync**, **on**, and **off** APIs of **RdbStore**. +> **NOTE** +> +> - The **ohos.permission.DISTRIBUTED_DATASYNC** permission is required for calling the **setDistributedTables**, **obtainDistributedTableName**, **sync**, **on** and **off** APIs of **RdbStore V9**. +> - The devices must be connected over network before the distributed tables are used. For details about the APIs and usage, see [Device Management](../reference/apis/js-apis-device-manager.md). **Setting Distributed Tables** **Table 8** API for setting distributed tables -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | setDistributedTables(tables: Array\): Promise\ | Sets distributed tables. This API uses a promise to return the result.
- **tables**: names of the distributed tables to set.| +| Class | API | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbStoreV9 | setDistributedTables(tables: Array\): Promise\ | Sets distributed tables. This API uses a promise to return the result.
- **tables**: names of the distributed tables to set.| **Obtaining the Distributed Table Name for a Remote Device** @@ -130,33 +134,33 @@ You can obtain the distributed table name for a remote device based on the local **Table 9** API for obtaining the distributed table name of a remote device -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | obtainDistributedTableName(device: string, table: string): Promise\ | Obtains the distributed table name for a remote device based on the local table name. The distributed table name is required when the RDB store of a remote device is queried. This API uses a promise to return the result.
- **device**: remote device.
- **table**: local table name.| +| Class | API | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbStoreV9 | obtainDistributedTableName(device: string, table: string): Promise\ | Obtains the distributed table name for a remote device based on the local table name. The distributed table name is required when the RDB store of a remote device is queried. This API uses a promise to return the result.
- **device**: remote device.
- **table**: local table name.| **Synchronizing Data Between Devices** **Table 10** API for synchronizing data between devices -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | sync(mode: SyncMode, predicates: RdbPredicates): Promise\> | Synchronizes data between devices. This API uses a promise to return the result.
- **mode**: synchronization mode. **SYNC_MODE_PUSH** means to push data from the local device to a remote device. **SYNC_MODE_PULL** means to pull data from a remote device to the local device.
- **predicates**: specifies the data and devices to synchronize.
- **string**: device ID.
- **number**: synchronization status of each device. The value **0** indicates a successful synchronization. Other values indicate a synchronization failure.| +| Class | API | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbStoreV9 | sync(mode: SyncMode, predicates: RdbPredicatesV9): Promise\> | Synchronizes data between devices. This API uses a promise to return the result.
- **mode**: synchronization mode. **SYNC_MODE_PUSH** means to push data from the local device to a remote device. **SYNC_MODE_PULL** means to pull data from a remote device to the local device.
- **predicates**: specifies the data and devices to synchronize.
- **string**: device ID.
- **number**: synchronization status of each device. The value **0** indicates a successful synchronization. Other values indicate a synchronization failure.| **Registering an RDB Store Observer** **Table 11** API for registering an observer -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | on(event: 'dataChange', type: SubscribeType, observer: Callback\>): void | Registers an observer for this RDB store to subscribe to distributed data changes. When data in the RDB store changes, a callback will be invoked to return the data changes.
- **type**: subscription type. **SUBSCRIBE_TYPE_REMOTE** means to subscribe to remote data changes.
- **observer**: observer that listens for data changes in the RDB store.| +| Class | API | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbStoreV9 | on(event: 'dataChange', type: SubscribeType, observer: Callback\>): void | Registers an observer for this RDB store to subscribe to distributed data changes. When data in the RDB store changes, a callback will be invoked to return the data changes.
- **type**: subscription type. **SUBSCRIBE_TYPE_REMOTE**: subscribes to remote data changes.
- **observer**: observer that listens for data changes in the RDB store.| **Unregistering an RDB Store Observer** **Table 12** API for unregistering an observer -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | off(event:'dataChange', type: SubscribeType, observer: Callback\>): void; | Unregisters the observer of the specified type from the RDB store. This API uses an asynchronous callback to return the result.
- **type**: subscription type. **SUBSCRIBE_TYPE_REMOTE** means to subscribe to remote data changes.
- **observer**: observer to unregister.| +| Class | API | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| RdbStoreV9 | off(event:'dataChange', type: SubscribeType, observer: Callback\>): void; | Unregisters the observer of the specified type from the RDB store. This API uses an asynchronous callback to return the result.
- **type**: subscription type. **SUBSCRIBE_TYPE_REMOTE**: subscribes to remote data changes.
- **observer**: observer to unregister.| ### Backing Up and Restoring an RDB Store @@ -164,17 +168,17 @@ You can obtain the distributed table name for a remote device based on the local **Table 13** API for backing up an RDB store -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | backup(destName: string): Promise<void> | Backs up an RDB store. This API uses a promise to return the result.
- **destName**: name of the RDB backup file.| +| Class | API | Description | +| ---------- | --------------------------------------------- | ------------------------------------------------------------ | +| RdbStoreV9 | backup(destName: string): Promise<void> | Backs up an RDB store. This API uses a promise to return the result.
- **destName**: name of the RDB backup file.| **Restoring an RDB Store** **Table 14** API for restoring an RDB store -| Class | API | Description | -| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| RdbStore | restore(srcName: string): Promise<void> | Restores an RDB store from a backup file. This API uses a promise to return the result.
- **srcName**: name of the backup file used to restore the RDB store.| +| Class | API | Description | +| ---------- | --------------------------------------------- | ------------------------------------------------------------ | +| RdbStoreV9 | restore(srcName: string): Promise<void> | Restores an RDB store from a backup file. This API uses a promise to return the result.
- **srcName**: name of the backup file used to restore the RDB store.| **Transaction** @@ -182,9 +186,9 @@ Table 15 Transaction APIs | Class | API | Description | | -------- | ----------------------- | --------------------------------- | -| RdbStore | beginTransaction(): void | Starts the transaction before executing SQL statements.| -| RdbStore | commit(): void | Commits the executed SQL statements. | -| RdbStore | rollBack(): void | Rolls back the SQL statements that have been executed. | +| RdbStoreV9 | beginTransaction(): void | Starts the transaction before executing SQL statements.| +| RdbStoreV9 | commit(): void | Commits the executed SQL statements. | +| RdbStoreV9 | rollBack(): void | Rolls back the SQL statements that have been executed. | ## How to Develop @@ -203,12 +207,13 @@ Table 15 Transaction APIs // Obtain the context. import featureAbility from '@ohos.ability.featureAbility' let context = featureAbility.getContext() - + const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)"; - - const STORE_CONFIG = { name: "RdbTest.db" } - data_rdb.getRdbStore(context, STORE_CONFIG, 1, function (err, rdbStore) { - rdbStore.executeSql(CREATE_TABLE_TEST) + + const STORE_CONFIGV9 = { name: "RdbTest.db", + securityLevel: data_rdb.SecurityLevel.S1} + data_rdb.getRdbStoreV9(context, STORE_CONFIGV9, 1, function (err, rdbStoreV9) { + rdbStoreV9.executeSql(CREATE_TABLE_TEST) console.info('create table done.') }) ``` @@ -223,15 +228,16 @@ Table 15 Transaction APIs context = this.context } } - + const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)"; - - const STORE_CONFIG = { name: "rdbstore.db" } - data_rdb.getRdbStore(context, STORE_CONFIG, 1, function (err, rdbStore) { - rdbStore.executeSql(CREATE_TABLE_TEST) + + const STORE_CONFIGV9 = { name: "rdbstore.db", + securityLevel: data_rdb.SecurityLevel.S1} + data_rdb.getRdbStoreV9(context, STORE_CONFIGV9, 1, function (err, rdbStoreV9) { + rdbStoreV9.executeSql(CREATE_TABLE_TEST) console.info('create table done.') }) - ``` + ``` 2. Insert data. @@ -244,12 +250,12 @@ Table 15 Transaction APIs ```js var u8 = new Uint8Array([1, 2, 3]) const valueBucket = { "name": "Tom", "age": 18, "salary": 100.5, "blobType": u8 } - let insertPromise = rdbStore.insert("test", valueBucket) + let insertPromise = rdbStoreV9.insert("test", valueBucket) ``` 3. Query data. - (1) Create an **RdbPredicates** object to specify query conditions. + (1) Create an **RdbPredicatesV9** object to specify query conditions. (2) Call the **query()** API to query data. @@ -258,17 +264,17 @@ Table 15 Transaction APIs The sample code is as follows: ```js - let predicates = new data_rdb.RdbPredicates("test"); - predicates.equalTo("name", "Tom") - let promisequery = rdbStore.query(predicates) - promisequery.then((resultSet) => { - resultSet.goToFirstRow() - const id = resultSet.getLong(resultSet.getColumnIndex("id")) - const name = resultSet.getString(resultSet.getColumnIndex("name")) - const age = resultSet.getLong(resultSet.getColumnIndex("age")) - const salary = resultSet.getDouble(resultSet.getColumnIndex("salary")) - const blobType = resultSet.getBlob(resultSet.getColumnIndex("blobType")) - resultSet.close() + let predicatesV9 = new data_rdb.RdbPredicatesV9("test"); + predicatesV9.equalTo("name", "Tom") + let promisequery = rdbStoreV9.query(predicatesV9) + promisequery.then((resultSetV9) => { + resultSetV9.goToFirstRow() + const id = resultSetV9.getLong(resultSetV9.getColumnIndex("id")) + const name = resultSetV9.getString(resultSetV9.getColumnIndex("name")) + const age = resultSetV9.getLong(resultSetV9.getColumnIndex("age")) + const salary = resultSetV9.getDouble(resultSetV9.getColumnIndex("salary")) + const blobType = resultSetV9.getBlob(resultSetV9.getColumnIndex("blobType")) + resultSetV9.close() }) ``` @@ -296,7 +302,7 @@ Table 15 Transaction APIs context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) { console.info(`result.requestCode=${result.requestCode}`) }) - let promise = rdbStore.setDistributedTables(["test"]) + let promise = rdbStoreV9.setDistributedTables(["test"]) promise.then(() => { console.info("setDistributedTables success.") }).catch((err) => { @@ -306,7 +312,7 @@ Table 15 Transaction APIs 5. Synchronize data across devices. - (1) Construct an **RdbPredicates** object to specify remote devices within the network to be synchronized. + (1) Construct an **RdbPredicatesV9** object to specify remote devices within the network to be synchronized. (2) Call **rdbStore.sync()** to synchronize data. @@ -315,9 +321,9 @@ Table 15 Transaction APIs The sample code is as follows: ```js - let predicate = new data_rdb.RdbPredicates('test') - predicate.inDevices(['12345678abcde']) - let promise = rdbStore.sync(data_rdb.SyncMode.SYNC_MODE_PUSH, predicate) + let predicateV9 = new data_rdb.RdbPredicatesV9('test') + predicateV9.inDevices(['12345678abcde']) + let promise = rdbStoreV9.sync(data_rdb.SyncMode.SYNC_MODE_PUSH, predicateV9) promise.then((result) => { console.log('sync done.') for (let i = 0; i < result.length; i++) { @@ -342,9 +348,9 @@ Table 15 Transaction APIs console.log('device=' + device[i] + 'data changed') } } - + try { - rdbStore.on('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, storeObserver) + rdbStoreV9.on('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, storeObserver) } catch (err) { console.log('register observer failed') } @@ -359,8 +365,8 @@ Table 15 Transaction APIs The sample code is as follows: ```js - let tableName = rdbStore.obtainDistributedTableName(deviceId, "test"); - let resultSet = rdbStore.querySql("SELECT * FROM " + tableName) + let tableName = rdbStoreV9.obtainDistributedTableName(deviceId, "test"); + let resultSetV9 = rdbStoreV9.querySql("SELECT * FROM " + tableName) ``` 8. Query data of a remote device. @@ -373,17 +379,17 @@ Table 15 Transaction APIs The sample code is as follows: ```js - let rdbPredicate = new data_rdb.RdbPredicates('employee') - predicates.greaterThan("id", 0) - let promiseQuery = rdbStore.remoteQuery('12345678abcde', 'employee', rdbPredicate) - promiseQuery.then((resultSet) => { - while (resultSet.goToNextRow()) { - let idx = resultSet.getLong(0); - let name = resultSet.getString(1); - let age = resultSet.getLong(2); + let rdbPredicateV9 = new data_rdb.RdbPredicatesV9('employee') + predicatesV9.greaterThan("id", 0) + let promiseQuery = rdbStoreV9.remoteQuery('12345678abcde', 'employee', rdbPredicateV9) + promiseQuery.then((resultSetV9) => { + while (resultSetV9.goToNextRow()) { + let idx = resultSetV9.getLong(0); + let name = resultSetV9.getString(1); + let age = resultSetV9.getLong(2); console.info(idx + " " + name + " " + age); } - resultSet.close(); + resultSetV9.close(); }).catch((err) => { console.info("failed to remoteQuery, err: " + err) }) @@ -396,7 +402,7 @@ Table 15 Transaction APIs The sample code is as follows: ```js - let promiseBackup = rdbStore.backup("dbBackup.db") + let promiseBackup = rdbStoreV9.backup("dbBackup.db") promiseBackup.then(() => { console.info('Backup success.') }).catch((err) => { @@ -408,7 +414,7 @@ Table 15 Transaction APIs The sample code is as follows: ```js - let promiseRestore = rdbStore.restore("dbBackup.db") + let promiseRestore = rdbStoreV9.restore("dbBackup.db") promiseRestore.then(() => { console.info('Restore success.') }).catch((err) => { diff --git a/en/application-dev/device-usage-statistics/Readme-EN.md b/en/application-dev/device-usage-statistics/Readme-EN.md index 75cfad35e1f36bfe07f0cb408c936f87e0ee520a..ccdf5a72d692b5e5e62a906819de1d6681ccfacf 100644 --- a/en/application-dev/device-usage-statistics/Readme-EN.md +++ b/en/application-dev/device-usage-statistics/Readme-EN.md @@ -1,4 +1,5 @@ # Device Usage Statistics - [Device Usage Statistics Overview](device-usage-statistics-overview.md) -- [Device Usage Statistics Development](device-usage-statistics-dev-guide.md) +- [Device Usage Statistics Development](device-usage-statistics-use-guide.md) + diff --git a/en/application-dev/device-usage-statistics/device-usage-statistics-dev-guide.md b/en/application-dev/device-usage-statistics/device-usage-statistics-dev-guide.md deleted file mode 100644 index 60aa41fedd15531c583c48200eddc3c91e5a8fde..0000000000000000000000000000000000000000 --- a/en/application-dev/device-usage-statistics/device-usage-statistics-dev-guide.md +++ /dev/null @@ -1,440 +0,0 @@ -# Device Usage Statistics Development - -## When to Use - -With device usage statistics APIs, you can have a better understanding of the application, notification, and system usage. For example, in application usage statistics, you can query the application usage, event log, and bundle group. -The application records (usage history statistics and event records) cached by components are updated to the database for persistent storage within 30 minutes after an event is reported. - -## Available APIs -Import the **stats** package to implement registration: -```js -import stats from '@ohos.bundleState'; -``` - -**Table 1** Major APIs for device usage statistics - -| API| Description| -| -------- | -------- | -| function queryBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void | Queries events of all applications based on the specified start time and end time.| -| function queryBundleStateInfos(begin: number, end: number, callback: AsyncCallback<BundleActiveInfoResponse>): void | Queries the application usage duration statistics based on the specified start time and end time.| -| function queryCurrentBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void | Queries events of this application based on the specified start time and end time.| -| function queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback<Array<BundleStateInfo>>): void | Queries the application usage duration statistics in the specified time frame at the specified interval (daily, weekly, monthly, or annually).| -| function queryAppUsagePriorityGroup(callback: AsyncCallback<number>): void | Queries the priority group of this application. This API uses an asynchronous callback to return the result.| -| function queryAppUsagePriorityGroup(): Promise<number>; | Queries the priority group of this application. This API uses a promise to return the result.| -| function isIdleState(bundleName: string, callback: AsyncCallback<boolean>): void | Checks whether the application specified by **bundleName** is in the idle state. | -| function getRecentlyUsedModules(callback: AsyncCallback<BundleActiveModuleInfo>): void | Obtains a maximum of 1000 FA usage records. | -| function getRecentlyUsedModules(maxNum: number, callback: AsyncCallback<BundleActiveModuleInfo>): void | Obtains the number of FA usage records specified by **maxNum**, which cannot exceed 1000.| -| function queryAppNotificationNumber(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveEventState>>): void | Queries the number of notifications from all applications based on the specified start time and end time.| -| function queryBundleActiveEventStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveEventState>>): void | Queries statistics about system events (hibernation, wakeup, unlocking, and screen locking) that occur between the specified start time and end time.| -| function queryAppUsagePriorityGroup(bundleName : string, callback: AsyncCallback<number>): void | Queries the priority group of the application specified by **bundleName**. This API uses an asynchronous callback to return the result.| -| function queryAppUsagePriorityGroup(bundleName? : string): Promise<number>; | Queries the priority group of the application specified by **bundleName**. If **bundleName** is not specified, the priority group of the current application is queried. This API uses a promise to return the result.| -| function setBundleGroup(bundleName : string, newGroup: GroupType, callback: AsyncCallback>boolean>): void | Sets the group for the application specified by **bundleName**. This API uses an asynchronous callback to return the result.| -| function setBundleGroup(bundleName : string, newGroup : GroupType): Promise>boolean>; | Sets the group for the application specified by **bundleName**. This API uses a promise to return the result.| -| function registerGroupCallBack(groupCallback: Callback>BundleActiveGroupCallbackInfo>, callback: AsyncCallback>boolean>): void | Registers a callback for application group changes. When an application group of the user changes, the change is returned to all applications that have registered the callback. This API uses an asynchronous callback to return the result.| -| function registerGroupCallBack(groupCallback: Callback>BundleActiveGroupCallbackInfo>): Promise>boolean>; | Registers a callback for application group changes. When an application group of the user changes, the change is returned to all applications that have registered the callback. This API uses a promise to return the result.| -| function unRegisterGroupCallBack(callback: AsyncCallback>boolean>): void | Deregisters the callback for application group changes. This API uses an asynchronous callback to return the result.| -| function unRegisterGroupCallBack(): Promise>boolean>; | Deregisters the callback for application group changes. This API uses a promise to return the result.| - -## How to Develop - -1. Configure the device usage statistics permission in the **config.json** file. - - ```json - "module": { - "package": "com.example.deviceUsageStatistics", - ..., - "reqPermissions": [ - { - "name": "ohos.permission.BUNDLE_ACTIVE_INFO" - } - ] - } - ``` - -2. Query events of all applications based on the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryBundleActiveStates(0, 20000000000000).then(res => { - console.log('BUNDLE_ACTIVE queryBundleActiveStates promise success.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE queryBundleActiveStates promise number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE queryBundleActiveStates promise result ' + JSON.stringify(res[i])); - } - }).catch(err => { - console.log('BUNDLE_ACTIVE queryBundleActiveStates promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.queryBundleActiveStates(0, 20000000000000, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryBundleActiveStates callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryBundleActiveStates callback success.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE queryBundleActiveStates callback number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE queryBundleActiveStates callback result ' + JSON.stringify(res[i])); - } - } - }); - ``` - -3. Query the application usage duration statistics based on the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryBundleStateInfos(0, 20000000000000).then(res => { - console.log('BUNDLE_ACTIVE queryBundleStateInfos promise success.'); - let i = 1; - for (let key in res){ - console.log('BUNDLE_ACTIVE queryBundleStateInfos promise number : ' + i); - console.log('BUNDLE_ACTIVE queryBundleStateInfos promise result ' + JSON.stringify(res[key])); - i++; - } - }).catch(err => { - console.log('BUNDLE_ACTIVE queryBundleStateInfos promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.queryBundleStateInfos(0, 20000000000000, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryBundleStateInfos callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryBundleStateInfos callback success.'); - let i = 1; - for(let key in res){ - console.log('BUNDLE_ACTIVE queryBundleStateInfos callback number : ' + i); - console.log('BUNDLE_ACTIVE queryBundleStateInfos callback result ' + JSON.stringify(res[key])); - i++; - } - } - }); - ``` - -4. Query events of this application based on the specified start time and end time. This requires no permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryCurrentBundleActiveStates(0, 20000000000000).then(res => { - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise success.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise result ' + JSON.stringify(res[i])); - } - }).catch(err => { - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.queryCurrentBundleActiveStates(0, 20000000000000, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback success.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback result ' + JSON.stringify(res[i])); - } - } - }); - ``` - -5. Query the application usage duration statistics in the specified time frame at the specified interval (daily, weekly, monthly, or annually). This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryBundleStateInfoByInterval(0, 0, 20000000000000).then(res => { - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise success.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise result ' + JSON.stringify(res[i])); - } - }).catch(err => { - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.queryBundleStateInfoByInterval(0, 0, 20000000000000, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback success.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback result ' + JSON.stringify(res[i])); - } - } - }); - ``` - -6. Query the priority group of the current application. This requires no permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryAppUsagePriorityGroup().then(res => { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise succeeded. result: ' + JSON.stringify(res)); - }).catch(err => { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failed. because: ' + err.code); - }); - - // Callback mode - stats.queryAppUsagePriorityGroup((err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failed. because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback succeeded. result: ' + JSON.stringify(res)); - } - }); - ``` - -7. Check whether the application specified by **bundleName** is in the idle state. This requires no permission to be configured in the **config.json** file. A third-party application can only check the idle status of itself. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.isIdleState("com.ohos.camera").then(res => { - console.log('BUNDLE_ACTIVE isIdleState promise succeeded, result: ' + JSON.stringify(res)); - }).catch(err => { - console.log('BUNDLE_ACTIVE isIdleState promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.isIdleState("com.ohos.camera", (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE isIdleState callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE isIdleState callback succeeded, result: ' + JSON.stringify(res)); - } - }); - ``` - -8. Obtain the number of FA usage records specified by **maxNum**. If **maxNum** is not specified, the default value **1000** is used. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.getRecentlyUsedModules(1000).then(res => { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise succeeded'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise result ' + JSON.stringify(res[i])); - } - }).catch(err=> { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise failed, because: ' + err.code); - }); - - // Promise mode when maxNum is not specified - stats.getRecentlyUsedModules().then(res => { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise succeeded'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise result ' + JSON.stringify(res[i])); - } - }).catch( err=> { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.getRecentlyUsedModules(1000, (err, res) => { - if(err) { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback succeeded.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback result ' + JSON.stringify(res[i])); - } - } - }); - - // Asynchronous callback mode when maxNum is not specified - stats.getRecentlyUsedModules((err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback succeeded.'); - for (let i = 0; i < res.length; i++) { - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback number : ' + (i + 1)); - console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback result ' + JSON.stringify(res[i])); - } - } - }); - ``` - -9. Query the number of notifications from all applications based on the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryAppNotificationNumber(0, 20000000000000).then(res => { - console.log('BUNDLE_ACTIVE queryAppNotificationNumber promise success.'); - console.log('BUNDLE_ACTIVE queryAppNotificationNumber promise result ' + JSON.stringify(res)); - }).catch(err => { - console.log('BUNDLE_ACTIVE queryAppNotificationNumber promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.queryAppNotificationNumber(0, 20000000000000, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryAppNotificationNumber callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryAppNotificationNumber callback success.'); - console.log('BUNDLE_ACTIVE queryAppNotificationNumber callback result ' + JSON.stringify(res)); - } - }); - ``` - -10. Query statistics about system events (hibernation, wakeup, unlocking, and screen locking) that occur between the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode - stats.queryBundleActiveEventStates(0, 20000000000000).then(res => { - console.log('BUNDLE_ACTIVE queryBundleActiveEventStates promise success.'); - console.log('BUNDLE_ACTIVE queryBundleActiveEventStates promise result ' + JSON.stringify(res)); - }).catch(err => { - console.log('BUNDLE_ACTIVE queryBundleActiveEventStates promise failed, because: ' + err.code); - }); - - // Asynchronous callback mode - stats.queryBundleActiveEventStates(0, 20000000000000, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryBundleActiveEventStates callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryBundleActiveEventStates callback success.'); - console.log('BUNDLE_ACTIVE queryBundleActiveEventStates callback result ' + JSON.stringify(res)); - } - }); - ``` - -11. Query the priority group of the current application. This requires no permission to be configured in the **config.json** file. Query the priority group of a specified application. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured in the **config.json** file. - - ```js - import stats from '@ohos.bundleState' - - // Promise mode when bundleName is not specified - stats.queryAppUsagePriorityGroup().then(res => { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise succeeded. result: ' + JSON.stringify(res)); - }).catch(err => { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failed. because: ' + err.code); - }); - - // Asynchronous callback mode when bundleName is not specified - stats.queryAppUsagePriorityGroup((err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failed. because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback succeeded. result: ' + JSON.stringify(res)); - } - }); - let bundleName = "com.ohos.camera"; - // Promise mode when bundleName is specified - stats.queryAppUsagePriorityGroup(bundleName).then(res => { - console.log('BUNDLE_ACTIVE QueryPackageGroup promise succeeded. result: ' + JSON.stringify(res)); - }).catch(err => { - console.log('BUNDLE_ACTIVE QueryPackageGroup promise failed. because: ' + err.code); - }); - - // Asynchronous callback mode when bundleName is specified - stats.queryAppUsagePriorityGroup(bundleName, (err, res) => { - if (err) { - console.log('BUNDLE_ACTIVE QueryPackageGroup callback failed. because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE QueryPackageGroup callback succeeded. result: ' + JSON.stringify(res)); - } - }); - ``` - -11. Set the group for the application specified by **bundleName**. - - ```javascript - import stats from '@ohos.bundleState' - - // Promise mode - stats.setBundleGroup(this.bundleName, this.newGroup).then(() => { - console.log('BUNDLE_ACTIVE SetBundleGroup promise succeeded.'); - }).catch( err => { - console.log('BUNDLE_ACTIVE SetBundleGroup promise failed. because: ' + err.code); - }); - // Asynchronous callback mode - stats.setBundleGroup(this.bundleName, this.newGroup, (err) => { - if (err) { - console.log('BUNDLE_ACTIVE SetBundleGroup callback failed. because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE SetBundleGroup callback succeeded.'); - } - }); - ``` - -12. Register a callback for application group changes. When an application group of the user changes, the change is returned to all applications that have registered the callback. - - ```javascript - import stats from '@ohos.bundleState' - - // Promise mode - let onBundleGroupChanged = (err,res) => { - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack callback success.'); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result oldGroup is : ' + res.oldGroup); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result newGroup is : ' + res.newGroup); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result changeReason is : ' + res.newGroup); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result userId is : ' + res.userId); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result bundleName is : ' + res.bundleName); - }; - stats.registerGroupCallBack(onBundleGroupChanged).then(() => { - console.log('BUNDLE_ACTIVE RegisterGroupCallBack promise succeeded.'); - }).catch(err => { - console.log('BUNDLE_ACTIVE RegisterGroupCallBack promise failed. because: ' + err.code); - }); - // Asynchronous callback mode - let onBundleGroupChanged = (err,res) => { - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack callback success.'); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result's oldGroup is : ' + res.oldGroup); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result's newGroup is : ' + res.newGroup); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result's changeReason is : ' + res.newGroup); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result's userId is : ' + res.userId); - console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result's bundleName is : ' + res.bundleName); - }; - stats.registerGroupCallBack(onBundleGroupChanged, (err) => { - if (err) { - console.log('BUNDLE_ACTIVE RegisterGroupCallBack callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE RegisterGroupCallBack callback success.'); - } - }); - ``` - -13. Deregister the callback for application group changes. - - ```javascript - import stats from '@ohos.bundleState' - - // Promise mode - stats.unRegisterGroupCallBack().then(() => { - console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack promise succeeded.'); - }).catch(err => { - console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack promise failed. because: ' + err.code); - }); - // Asynchronous callback mode - stats.unRegisterGroupCallBack((err) => { - if (err) { - console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack callback failed, because: ' + err.code); - } else { - console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack callback success.'); - } - }); - ``` - diff --git a/en/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md b/en/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md new file mode 100644 index 0000000000000000000000000000000000000000..45255f18ee313ad96d072e42f620b219315a8adf --- /dev/null +++ b/en/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md @@ -0,0 +1,534 @@ +# Device Usage Statistics Development (API Version 9) + +## When to Use + +With device usage statistics APIs, you can have a better understanding of the application, notification, and system usage. For example, in application usage statistics, you can query the application usage, event log, and application group. +The application records (usage history statistics and event records) cached by components are updated to the database for persistent storage within 30 minutes after an event is reported. + +## Available APIs +Import the **stats** package to implement registration: +```js +import usageStatistics from '@ohos.resourceschedule.usageStatistics'; +``` + +**Table 1** Major APIs for device usage statistics + +| API| Description| +| -------- | -------- | +| function queryBundleEvents(begin: number, end: number, callback: AsyncCallback<Array<BundleEvents>>): void | Queries events of all applications based on the specified start time and end time.| +| function queryBundleStatsInfos(begin: number, end: number, callback: AsyncCallback<BundleStatsMap>): void | Queries the application usage duration statistics based on the specified start time and end time.| +| function queryCurrentBundleEvents(begin: number, end: number, callback: AsyncCallback<Array<BundleEvents>>): void | Queries events of this application based on the specified start time and end time.| +| function queryBundleStatsInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback<Array<BundleStatsInfo>>): void | Queries the application usage duration statistics in the specified time frame at the specified interval (daily, weekly, monthly, or annually).| +| function queryAppGroup(callback: AsyncCallback<number>): void | Queries the priority group of this application. This API uses an asynchronous callback to return the result.| +| function queryAppGroup(): Promise<number>; | Queries the priority group of this application. This API uses a promise to return the result.| +| function queryAppGroup(bundleName : string, callback: AsyncCallback<number>): void | Queries the priority group of the application specified by **bundleName**. This API uses an asynchronous callback to return the result.| +| function queryAppGroup(bundleName : string): Promise<number>; | Queries the priority group of the application specified by **bundleName**. If **bundleName** is not specified, the priority group of the current application is queried. This API uses a promise to return the result.| +| function isIdleState(bundleName: string, callback: AsyncCallback<boolean>): void | Checks whether the application specified by **bundleName** is in the idle state. | +| function queryModuleUsageRecords(callback: AsyncCallback<HapModuleInfo>): void | Obtains a maximum of 1000 FA usage records.| +| function queryModuleUsageRecords(maxNum: number, callback: AsyncCallback<HapModuleInfo>): void | Obtains the number of FA usage records specified by **maxNum**, which cannot exceed 1000.| +| function queryNotificationEventStats(begin: number, end: number, callback: AsyncCallback<Array<DeviceEventStats>>): void | Queries the number of notifications from all applications based on the specified start time and end time.| +| function queryDeviceEventStats(begin: number, end: number, callback: AsyncCallback<Array<DeviceEventStats>>): void | Queries statistics about system events (hibernation, wakeup, unlocking, and screen locking) that occur between the specified start time and end time.| +| function setAppGroup(bundleName : string, newGroup: GroupType, callback: AsyncCallback>boolean>): void | Sets the group for the application specified by **bundleName**. This API uses an asynchronous callback to return the result.| +| function setAppGroup(bundleName : string, newGroup : GroupType): Promise>boolean>; | Sets the group for the application specified by **bundleName**. This API uses a promise to return the result.| +| function registerAppGroupCallBack(groupCallback: Callback>AppGroupCallbackInfo>, callback: AsyncCallback>boolean>): void | Registers a callback for application group changes. When an application group of the user changes, the change is returned to all applications that have registered the callback. This API uses an asynchronous callback to return the result.| +| function registerAppGroupCallBack(groupCallback: Callback>AppGroupCallbackInfo>): Promise>boolean>; | Registers a callback for application group changes. When an application group of the user changes, the change is returned to all applications that have registered the callback. This API uses a promise to return the result.| +| function unregisterAppGroupCallBack(callback: AsyncCallback>boolean>): void | Deregisters the callback for application group changes. This API uses an asynchronous callback to return the result.| +| function unregisterAppGroupCallBack(): Promise>boolean>; | Deregisters the callback for application group changes. This API uses a promise to return the result.| + +## How to Develop + +1. Before obtaining the device usage statistics, check whether the **ohos.permission.BUNDLE_ACTIVE_INFO** permission is configured. For details about how to configure a permission, see [Declaring Permissions](../security/accesstoken-guidelines.md). + +2. Query events of all applications based on the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryBundleEvents(0, 20000000000000).then( res => { + console.log('BUNDLE_ACTIVE queryBundleEvents promise success.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryBundleEvents promise number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryBundleEvents promise result ' + JSON.stringify(res[i])); + } + }).catch( err => { + console.log('BUNDLE_ACTIVE queryBundleEvents promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryBundleEvents throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryBundleEvents(0, 20000000000000, (err, res) => { + if (err) { + console.log('BUNDLE_ACTIVE queryBundleEvents callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryBundleEvents callback success.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryBundleEvents callback number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryBundleEvents callback result ' + JSON.stringify(res[i])); + } + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryBundleEvents throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +3. Query the application usage duration statistics based on the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryBundleStatsInfos(0, 20000000000000).then( res => { + console.log('BUNDLE_ACTIVE queryBundleStatsInfos promise success.'); + let i = 1; + for(let key in res){ + console.log('BUNDLE_ACTIVE queryBundleStatsInfos promise number : ' + i); + console.log('BUNDLE_ACTIVE queryBundleStatsInfos promise result ' + JSON.stringify(res[key])); + i++; + } + }).catch( err => { + console.log('BUNDLE_ACTIVE queryBundleStatsInfos promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfos throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryBundleStatsInfos(0, 20000000000000, (err, res) => { + if (err) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfos callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryBundleStatsInfos callback success.'); + let i = 1; + for(let key in res){ + console.log('BUNDLE_ACTIVE queryBundleStatsInfos callback number : ' + i); + console.log('BUNDLE_ACTIVE queryBundleStatsInfos callback result ' + JSON.stringify(res[key])); + i++; + } + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfos throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +4. Query events of this application based on the specified start time and end time. This requires no permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryCurrentBundleEvents(0, 20000000000000).then( res => { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents promise success.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents promise number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents promise result ' + JSON.stringify(res[i])); + } + }).catch( err => { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryCurrentBundleEvents(0, 20000000000000, (err, res) => { + if (err) { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents callback success.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents callback number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents callback result ' + JSON.stringify(res[i])); + } + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryCurrentBundleEvents throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +5. Query the application usage duration statistics in the specified time frame at the specified interval (daily, weekly, monthly, or annually). This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryBundleStatsInfoByInterval(0, 0, 20000000000000).then( res => { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval promise success.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval promise number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval promise result ' + JSON.stringify(res[i])); + } + }).catch( err => { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryBundleStatsInfoByInterval(0, 0, 20000000000000, (err, res) => { + if (err) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval callback success.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval callback number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval callback result ' + JSON.stringify(res[i])); + } + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryBundleStatsInfoByInterval throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +6. Query the priority group of the current application. This requires no permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryAppGroup().then( res => { + console.log('BUNDLE_ACTIVE queryAppGroup promise succeeded. result: ' + JSON.stringify(res)); + }).catch( err => { + console.log('BUNDLE_ACTIVE queryAppGroup promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryAppGroup throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Callback mode + try{ + usageStatistics.queryAppGroup((err, res) => { + if(err) { + console.log('BUNDLE_ACTIVE queryAppGroup callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryAppGroup callback succeeded. result: ' + JSON.stringify(res)); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryAppGroup throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +7. Check whether the application specified by **bundleName** is in the idle state. This requires no permission to be configured. A third-party application can only check the idle status of itself. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.isIdleState("com.ohos.camera").then( res => { + console.log('BUNDLE_ACTIVE isIdleState promise succeeded, result: ' + JSON.stringify(res)); + }).catch( err => { + console.log('BUNDLE_ACTIVE isIdleState promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE isIdleState throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.isIdleState("com.ohos.camera", (err, res) => { + if (err) { + console.log('BUNDLE_ACTIVE isIdleState callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE isIdleState callback succeeded, result: ' + JSON.stringify(res)); + } + }); + } catch(error) { + console.log('BUNDLE_ACTIVE isIdleState throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +8. Obtain the number of FA usage records specified by **maxNum**. If **maxNum** is not specified, the default value **1000** is used. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryModuleUsageRecords(1000).then( res => { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise succeeded'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise result ' + JSON.stringify(res[i])); + } + }).catch( err=> { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Promise mode when maxNum is not specified + try{ + usageStatistics.queryModuleUsageRecords().then( res => { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise succeeded'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise result ' + JSON.stringify(res[i])); + } + }).catch( err=> { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryModuleUsageRecords(1000, (err, res) => { + if(err) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback succeeded.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback result ' + JSON.stringify(res[i])); + } + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode when maxNum is not specified + try{ + usageStatistics.queryModuleUsageRecords((err, res) => { + if(err) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback succeeded.'); + for (let i = 0; i < res.length; i++) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback number : ' + (i + 1)); + console.log('BUNDLE_ACTIVE queryModuleUsageRecords callback result ' + JSON.stringify(res[i])); + } + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryModuleUsageRecords throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +9. Query the number of notifications from all applications based on the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryNotificationEventStats(0, 20000000000000).then( res => { + console.log('BUNDLE_ACTIVE queryNotificationEventStats promise success.'); + console.log('BUNDLE_ACTIVE queryNotificationEventStats promise result ' + JSON.stringify(res)); + }).catch( err=> { + console.log('BUNDLE_ACTIVE queryNotificationEventStats promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryNotificationEventStats throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryNotificationEventStats(0, 20000000000000, (err, res) => { + if(err) { + console.log('BUNDLE_ACTIVE queryNotificationEventStats callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryNotificationEventStats callback success.'); + console.log('BUNDLE_ACTIVE queryNotificationEventStats callback result ' + JSON.stringify(res)); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryNotificationEventStats throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +10. Query statistics about system events (hibernation, wakeup, unlocking, and screen locking) that occur between the specified start time and end time. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + try{ + usageStatistics.queryDeviceEventStats(0, 20000000000000).then( res => { + console.log('BUNDLE_ACTIVE queryDeviceEventStates promise success.'); + console.log('BUNDLE_ACTIVE queryDeviceEventStates promise result ' + JSON.stringify(res)); + }).catch( err=> { + console.log('BUNDLE_ACTIVE queryDeviceEventStats promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryDeviceEventStats throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + try{ + usageStatistics.queryDeviceEventStats(0, 20000000000000, (err, res) => { + if(err) { + console.log('BUNDLE_ACTIVE queryDeviceEventStats callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryDeviceEventStats callback success.'); + console.log('BUNDLE_ACTIVE queryDeviceEventStats callback result ' + JSON.stringify(res)); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryDeviceEventStats throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +11. Query the priority group of the application specified by **bundleName**. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```js + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode when bundleName is specified + let bundleName = "com.ohos.camera"; + try{ + usageStatistics.queryAppGroup(bundleName).then( res => { + console.log('BUNDLE_ACTIVE queryAppGroup promise succeeded. result: ' + JSON.stringify(res)); + }).catch( err => { + console.log('BUNDLE_ACTIVE queryAppGroup promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryAppGroup throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode when bundleName is specified + let bundleName = "com.ohos.camera"; + try{ + usageStatistics.queryAppGroup(bundleName, (err, res) => { + if(err) { + console.log('BUNDLE_ACTIVE queryAppGroup callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE queryAppGroup callback succeeded. result: ' + JSON.stringify(res)); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE queryAppGroup throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +12. Set the priority group of for application specified by **bundleName**. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```javascript + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + let bundleName = "com.example.deviceUsageStatistics"; + let newGroup = bundleState.GroupType.ACTIVE_GROUP_DAILY; + + try{ + usageStatistics.setAppGroup(bundleName, newGroup).then( () => { + console.log('BUNDLE_ACTIVE setAppGroup promise succeeded.'); + }).catch( err => { + console.log('BUNDLE_ACTIVE setAppGroup promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE setAppGroup throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + let bundleName = "com.example.deviceUsageStatistics"; + let newGroup = bundleState.GroupType.ACTIVE_GROUP_DAILY; + + try{ + usageStatistics.setAppGroup(bundleName, newGroup, (err) => { + if(err) { + console.log('BUNDLE_ACTIVE setAppGroup callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE setAppGroup callback succeeded.'); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE setAppGroup throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +13. Register a callback for application group changes. When an application group of the user changes, the change is returned to all applications that have registered the callback. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```javascript + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // Promise mode + let onBundleGroupChanged = (res) =>{ + console.log('BUNDLE_ACTIVE registerAppGroupCallBack RegisterGroupCallBack callback success.'); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result appOldGroup is : ' + res.appOldGroup); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result appNewGroup is : ' + res.appNewGroup); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result changeReason is : ' + res.changeReason); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result userId is : ' + res.userId); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result bundleName is : ' + res.bundleName); + }; + try{ + usageStatistics.registerAppGroupCallBack(onBundleGroupChanged).then( () => { + console.log('BUNDLE_ACTIVE registerAppGroupCallBack promise succeeded.'); + }).catch( err => { + console.log('BUNDLE_ACTIVE registerAppGroupCallBack promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE registerAppGroupCallBack throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // Asynchronous callback mode + let onBundleGroupChanged = (err, res) =>{ + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack callback success.'); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result appOldGroup is : ' + res.appOldGroup); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result appNewGroup is : ' + res.appNewGroup); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result changeReason is : ' + res.changeReason); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result userId is : ' + res.userId); + console.log('BUNDLE_ACTIVE registerAppGroupCallBack result bundleName is : ' + res.bundleName); + }; + try{ + usageStatistics.registerAppGroupCallBack(onBundleGroupChanged, err => { + if(err) { + console.log('BUNDLE_ACTIVE registerAppGroupCallBack callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE registerAppGroupCallBack callback success.'); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE registerAppGroupCallBack throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` + +14. Deregister the callback for application group changes. This requires the **ohos.permission.BUNDLE_ACTIVE_INFO** permission to be configured. + + ```javascript + import usageStatistics from '@ohos.resourceschedule.usageStatistics' + + // promise + try{ + usageStatistics.unregisterAppGroupCallBack().then( () => { + console.log('BUNDLE_ACTIVE unregisterAppGroupCallBack promise succeeded.'); + }).catch( err => { + console.log('BUNDLE_ACTIVE unregisterAppGroupCallBack promise failed. code is: ' + err.code + ',message is: ' + err.message); + }); + } catch (error) { + console.log('BUNDLE_ACTIVE unregisterAppGroupCallBack throw error, code is: ' + error.code + ',message is: ' + error.message); + } + + // callback + try{ + usageStatistics.unregisterAppGroupCallBack(err => { + if(err) { + console.log('BUNDLE_ACTIVE unregisterAppGroupCallBack callback failed. code is: ' + err.code + ',message is: ' + err.message); + } else { + console.log('BUNDLE_ACTIVE unregisterAppGroupCallBack callback success.'); + } + }); + } catch (error) { + console.log('BUNDLE_ACTIVE unregisterAppGroupCallBack throw error, code is: ' + error.code + ',message is: ' + error.message); + } + ``` \ No newline at end of file diff --git a/en/application-dev/device/usb-guidelines.md b/en/application-dev/device/usb-guidelines.md index eb023f7c782d8cb0e086819904b6def65da14214..768866b4974eb59a81aa3d17f9d099d03fbdc415 100644 --- a/en/application-dev/device/usb-guidelines.md +++ b/en/application-dev/device/usb-guidelines.md @@ -2,7 +2,7 @@ ## When to Use -In Host mode, you can obtain the list of connected devices, enable or disable the devices, manage device access permissions, and perform data transfer or control transfer. +In Host mode, you can obtain the list of connected USB devices, enable or disable the devices, manage device access permissions, and perform data transfer or control transfer. ## APIs @@ -16,6 +16,7 @@ The following table lists the USB APIs currently available. For details, see the | ------------------------------------------------------------ | ------------------------------------------------------------ | | hasRight(deviceName: string): boolean | Checks whether the user, for example, the application or system, has the device access permissions. The value **true** is returned if the user has the device access permissions; the value **false** is returned otherwise. | | requestRight(deviceName: string): Promise\ | Requests the temporary permission for a given application to access the USB device. | +| removeRight(deviceName: string): boolean | Removes the permission for a given application to access the USB device. | | connectDevice(device: USBDevice): Readonly\ | Connects to the USB device based on the device information returned by `getDevices()`. | | getDevices(): Array> | Obtains the USB device list. | | setConfiguration(pipe: USBDevicePipe, config: USBConfig): number | Sets the USB device configuration. | diff --git a/en/application-dev/dfx/hiappevent-guidelines.md b/en/application-dev/dfx/hiappevent-guidelines.md index afda67ee6fdf21b3d91d525d397c956d98167e82..067b9b8c915417b93340ab55bf34a74bca422a3d 100644 --- a/en/application-dev/dfx/hiappevent-guidelines.md +++ b/en/application-dev/dfx/hiappevent-guidelines.md @@ -8,7 +8,7 @@ The event logging function helps applications log various information generated JS application event logging APIs are provided by the **hiAppEvent** module. -The following table provides only a brief description of related APIs. For details, see [HiAppEvent](../reference/apis/js-apis-hiappevent.md). +The following table provides only a brief description of related APIs. For details, see [HiAppEvent](../reference/apis/js-apis-hiviewdfx-hiappevent.md). **Table 1** APIs for application event logging @@ -17,17 +17,11 @@ The following table provides only a brief description of related APIs. For detai | write(AppEventInfo info, AsyncCallback\ callback): void | Logs application events in asynchronous mode. This API uses an asynchronous callback to return the result.| | write(AppEventInfo info): Promise\ | Logs application events in asynchronous mode. This API uses a promise to return the result. | -When an asynchronous callback is used, the return value can be processed directly in the callback. - -If a promise is used, the return value can also be processed in the promise in a similar way. - -For details about the result codes, see [Event Verification Result Codes](#event-verification-result-codes). - **Table 2** APIs for event logging configuration -| API | Description | -| --------------------------------------- | ---------------------------------------------------- | -| configure(ConfigOption config): boolean | Sets the configuration options for application event logging.| +| API | Description | +| ------------------------------------ | ---------------------------------------------------- | +| configure(ConfigOption config): void | Sets the configuration options for application event logging.| **Table 3** APIs for watcher management @@ -42,32 +36,14 @@ For details about the result codes, see [Event Verification Result Codes](#event | ----------------- | -------------------- | | clearData(): void | Clears local logging data.| -### Event Verification Result Codes - -| Result Code| Cause | Verification Rules | Handling Method | -| ------ | ----------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- | -| 0 | N/A | Event verification is successful. | Event logging is normal. No action is required. | -| -1 | Invalid event name | The name is not empty and contains a maximum of 48 characters.
The name consists of only the following characters: digits (0 to 9), letters (a to z), and underscore \(_).
The name does not start with a digit or underscore \(_).| Ignore this event and do not perform logging. | -| -2 | Invalid event parameter type | The event name must be a string.
The event type must be a number.
The event parameter must be an object.| Ignore this event and do not perform logging. | -| -4 | Invalid event domain name | The name is not empty and contains a maximum of 32 characters.
The name consists of only the following characters: digits (0 to 9), letters (a to z), and underscore \(_).
The name does not start with a digit or underscore \(_).| Ignore this event and do not perform logging. | -| -99 | Application event logging disabled | Application event logging is disabled. | Ignore this event and do not perform logging. | -| -100 | Unknown error | None. | Ignore this event and do not perform logging. | -| 1 | Invalid key name | The name is not empty and contains a maximum of 16 characters.
The name consists of only the following characters: digits (0 to 9), letters (a to z), and underscore \(_).
The name does not start with a digit or underscore \(_).
The name does not end with an underscore \(_).| Ignore the key-value pair and continue to perform logging. | -| 2 | Invalid key type | The key must be a string. | Ignore the key-value pair and continue to perform logging. | -| 3 | Invalid value type | The supported value types vary depending on the programming language:
boolean, number, string, or Array [basic element]| Ignore the key-value pair and continue to perform logging. | -| 4 | Invalid length for values of the string type| For a value of the string type, the maximum length is 8*1024 characters. | Truncate the value with the first 8*1024 characters retained, and continue to perform logging.| -| 5 | Excess key-value pairs | The number of key-value pairs must be less than or equal to 32. | Ignore the excess key-value pairs and continue to perform logging. | -| 6 | Invalid number of elements in values of the array type | For a value of the array type, the number of elements must be less than or equal to 100. | Truncate the array with the first 100 elements retained, and continue to perform logging. | -| 7 | Invalid parameters in values of the array type | For a value of the array type, all the parameters must be of the same type, which can only be boolean, number, or string.| Ignore the key-value pair and continue to perform logging. | - -## Development Procedure +## How to Develop The following uses a one-time event watcher as an example to illustrate the development procedure. 1. Create an eTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **pages** > **index.ets**, and double-click **index.ets**. Then, add three buttons to simulate the process of watching for application events. Wherein, button 1 is used to invoke application event logging, button 2 to add an event watcher that automatically triggers a callback, and button 3 to remove the watcher. The complete sample code is as follows: ```ts - import hiAppEvent from '@ohos.hiAppEvent'; + import hiAppEvent from '@ohos.hiviewdfx.hiAppEvent'; @Entry @Component @@ -91,10 +67,10 @@ The following uses a one-time event watcher as an example to illustrate the deve int_data: 100, str_data: "strValue" } - }).then((value) => { - console.log(`HiAppEvent success to write event: ${value}`); + }).then(() => { + console.log(`HiAppEvent success to write event`); }).catch((err) => { - console.error(`HiAppEvent failed to write event because ${err.code}`); + console.error(`code: ${err.code}, message: ${err.message}`); }); }) @@ -120,12 +96,12 @@ The following uses a one-time event watcher as an example to illustrate the deve // Obtain the event package based on the configured size threshold. If returned event package is null, all event data has been obtained. while ((eventPkg = holder.takeNext()) != null) { // Parse the obtained event package and display the result on the Log page. - console.info('HiAppEvent eventPkg.packageId=' + eventPkg.packageId); - console.info('HiAppEvent eventPkg.row=' + eventPkg.row); - console.info('HiAppEvent eventPkg.size=' + eventPkg.size); + console.info(`HiAppEvent eventPkg.packageId=${eventPkg.packageId}`); + console.info(`HiAppEvent eventPkg.row=${eventPkg.row}`); + console.info(`HiAppEvent eventPkg.size=${eventPkg.size}`); // Traverse and parse event string arrays in the obtained event package. for (const eventInfo of eventPkg.data) { - console.info('HiAppEvent eventPkg.data=' + eventInfo); + console.info(`HiAppEvent eventPkg.data=${eventInfo}`); } } } @@ -169,4 +145,4 @@ The following uses a one-time event watcher as an example to illustrate the deve The following sample is provided to help you better understand how to develop the application event logging feature: -- [`JsDotTest` (JS) (API8)](https://gitee.com/openharmony/applications_app_samples/tree/master/DFX/JsDotTest) +- [`JsDotTest`: Event Logging (JS) (API8)](https://gitee.com/openharmony/applications_app_samples/tree/master/DFX/JsDotTest) diff --git a/en/application-dev/dfx/hiappevent-overview.md b/en/application-dev/dfx/hiappevent-overview.md index 088f3624b0c9638dd5137e1460b3cc832c290de9..2e54f28d8a69623accc2aff1b8dc96f30045f8ed 100644 --- a/en/application-dev/dfx/hiappevent-overview.md +++ b/en/application-dev/dfx/hiappevent-overview.md @@ -1,8 +1,8 @@ # Overview of Application Event Logging -HiAppEvent provides event logging APIs for applications to log the fault, statistical, security, and user behavior events reported during running. Based on event information, you will be able to analyze the running status of your application. +The HiAppEvent module provides event logging APIs for applications to log the fault, statistical, security, and user behavior events reported during running. Based on event information, you will be able to analyze the running status of your application. -The HiAppEvent module can be used to develop application event-related functions, including flushing application events to a disk and querying historical application events. +You can use this module to develop application event-related functions, including flushing application events to a disk, querying and clearing application events, and customizing application event logging configuration. ## Basic Concepts diff --git a/en/application-dev/faqs/Readme-EN.md b/en/application-dev/faqs/Readme-EN.md index c0b69b85a868f8afd7a7f627fb0275f46cbc87fc..37baff507755e5862045dfb3247324c6e80dcfdf 100644 --- a/en/application-dev/faqs/Readme-EN.md +++ b/en/application-dev/faqs/Readme-EN.md @@ -1,10 +1,12 @@ # FAQs - [Ability Framework Development](faqs-ability.md) -- [ArkUI (JavaScript) Development](faqs-ui-js.md) +- [Bundle Management Development](faqs-bundle.md) - [ArkUI (eTS) Development](faqs-ui-ets.md) +- [ArkUI (JavaScript) Development](faqs-ui-js.md) - [Graphics and Image Development](faqs-graphics.md) - [File Management Development](faqs-file-management.md) +- [Media Development](faqs-media.md) - [Network and Connection Development](faqs-connectivity.md) - [Data Management Development](faqs-data-management.md) - [Device Management Development](faqs-device-management.md) diff --git a/en/application-dev/faqs/faqs-ability.md b/en/application-dev/faqs/faqs-ability.md index 0cabbba71815d043e29f9c840c8ce7589af76dad..ed3cfcc4412379ea61974895ca111256b68ae696 100644 --- a/en/application-dev/faqs/faqs-ability.md +++ b/en/application-dev/faqs/faqs-ability.md @@ -4,7 +4,7 @@ Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 -A guide is available for the **DataShareExtensionAbility** class in the stage model, which provides APIs for sharing data with other applications and managing the data. +A guide is available for the **DataShareExtensionAbility** class, which provides APIs for sharing data with other applications and managing the data, in the stage model. Reference: [DataShare Development](../database/database-datashare-guidelines.md) @@ -20,6 +20,32 @@ Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 Reference: [Release Testing Version](https://gitee.com/openharmony-sig/oh-inner-release-management/blob/master/Release-Testing-Version.md) +## How do I set the UI of an ability to transparent? + +Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 + +Set the background color of the top container component to transparent, and then set the **opacity** attribute of the XComponent to **0.01**. + +Example: + +``` +build() { + Stack() { + XComponent({ + id: 'componentId', + type: 'surface', + }) + .width('100%') + .height('100%') + .opacity(0.01) + // Page content + } + .width('100%') + .height('100%') + .backgroundColor('rgba(255,255,255, 0)') +} +``` + ## How do I prevent "this" in a method from changing to "undefined" when the method is called? Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 @@ -36,7 +62,7 @@ Configure the **startWindowIcon** attribute under **abilities** in the **module. Reference: [Application Package Structure Configuration File](../quick-start/stage-structure.md) - Example: +Example: ``` { @@ -58,3 +84,133 @@ Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 Implement the **onConfigurationUpdated** callback in the **Ability** class. The callback is triggered when the system language, color mode, or display parameters (such as the orientation and density) change. Reference: [Ability Development](../ability/stage-ability.md) + +## Can I obtain the context through globalThis in the stage model? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +Do not use **globalThis** to obtain the context in the stage model. This is because all the processes of an application share a JS VM instance in the stage model. Multiple abilities can run on these processes and share the same global object. If **globalThis** is used, the context of different abilities of the same JS VM instance may be returned. + +For details about the recommended operation, see [Context in the Stage Model](../ability/context-userguide.md#context-in-the-stage-model). + +## How do I obtain the HAP file installation path of application B from application A? + +Applicable to: OpenHarmony SDK 3.0 or later, stage model of API version 9 + +First, request the system permission. For details, see [Having Your App Automatically Signed](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-auto-configuring-signature-information-0000001271659465). Then, import the **bundle** module, and call **bundle.getApplicationInfo()** to obtain application information based on the bundle name. Finally, use **application.moduleSourceDirs** to obtain the application storage path. + +## How is data returned when startAbilityForResult is called? + +Applicable to: OpenHarmony SDK3.0, stage model of API version 9 + +The callee uses **AbilityContext.terminateSelfWithResult** to destroy its ability and pass parameters to **startAbilityForResult**. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextterminateselfwithresult). + +## Can the lifecycle callback of a released FA widget be triggered when the widget is displayed in the service center so that the user login information can be obtained without opening the FA application? + +Applicable to: OpenHarmony SDK 3.2.5.5, FA model of API version 8 + +After a widget is added, the **onCreate()** lifecycle is triggered so that related user information (silent login) can be displayed even when the application is not started. However, users must manually add the widget after the application is installed. + +## How do I obtain the context? + +Applicable to: OpenHarmony SDK 3.2.7.5, stage model of API version 9 + +You can use **this.context** to obtain the context in the **MainAbility.ts** file or call **getContext(this)** to obtain the context on the component page. + +## What should I do when undefined is displayed for the calling of **abilityAccessCtrl.grantUserGrantedPermission** during API version 8 syntax verification? + +Applicable to: OpenHarmony SDK 3.0, FA model of API version 8 + +**abilityAccessCtrl.grantUserGrantedPermission** is a system API. It is not available in the public SDK, which is provided as default on DevEco Studio. To use system APIs, switch to the full SDK. For details, see [Guide to Switching to Full SDK](../quick-start/full-sdk-switch-guide.md). + +## Which of the following Extension abilities are available in the public SDK: ServiceExtensionAbility, FormExtensionAbility, and DataShareExtensionAbility? + +Applicable to: OpenHarmony SDK 3.2.5.6, stage model of API version 9 + +Among the aforementioned Extension abilities, only **FormExtensionAbility** is available in the public SDK. **ServiceExtensionAbility** and **DataShareExtensionAbility** are system APIs and available only in the full SDK. + +Public SDK: intended for application developers and does not contain system APIs that require system permissions. + +Full SDK: intended for original equipment manufacturers (OEMs) and contains system APIs that require system permissions. + +## Why can't I play GIF images cyclically on the widget? + +Applicable to: OpenHarmony SDK 3.2.5.6, stage model of API version 9 + +The system does not support the display of GIF images on the widget. + +## How do I implement service login by touching a widget? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +You can start an ability upon the touch and implement service login in the ability. + +## How do I redirect to the application details page in Settings? + +Applicable to: OpenHarmony SDK 3.2.6.5 + +Refer to the following code: + +``` +this.context.startAbility( +{ + action: "action.settings.app.info", + parameters: { "settingsParamBundleName": "your app bundlename" } +}) +``` + +## How do I listen for screen rotation events? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +Refer to the following code: + +``` +let listener = mediaquery.matchMediaSync('(orientation: landscape)') +onPortrait(mediaQueryResult) { +if (mediaQueryResult.matches) { +// Do something here. + } else { +// Do something here. + } +} +listener.on('change', onPortrait) +``` + +## How do I control the shadow background size during checkbox selection? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +Set the **padding** attribute of the **\** component to control the shadow size. + +## How do I set the widget background to transparent? + +Applicable to: OpenHarmony SDK 3.2.5.5 + +1. Create the **widget/resources/styles/default.json** file in the root directory of the widget. + +2. Add the following code to the **default.json** file: + +``` +{ + "style": { + "app_background": "#00000000" + } +} +``` + +## How do I pass parameters for FA widgets? + +Applicable to: OpenHarmony SDK 3.2.5.5 + +Use **featureAbility.getWant()** and **featureAbility.getContext()** to send data through **router** in the JSON file and use **featureAbility** to receive data in the JS file. + +## How do I trigger router.disableAlertBeforeBackPage and router.enableAlertBeforeBackPage? + +Applicable to: OpenHarmony SDK 3.2.5.5 + +The following conditions must be met: + +1. Before the redirection to the previous page, a confirm dialog box will be displayed. Note that **router.disableAlertBeforeBackPage** is used to disable the display of a confirm dialog box before returning to the previous page (default), and **router.enableAlertBeforeBackPage** is used to enable the display. + +2. The system return key is used. diff --git a/en/application-dev/faqs/faqs-bundle.md b/en/application-dev/faqs/faqs-bundle.md new file mode 100644 index 0000000000000000000000000000000000000000..61a5277c6d4a1493d0281fdd66b88a99a07141ae --- /dev/null +++ b/en/application-dev/faqs/faqs-bundle.md @@ -0,0 +1,31 @@ +# Bundle Management Development + +## How do I obtain the version code and version name of an application? + +Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 + +Use **bundle.getBundleInfo()** to obtain the bundle information, which contains the version code and version name. + +Reference: [Bundle](../reference/apis/js-apis-Bundle.md#bundlegetbundleinfo) + +## How do I obtain the bundle name of an application? + +Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 + +Obtain the bundle name through **context.abilityInfo.bundleName**. + +Reference: [AbilityContext](../reference/apis/js-apis-ability-context.md) and [AbilityInfo](../reference/apis/js-apis-bundle-AbilityInfo.md) + +## How do I obtain an application icon? + +Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 + +Use **bundle.getAbilityIcon** to obtain the application icon. To use this API, you must configure the permission **ohos.permission.GET_BUNDLE_INFO**. + +Reference: [Bundle](../reference/apis/js-apis-Bundle.md#bundlegetbundleinfo) + +## How do I determine whether an application is a system application? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +Use **bundle.getApplicationInfo** to obtain the application information, and then check the value of **systemApp** in the information. The application is a system application if the value is **true**. diff --git a/en/application-dev/faqs/faqs-development-board.md b/en/application-dev/faqs/faqs-development-board.md index 4766d4f5271dec2e5ec937477cf1ce1b7946eef6..79e5fc390f934f82eb3d70468f9ed41faed68947 100644 --- a/en/application-dev/faqs/faqs-development-board.md +++ b/en/application-dev/faqs/faqs-development-board.md @@ -1,6 +1,4 @@ -# Development Board - - +# Development Board Usage ## How do I take screenshots on a development board? @@ -29,8 +27,8 @@ Applicable to: DevEco Studio 3.0.0.991 1. Create a profile in Previewer. ![en-us_image_0000001361254285](figures/en-us_image_0000001361254285.png) -2. Set the profile parameters as follows: +2. Set the profile parameters as follows: Device type : default Resolution: 720\*1280 diff --git a/en/application-dev/faqs/faqs-device-management.md b/en/application-dev/faqs/faqs-device-management.md index 5bb748f758a4636fb40ae5d7fb741eccfb5306fe..dd836eb11abfbee3979f5a604eb5aa734d0d9112 100644 --- a/en/application-dev/faqs/faqs-device-management.md +++ b/en/application-dev/faqs/faqs-device-management.md @@ -1,12 +1,10 @@ # Device Management Development - - ## How do I obtain the DPI of a device? Applicable to: OpenHarmony SDK 3.2.2.5, stage model of API version 9 -Import the **@ohos.display** module and call the **getDefaultDisplay** API. +Import the **\@ohos.display** module and call the **getDefaultDisplay** API. Example: @@ -20,5 +18,33 @@ display.getDefaultDisplay((err, data) => { } console.info('Test Succeeded in obtaining the default display object. Data:' + JSON.stringify(data)); console.info('Test densityDPI:' + JSON.stringify(data.densityDPI)); -});https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-device-info.md) +}); ``` + +## How do I obtain the type of the device where the application is running? + +Applicable to: OpenHarmony SDK 3.2.2.5, stage model of API version 9 + +Import the **\@ohos.deviceInfo** module and call the **deviceInfo.deviceType** API. + +For details, see [Device Information](../reference/apis/js-apis-device-info.md). + +## How do I obtain the system version of a device? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +Use the **osFullName** attribute of the [deviceInfo](../reference/apis/js-apis-device-info.md) object. + +## How do I obtain the UDID of an OpenHarmony device? + +Applicable to: OpenHarmony SDK3.0, stage model of API version 9 + +- To obtain the UDID of the connected device, run the **hdc shell bm get --udid** command. + +- For details about how to obtain the UDID from code, see [udid](../reference/apis/js-apis-device-info.md). + +## How do I develop a shortcut key function? + +Applicable to: OpenHarmony SDK 3.2.6.5, stage model of API version 9 + +To develop a shortcut key function, use the APIs in [Input Consumer](../reference/apis/js-apis-inputconsumer.md). diff --git a/en/application-dev/faqs/faqs-graphics.md b/en/application-dev/faqs/faqs-graphics.md index c4e151559b547b2cdb4f8d7cb19b35318203674a..7752d9d746fc3cfe3d8b7028ada2c4d3c5af2136 100644 --- a/en/application-dev/faqs/faqs-graphics.md +++ b/en/application-dev/faqs/faqs-graphics.md @@ -11,3 +11,80 @@ In effect, the **isStatusBarLightIcon** and **isNavigationBarLightIcon** attribu Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 Import the **\@ohos.window** module, and call **window.setSystemBarProperties()**. + +## How do I hide the status bar to get the immersive effect? + +Applicable to: OpenHarmony SDK 3.2.6.3, stage model of API version 9 + +1. Use the **onWindowStageCreate** to obtain a **windowClass** object. + + ``` + onWindowStageCreate(windowStage) { + // When the main window is created, set the main page for this ability. + console.log("[Demo] MainAbility onWindowStageCreate") + windowStage.getMainWindow((err, data) => { + if (err.code) { + console.error('Failed to obtain the main window.') + return; + } + // Obtain a windowClass object. + globalThis.windowClass = data; + }) + } + ``` + +2. Enable the full-screen mode for the window and hide the status bar. + + ``` + globalThis.windowClass.setFullScreen(isFullScreen, (err, data) => { + if (err.code) { + console.error('Failed to enable the full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data)); + }); + ``` + +## How do I obtain the window width and height? + +Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 + +Use **window.getProperties()** to obtain the window properties. The **windowRect** field in the properties specifies the window width and height. + +Example: + + +``` +let promise = windowClass.getProperties(); +promise.then((data)=> { + console.info('Succeeded in obtaining the window properties. Data: ' + JSON.stringify(data.windowRect)); +}).catch((err)=>{ + console.error('Failed to obtain the window properties. Cause: ' + JSON.stringify(err)); +}); +``` + +## How do I set the color of the system bar? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +Refer to the following code: + + +``` +window.getTopWindow(globalThis.mainContext).then(win => { + var systemBarProperties = { + statusBarColor: '#19B6FF', // Set the background color of the status bar. + navigationBarColor: '#19B6FF', // Set the background color of the navigation bar. + isStatusBarLightIcon: false, // Set the icon on the status bar not to be highlighted. + isNavigationBarLightIcon: true, // Set the icon on the navigation bar to be highlighted. + statusBarContentColor: '#0D0500', // Set the text color of the status bar. + navigationBarContentColor: '#FFA500' // Set the text color of the navigation bar. + }; + win.setSystemBarProperties(systemBarProperties).catch(err => { + INDEX_LOGGER.info(`set System Bar Properties failed:${err}`) + }) +}) +.catch(err => { + INDEX_LOGGER.info(`get top window failed:${err}`) +}) +``` diff --git a/en/application-dev/faqs/faqs-media.md b/en/application-dev/faqs/faqs-media.md new file mode 100644 index 0000000000000000000000000000000000000000..9f465834a0951246f822ef2b5f8a5bf619ec1c5a --- /dev/null +++ b/en/application-dev/faqs/faqs-media.md @@ -0,0 +1,128 @@ +# Media Development + +## How do I set a front camera? + +Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 + +1. Set the camera position to **camera.CameraPosition.CAMERA_POSITION_FRONT**. + +2. Create a **CameraInput** instance based on the camera position and type. + +Reference: [Camera Management](../reference/apis/js-apis-camera.md) + +Example: + +``` +// The rear camera is set by default. You can use **isFrontCamera** to switch to the rear camera. +let cameraId +let cameraInput +for(let cameraIndex = 0; cameraIndex < this.cameraArray.length; cameraIndex++) { + let faceType = this.cameraArray[cameraIndex].cameraPosition + switch(faceType) { + case camera.CameraPosition.CAMERA_POSITION_FRONT: // Front camera + if(this.isFrontCamera){ + cameraId = this.cameraArray[cameraIndex].cameraId + } + break + case camera.CameraPosition.CAMERA_POSITION_BACK: // Rear camera + if(!this.isFrontCamera){ + cameraId = this.cameraArray[cameraIndex].cameraId + } + break + case camera.CameraPosition.CAMERA_POSITION_UNSPECIFIED: + default: + break + } +} +cameraInput = await this.cameraManager.createCameraInput(cameraId) +``` + +## How do I crop an image? + +Applicable to: OpenHarmony SDK 3.2.5.6, stage model of API version 9 + +1. Create an **ImageSource** instance based on the input URI. + + ``` + let path = this.context.getApplicationContext().fileDirs + "test.jpg"; + const imageSourceApi = image.createImageSource(path); + ``` + +2. Set decoding parameters and decode the image to obtain a **PixelMap** object. Image processing is supported during decoding. + - Set **desiredSize** to specify the target size after scaling. If the values are all set to **0**, scaling will not be performed. + - Set **desiredRegion** to specify the target rectangular area after cropping. If the values are all set to **0**, cropping will not be performed. + - Set **rotateDegrees** to specify the rotation angle. The image will be rotated clockwise at the center. + + ``` + const decodingOptions = { + desiredSize: { + height:0, + width:0 + }, + // Crop a rectangular area. + desiredRegion: { + size: { + height:100, + width:100 + }, + x:0, + y:0 + }, + // Rotate the image by 90 degrees. + rotate:90 + } + imageSourceApi.createPixelMap(decodingOptions).then(pixelMap => { + this.handlePixelMap(pixelMap) + }) + ``` + +3. Process the obtained **PixelMap** object. For example, render and display the image. + +## How do I apply for the media read/write permission on a device? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 + +1. Configure the permissions **ohos.permission.READ_MEDIA** and **ohos.permission.WRITE_MEDIA** in the **module.json5** file. + Example: + + + ``` + { + "module" : { + "requestPermissions":[ + { + "name" : "ohos.permission.READ_MEDIA", + "reason": "$string:reason" + }, + { + "name" : "ohos.permission.WRITE_MEDIA", + "reason": "$string:reason" + } + ] + } + } + ``` + +2. Call **requestPermissionsFromUser** to request the permissions from end users in the form of a dialog box. This operation is required because the grant mode of both permissions is **user_grant**. + + ``` + let permissions: Array = ['ohos.permission.READ_MEDIA','ohos.permission.WRITE_MEDIA'] + context.requestPermissionsFromUser(permissions).then((data) => { + console.log("Succeed to request permission from user with data: " + JSON.stringify(data)) + }).catch((error) => { + console.log("Failed to request permission from user with error: " + JSON.stringify(error)) + }) + ``` + +## Why can't I play MP4 videos? + +Applicable to: OpenHarmony SDK 3.2.7.5, stage model of API version 9 + +Currently, the system does not support the playback of MP4 videos in H.265 format. + + +## Why can't I play a new video or even encounters a crash after creating more than 10 videos? + +Applicable to: OpenHarmony SDK 3.2.7.5, stage model of API version 9 + +A maximum of 13 media player instances can be created. diff --git a/en/application-dev/faqs/faqs-native.md b/en/application-dev/faqs/faqs-native.md index da00895e4a5b5a532e67f9f709dd84c25abe3205..ef5700bb0ec1e3c903fd758d644779856f0ce681 100644 --- a/en/application-dev/faqs/faqs-native.md +++ b/en/application-dev/faqs/faqs-native.md @@ -1,12 +1,30 @@ # Native API Usage +## Is there a native API that provides functions similar to Canvas? + +Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 + +Yes. The native API **Drawing** provides similar functions. It can be used for 2D drawing. + ## When a native HAP is running, the error message "Obj is not a valid object" is displayed for the imported namespace. What should I do? Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 Check the **abiFilters** parameter value in the **build-profile.json5** file in the root directory of the module (not the root directory of the project). If the device is 32-bit, the value must be **armeabi-v7a**. If the device is 64-bit, the value must be **arm64-v8a**. -## How do I obtain the value of version in the package.json file of a module in the C++ code developed using native APIs? +## What should I do when the error message "install parse profile prop check error" is displayed during the running of a native HAP? + +Applicable to: OpenHarmony SDK 3.2.6.3, stage model of API version 9 + +Check the **abiFilters** parameter value in the **build-profile.json5** file in the root directory of the module (not the root directory of the project). If the device is 32-bit, the value must be **armeabi-v7a**. If the device is 64-bit, the value must be **arm64-v8a**. + +## What should I do when the error message "undefined symbol: OH_LOG_Print" is displayed during log printing by **OH_LOG_Print**? + +Applicable to: OpenHarmony SDK 3.2.6.3, stage model of API version 9 + +Modify the **CMakeLists.txt** file by adding **libhilog_ndk.z.so** to the end of **target_link_libraries**. + +## How do I obtain the value of version in the package.json file of a module? Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 @@ -53,3 +71,9 @@ static napi_value Add(napi_env env, napi_callback_info info) return fixed_version_value; } ``` + +## How do I traverse files in rawfile? + +Applicable to: OpenHarmony SDK 3.2 or later, stage model of API version 9 + +Use the native API **OH_ResourceManager_OpenRawDir()** to obtain the root directory of **rawfile** and traverse the root directory. diff --git a/en/application-dev/faqs/faqs-third-party-library.md b/en/application-dev/faqs/faqs-third-party-library.md index 323269c5e0a4d8c84e9adbb39c4184bba9a00b5e..898055cd200805d8df549b33bb2c5f3b4b05bca6 100644 --- a/en/application-dev/faqs/faqs-third-party-library.md +++ b/en/application-dev/faqs/faqs-third-party-library.md @@ -1,7 +1,74 @@ # Usage of Third- and Fourth-Party Libraries -## What does the following error message mean : "Stage model module... does not support including OpenHarmony npm packages or modules in FA model. OpenHarmony build tasks will not be executed, and OpenHarmony resources will not be packed." +## What does the following error message mean: "Stage model module... does not support including OpenHarmony npm packages or modules in FA model. OpenHarmony build tasks will not be executed, and OpenHarmony resources will not be packed." Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 The third- and fourth-party libraries are not yet compatible with the stage model of API version 9 and cannot be used. + +## Can I transfer project-level dependencies? + +Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 + +For example, if project A depends on project B and project B depends on project C, can project A directly use the APIs provided by project C? + +No. Project A cannot directly use the APIs provided by project C. The project packing tool NPM does not support dependency transfer. To use the APIs provided by project C, you can add the dependency of project C to project A. + +## How do I obtain available third-party libraries? + +Applicable to: OpenHarmony SDK 3.2.6.5, stage model of API version 9 + +For details, see [Third-Party Components That Can Be Directly Used on OpenHarmony](https://gitee.com/openharmony-sig/third_party_app_libs). + +## Which third-party libraries are related to network requests? + +Applicable to: OpenHarmony SDK 3.2.6.5, stage model of API version 9 + +The [Axios](https://gitee.com/openharmony-sig/axios) library is related to network requests. + +## How do I use NPM to import third- and fourth-party libraries? + +Applicable to: OpenHarmony SDK 3.2.5.5, stage model of API version 9 +- Method 1: + 1. Open the **Terminal** window and run the following command to go to the **entry** directory: + + ``` + cd entry + ``` + 2. Run the following command to install a third-party package, for example, **dayjs**: + + ``` + npm install dayjs --save + ``` + 3. Add the following statement in the .js file to import the package: + + ``` + import dayjs from 'dayjs'; + ``` + +- Method 2: + 1. Enter the **entry** directory of the project and open the **package.json** file. + 2. Write the third-party NPM package to be installed (for example, **dayjs**) in the **package.json** file. + + ``` + { + "dependencies": { + "dayjs": "^1.10.4", + } + } + ``` + 3. Open the **Terminal** window and run the following command to go to the **entry** directory: + + ``` + cd entry + ``` + 4. Run the following command to install NPM: + + ``` + npm install + ``` + 5. Add the following statement in the .js file to import the package: + + ``` + import dayjs from 'dayjs'; + ``` diff --git a/en/application-dev/faqs/faqs-ui-ets.md b/en/application-dev/faqs/faqs-ui-ets.md index 86a05c91851d6844dcc08e368d81b936b7d1b8ac..3ec2b755e3e99db07930d5f8a6d01975985f4948 100644 --- a/en/application-dev/faqs/faqs-ui-ets.md +++ b/en/application-dev/faqs/faqs-ui-ets.md @@ -1,4 +1,4 @@ -# ArkUI (eTS) Development +# ArkUI (ArkTS) Development @@ -72,7 +72,7 @@ Applicable to: OpenHarmony SDK 3.2.2.5, stage model of API version 9 2. Convert data in Uint8Array format to the string type by calling the **String.fromCharCode** API. -Reference: [Resource Management](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-resource-manager.md) +Reference: [Resource Management](../reference/apis/js-apis-resource-manager.md) Example: @@ -94,7 +94,7 @@ Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 Use the **resourceManager.getString()** API of the **\@ohos.resourceManager** module. -Reference: [Resource Management](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-resource-manager.md#getstring) +Reference: [Resource Management](../reference/apis/js-apis-resource-manager.md#getstring) ## What should I do if the global static variables of a class do not work? @@ -102,8 +102,6 @@ Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 Objects imported to abilities and pages are packaged into two different closures, that is, two global objects. In this case, a static variable referenced by the abilities is not the same object as that referenced by the pages. Therefore, global variables cannot be defined by defining static variables in the class. You are advised to use AppStorage to manage global variables. -Reference: [AppStorage](https://docs.openharmony.cn/pages/v3.2Beta/en/application-dev/ui/ts-application-states-appstorage.md/) - ## How do I obtain resources in the stage model? Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 @@ -154,9 +152,9 @@ build() { Applicable to: OpenHarmony SDK 3.2.2.5, stage model of API version 9 -No. Currently, **CustomDialog** can be used only on eTS pages. +No. Currently, **CustomDialog** can be used only on ArkTS pages. -Reference: [Custom Dialog Box](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md) +Reference: [Custom Dialog Box](../reference/arkui-ts/ts-methods-custom-dialog-box.md) ## How do I transfer variables in CustomDialog to variables on pages? @@ -210,7 +208,7 @@ Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9 By default, child components in a **\** are horizontally aligned to the left. To center them, perform the following steps: -Nest a **\** component and set it to **justifyContent(FlexAlign.Center)**. For details, see [Grid Layout](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/ui-ts-layout-grid-container.md). +Nest a **\** component and set it to **justifyContent(FlexAlign.Center)**. For details, see [Grid Layout](../reference/arkui-ts/ts-container-gridcontainer.md). Example: @@ -267,13 +265,13 @@ export default class MainAbility extends Ability { } ``` -## How do I execute JavaScript functions in the \ component in eTS code? +## How do I execute JavaScript functions in the \ component in ArkTS code? Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 Call the **runJavaScript** API in the **WebController** to asynchronously execute JavaScript scripts. This API uses a callback to return the execution result. Note: **runJavaScript** can only be called after **loadUrl** has been completed. For example, it can be called in **onPageEnd**. -Reference: [Web](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/arkui-ts/ts-basic-components-web.md) +Reference: [Web](../reference/arkui-ts/ts-basic-components-web.md) ## How do I fix misidentification of the pan gesture where container nesting is involved? diff --git a/en/application-dev/faqs/faqs-ui-js.md b/en/application-dev/faqs/faqs-ui-js.md index 7d4ae1dcb80b63a4632e3a30627ff53f37e63c37..c60ff729eae773a356a50da1b9197c1de2b9c120 100644 --- a/en/application-dev/faqs/faqs-ui-js.md +++ b/en/application-dev/faqs/faqs-ui-js.md @@ -1,7 +1,5 @@ # ArkUI (JavaScript) Development - - ## How do I convert the fields in an XML file into JavaScript objects? Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 @@ -13,38 +11,37 @@ Example: ``` import convertxml from '@ohos.convertxml'; -// Code snippet -xml = +// XML strings +let xml = '' + '' + ' Happy' + ' Work' + ' Play' + ''; -let conv = new convertxml.ConvertXML(); +let conv = new convertxml.ConvertXML(); // Options for conversion. For details, see the reference document. -let options = {trim : false, declarationKey:"_declaration", - instructionKey : "_instruction", attributesKey : "_attributes", - textKey : "_text", cdataKey:"_cdata", doctypeKey : "_doctype", - commentKey : "_comment", parentKey : "_parent", typeKey : "_type", - nameKey : "_name", elementsKey : "_elements"} -let result:any = conv.convert(xml, options) // Convert fields in the XML file into JavaScript objects. +let options = { + trim: false, + declarationKey: "_declaration", + instructionKey: "_instruction", + attributesKey: "_attributes", + textKey: "_text", + cdataKey: "_cdata", + doctypeKey: "_doctype", + commentKey: "_comment", + parentKey: "_parent", + typeKey: "_type", + nameKey: "_name", + elementsKey: "_elements" +} +let result: any = conv.convert(xml, options) // Convert fields in the XML file into JavaScript objects. console.log('Test: ' + JSON.stringify(result)) -console.log('Test: ' + result._declaration._attributes.version) // version field in XML file -console.log('Test: ' + result._elements[0]._elements[0]._elements[0]._text) // title field in XML file +console.log('Test: ' + result._declaration._attributes.version) // version field in the XML file +console.log('Test: ' + result._elements[0]._elements[0]._elements[0]._text) // title field in the XML file ``` -Reference: [XML-to-JavaScript Conversion](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-convertxml.md) - -## What are the differences between JavaScript, TypeScript, and eTS? - -Applicable to: OpenHarmony SDK 3.2.3.5, stage model of API version 9 - -- JavaScript: a lightweight, weakly-typed programming language, most commonly known as the scripting language for web pages. - -- TypeScript: a superset of JavaScript, with additions of static typing and more object-oriented APIs, enums, etc. - -- eTS: a superset of TypeScript and the programming language for OpenHarmony ArkUI development, which powers UI development through a declarative development paradigm. +For details, see [XML-to-JavaScript Conversion](../reference/apis/js-apis-convertxml.md). ## How do I convert the time to the HHMMSS format? @@ -93,4 +90,5 @@ export default class DateTimeUtil{ return `${this.fill(hours)}${this.fill(minutes)}${this.fill(seconds)}` } } + ``` diff --git a/en/application-dev/file-management/medialibrary-album-guidelines.md b/en/application-dev/file-management/medialibrary-album-guidelines.md index 322e596ef6a0776291ab36529fb10760c09b4c51..fccb8446d5309dbbff0d0687aae8be5ceaf958c8 100644 --- a/en/application-dev/file-management/medialibrary-album-guidelines.md +++ b/en/application-dev/file-management/medialibrary-album-guidelines.md @@ -12,9 +12,9 @@ To ensure the application running efficiency, most **MediaLibrary** API calls ar You can obtain images and videos in an album in either of the following ways: -- Call [MediaLibrary.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-1) with an album specified to obtain the media assets. For details, see [Querying Media Assets with the Specified Album Name](medialibrary-resource-guidelines#querying-media-assets-with-the-specified-album-name). +- Call [MediaLibrary.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-1) with an album specified to obtain the media assets. For details, see [Querying Media Assets with the Specified Album Name](medialibrary-resource-guidelines.md#querying-media-assets-with-the-specified-album-name). -- Call [Album.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-3) to obtain an **Album** instance, so as to obtain the media assets in it. For details, see [Obtaining Images and Videos in an Album](medialibrary-resource-guidelines#obtaining-images-and-videos-in-an-album). +- Call [Album.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-3) to obtain an **Album** instance, so as to obtain the media assets in it. For details, see [Obtaining Images and Videos in an Album](medialibrary-resource-guidelines.md#obtaining-images-and-videos-in-an-album). ## Creating an Album diff --git a/en/application-dev/file-management/medialibrary-resource-guidelines.md b/en/application-dev/file-management/medialibrary-resource-guidelines.md index 737ea4e48fa24c38f47fe7595e9df6e1370ab69a..d3ca37dc5be9163a4de8c303aa81704d95056bc1 100644 --- a/en/application-dev/file-management/medialibrary-resource-guidelines.md +++ b/en/application-dev/file-management/medialibrary-resource-guidelines.md @@ -6,7 +6,7 @@ Your applications can use the APIs provided by the **mediaLibrary** module to pe > > Before developing features, read [MediaLibrary Overview](medialibrary-overview.md) to learn how to obtain a **MediaLibrary** instance and request the permissions to call the APIs of **MediaLibrary**. -To ensure the application running efficiency, most **MediaLibrary** API calls are asynchronous, and both callback and promise modes are provided for these APIs. The following code samples use the promise mode. For details about the APIs, see [MediaLibrary API Reference](../reference/apis/js-apis-medialibrary.md). +To maximize the application running efficiency, most **MediaLibrary** API calls are asynchronous in callback or promise mode. The following code samples use the promise mode. For details about the APIs, see [MediaLibrary API Reference](../reference/apis/js-apis-medialibrary.md). ## Querying Media Assets @@ -215,7 +215,7 @@ async function getCameraImagePromise() { ## Obtaining the Thumbnail of an Image or a Video -You can call [FileAsset.getThumbnail](../reference/apis/js-apis-medialibrary.md#getthumbnail8-2) with the thumbnail size passed in to obtain the thumbnail of an image or a video. Thumbnails are usually displayed on the UI. +You can call [FileAsset.getThumbnail](../reference/apis/js-apis-medialibrary.md#getthumbnail8-2) with the thumbnail size passed in to obtain the thumbnail of an image or a video. Your application can use thumbnails to offer a quick preview on images and videos. **Prerequisites** @@ -224,8 +224,6 @@ You can call [FileAsset.getThumbnail](../reference/apis/js-apis-medialibrary.md# ### Obtaining the Thumbnail of an Image -Your application may need to obtain the thumbnail of an image for preview purposes. - The following describes how to obtain the thumbnail (size: 720 x 720) of the first image in the album. **How to Develop** @@ -273,7 +271,7 @@ You can call [MediaLibrary.createAsset](../reference/apis/js-apis-medialibrary.m - You have obtained a **MediaLibrary** instance. - You have granted the permission **ohos.permission.WRITE_MEDIA**. -- [Obtain the public directory](medialibrary-filepath-guidelines.md). +- [You have obtained a public directory](medialibrary-filepath-guidelines.md). The following describes how to create a file of the **MediaType.FILE** type. @@ -296,7 +294,7 @@ async function example() { You can use [FileAsset.trash](../reference/apis/js-apis-medialibrary.md#trash8) to move a media asset to the recycle bin. -By default, files in the recycle bin will be stored for 30 days. During this period, you can set **isTrash** in **trash** to **false** to recover the files from the recycle bin. Application users can also recover the files through the system applications **Files** or **Gallery**. +By default, files in the recycle bin will be stored for 30 days before being permanently removed. During this period, you can set **isTrash** in **trash** to **false** to recover the files. Application users can also recover the files through the system applications **Files** or **Gallery**. **Prerequisites** @@ -339,11 +337,9 @@ async function example() { ## Renaming a Media Asset -Renaming modifies the **FileAsset.displayName** attribute of a file, that is, the displayed file name, including the file name extension. - -After the modification, call [FileAsset.commitModify](../reference/apis/js-apis-medialibrary.md#commitmodify8-1) to commit the modification to the database. +To rename a media asset, modify the **FileAsset.displayName** attribute (which specifies the displayed file name, including the file name extension) and commit the modification through [FileAsset.commitModify](../reference/apis/js-apis-medialibrary.md#commitmodify8-1). -Before renaming a file, you must call [FetchFileResult](../reference/apis/js-apis-medialibrary.md#fetchfileresult7) to obtain the file. +Before renaming a file, you must obtain the file, for example, by calling [FetchFileResult](../reference/apis/js-apis-medialibrary.md#fetchfileresult7). **Prerequisites** @@ -358,7 +354,7 @@ The following describes how to rename the first file in the result set as **newt 2. Call **getFileAssets** to obtain the images in the target album. 3. Call **getFirstObject** to obtain the first image among all the images obtained. 4. Rename the image as **newImage.jpg**. -5. Call **FileAsset.commitModify** to commit the modification of the attributes to the database. +5. Call **FileAsset.commitModify** to commit the modification to the database. ```ts async function example() { diff --git a/en/application-dev/media/Readme-EN.md b/en/application-dev/media/Readme-EN.md index 07f3425ff5ab3c10beeac312740ff6e756c3cd85..d65c0d9dbe51f963385afaac0b75deccc6b21d2b 100755 --- a/en/application-dev/media/Readme-EN.md +++ b/en/application-dev/media/Readme-EN.md @@ -10,11 +10,16 @@ - [OpenSL ES Audio Playback Development](opensles-playback.md) - [OpenSL ES Audio Recording Development](opensles-capture.md) - [Audio Interruption Mode Development](audio-interruptmode.md) + - [Volume Management Development](audio-volume-manager.md) + - [Audio Routing and Device Management Development](audio-routing-manager.md) - Video - [Video Playback Development](video-playback.md) - [Video Recording Development](video-recorder.md) +- AVSession + - [AVSession Overview](avsession-overview.md) + - [AVSession Development](avsession-guidelines.md) - Image - [Image Development](image.md) diff --git a/en/application-dev/media/audio-playback.md b/en/application-dev/media/audio-playback.md index 92aa1cd4fc35a4b64ad9b1044c1a7bd59f24453d..bbdb993ecdb9a1289a939af43db0e670ec10f98f 100644 --- a/en/application-dev/media/audio-playback.md +++ b/en/application-dev/media/audio-playback.md @@ -2,11 +2,11 @@ ## Introduction -You can use audio playback APIs to convert audio data into audible analog signals and play the signals using output devices. You can also manage playback tasks. For example, you can start, suspend, stop playback, release resources, set the volume, seek to a playback position, and obtain track information. +You can use audio playback APIs to convert audio data into audible analog signals and play the signals using output devices. You can also manage playback tasks. For example, you can control the playback and volume, obtain track information, and release resources. ## Working Principles -The following figures show the audio playback status changes and the interaction with external modules for audio playback. +The following figures show the audio playback state transition and the interaction with external modules for audio playback. **Figure 1** Audio playback state transition @@ -28,7 +28,7 @@ For details about the APIs, see [AudioPlayer in the Media API](../reference/apis > **NOTE** > -> The method for obtaining the path in the FA model is different from that in the stage model. **pathDir** used in the sample code below is an example. You need to obtain the path based on project requirements. For details about how to obtain the path, see [Application Sandbox Path Guidelines](../reference/apis/js-apis-fileio.md#guidelines). +> The method for obtaining the path in the FA model is different from that in the stage model. For details about how to obtain the path, see [Application Sandbox Path Guidelines](../reference/apis/js-apis-fileio.md#guidelines). ### Full-Process Scenario @@ -109,7 +109,7 @@ async function audioPlayerDemo() { setCallBack(audioPlayer); // Set the event callbacks. // 2. Set the URI of the audio file. let fdPath = 'fd://' - let pathDir = "/data/storage/el2/base/haps/entry/files" // The method for obtaining pathDir in the FA model is different from that in the stage model. For details, see NOTE just below How to Develop. You need to obtain pathDir based on project requirements. + let pathDir = "/data/storage/el2/base/haps/entry/files" // The path used here is an example. Obtain the path based on project requirements. // The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el2/100/base/ohos.acts.multimedia.audio.audioplayer/haps/entry/files" command. let path = pathDir + '/01.mp3' await fileIO.open(path).then((fdNumber) => { @@ -151,7 +151,7 @@ export class AudioDemo { let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance. this.setCallBack(audioPlayer); // Set the event callbacks. let fdPath = 'fd://' - let pathDir = "/data/storage/el2/base/haps/entry/files" // The method for obtaining pathDir in the FA model is different from that in the stage model. For details, see NOTE just below How to Develop. You need to obtain pathDir based on project requirements. + let pathDir = "/data/storage/el2/base/haps/entry/files" // The path used here is an example. Obtain the path based on project requirements. // The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el2/100/base/ohos.acts.multimedia.audio.audioplayer/haps/entry/files" command. let path = pathDir + '/01.mp3' await fileIO.open(path).then((fdNumber) => { @@ -199,7 +199,7 @@ export class AudioDemo { async nextMusic(audioPlayer) { this.isNextMusic = true; let nextFdPath = 'fd://' - let pathDir = "/data/storage/el2/base/haps/entry/files" // The method for obtaining pathDir in the FA model is different from that in the stage model. For details, see NOTE just below How to Develop. You need to obtain pathDir based on project requirements. + let pathDir = "/data/storage/el2/base/haps/entry/files" // The path used here is an example. Obtain the path based on project requirements. // The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\02.mp3 /data/app/el2/100/base/ohos.acts.multimedia.audio.audioplayer/haps/entry/files" command. let nextpath = pathDir + '/02.mp3' await fileIO.open(nextpath).then((fdNumber) => { @@ -217,7 +217,7 @@ export class AudioDemo { let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance. this.setCallBack(audioPlayer); // Set the event callbacks. let fdPath = 'fd://' - let pathDir = "/data/storage/el2/base/haps/entry/files" // The method for obtaining pathDir in the FA model is different from that in the stage model. For details, see NOTE just below How to Develop. You need to obtain pathDir based on project requirements. + let pathDir = "/data/storage/el2/base/haps/entry/files" // The path used here is an example. Obtain the path based on project requirements. // The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el2/100/base/ohos.acts.multimedia.audio.audioplayer/haps/entry/files" command. let path = pathDir + '/01.mp3' await fileIO.open(path).then((fdNumber) => { @@ -256,7 +256,7 @@ export class AudioDemo { let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance. this.setCallBack(audioPlayer); // Set the event callbacks. let fdPath = 'fd://' - let pathDir = "/data/storage/el2/base/haps/entry/files" // The method for obtaining pathDir in the FA model is different from that in the stage model. For details, see NOTE just below How to Develop. You need to obtain pathDir based on project requirements. + let pathDir = "/data/storage/el2/base/haps/entry/files" // The path used here is an example. Obtain the path based on project requirements. // The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el2/100/base/ohos.acts.multimedia.audio.audioplayer/haps/entry/files" command. let path = pathDir + '/01.mp3' await fileIO.open(path).then((fdNumber) => { diff --git a/en/application-dev/media/audio-routing-manager.md b/en/application-dev/media/audio-routing-manager.md new file mode 100644 index 0000000000000000000000000000000000000000..55febdca0fad968d946601fce4faed99bc148dd2 --- /dev/null +++ b/en/application-dev/media/audio-routing-manager.md @@ -0,0 +1,111 @@ +# Audio Routing and Device Management Development + +## Overview + +The **AudioRoutingManager** module provides APIs for audio routing and device management. You can use the APIs to obtain the current input and output audio devices, listen for connection status changes of audio devices, and activate communication devices. + +## Working Principles + +The figure below shows the common APIs provided by the **AudioRoutingManager** module. + +**Figure 1** Common APIs of AudioRoutingManager + +![en-us_image_audio_routing_manager](figures/en-us_image_audio_routing_manager.png) + +You can use these APIs to obtain the device list, subscribe to or unsubscribe from device connection status changes, activate communication devices, and obtain their activation status. For details, see [Audio Management](../reference/apis/js-apis-audio.md). + + +## How to Develop + +For details about the APIs, see [AudioRoutingManager in Audio Management](../reference/apis/js-apis-audio.md#audioroutingmanager9). + +1. Obtain an **AudioRoutingManager** instance. + + Before using an API in **AudioRoutingManager**, you must use **getRoutingManager()** to obtain an **AudioRoutingManager** instance. + + ```js + import audio from '@ohos.multimedia.audio'; + async loadAudioRoutingManager() { + var audioRoutingManager = await audio.getAudioManager().getRoutingManager(); + console.info('audioRoutingManager------create-------success.'); + } + + ``` + +2. (Optional) Obtain the device list and subscribe to device connection status changes. + + To obtain the device list (such as input, output, distributed input, and distributed output devices) or listen for connection status changes of audio devices, refer to the following code: + + ```js + import audio from '@ohos.multimedia.audio'; + // Obtain an AudioRoutingManager instance. + async loadAudioRoutingManager() { + var audioRoutingManager = await audio.getAudioManager().getRoutingManager(); + console.info('audioRoutingManager------create-------success.'); + } + // Obtain information about all audio devices. (You can set DeviceFlag as required.) + async getDevices() { + await loadAudioRoutingManager(); + await audioRoutingManager.getDevices(audio.DeviceFlag.ALL_DEVICES_FLAG).then((data) => { + console.info(`getDevices success and data is: ${JSON.stringify(data)}.`); + }); + } + // Subscribe to connection status changes of audio devices. + async onDeviceChange() { + await loadAudioRoutingManager(); + await audioRoutingManager.on('deviceChange', audio.DeviceFlag.ALL_DEVICES_FLAG, (deviceChanged) => { + console.info('on device change type : ' + deviceChanged.type); + console.info('on device descriptor size : ' + deviceChanged.deviceDescriptors.length); + console.info('on device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceRole); + console.info('on device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceType); + }); + } + // Unsubscribe from the connection status changes of audio devices. + async offDeviceChange() { + await loadAudioRoutingManager(); + await audioRoutingManager.off('deviceChange', (deviceChanged) => { + console.info('off device change type : ' + deviceChanged.type); + console.info('off device descriptor size : ' + deviceChanged.deviceDescriptors.length); + console.info('off device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceRole); + console.info('off device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceType); + }); + } + // Complete process: Call APIs to obtain all devices and subscribe to device changes, then manually change the connection status of a device (for example, wired headset), and finally call APIs to obtain all devices and unsubscribe from the device changes. + async test(){ + await getDevices(); + await onDeviceChange()(); + // Manually disconnect or connect devices. + await getDevices(); + await offDeviceChange(); + } + ``` + +3. (Optional) Activate a communication device and obtain its activation status. + + ```js + import audio from '@ohos.multimedia.audio'; + // Obtain an AudioRoutingManager instance. + async loadAudioRoutingManager() { + var audioRoutingManager = await audio.getAudioManager().getRoutingManager(); + console.info('audioRoutingManager------create-------success.'); + } + // Activate a communication device. + async setCommunicationDevice() { + await loadAudioRoutingManager(); + await audioRoutingManager.setCommunicationDevice(audio.CommunicationDeviceType.SPEAKER, true).then(() => { + console.info('setCommunicationDevice true is success.'); + }); + } + // Obtain the activation status of the communication device. + async isCommunicationDeviceActive() { + await loadAudioRoutingManager(); + await audioRoutingManager.isCommunicationDeviceActive(audio.CommunicationDeviceType.SPEAKER).then((value) => { + console.info(`CommunicationDevice state is: ${value}.`); + }); + } + // Complete process: Activate a device and obtain the activation status. + async test(){ + await setCommunicationDevice(); + await isCommunicationDeviceActive(); + } + ``` diff --git a/en/application-dev/media/audio-volume-manager.md b/en/application-dev/media/audio-volume-manager.md new file mode 100644 index 0000000000000000000000000000000000000000..2063e831f886ae3e6e1fe0a5bd428da194d00227 --- /dev/null +++ b/en/application-dev/media/audio-volume-manager.md @@ -0,0 +1,126 @@ +# Volume Management Development + +## Overview + +The **AudioVolumeManager** module provides APIs for volume management. You can use the APIs to obtain the volume of a stream, listen for ringer mode changes, and mute a microphone. + +## Working Principles + +The figure below shows the common APIs provided by the **AudioVolumeManager** module. + +**Figure 1** Common APIs of AudioVolumeManager + +![en-us_image_audio_volume_manager](figures/en-us_image_audio_volume_manager.png) + +**AudioVolumeManager** provides the APIs for subscribing to system volume changes and obtaining the audio volume group manager (an **AudioVolumeGroupManager** instance). Before calling any API in **AudioVolumeGroupManager**, you must call **getVolumeGroupManager** to obtain an **AudioVolumeGroupManager** instance. You can use the APIs provided by **AudioVolumeGroupManager** to obtain the volume of a stream, mute a microphone, and listen for microphone state changes. For details, see [Audio Management](../reference/apis/js-apis-audio.md). + +## Constraints + +Before developing a microphone management application, configure the permission **ohos.permission.MICROPHONE** for the application. To set the microphone state, configure the permission **ohos.permission.MANAGE_AUDIO_CONFIG** (a system permission). For details about the permission configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md). + +## How to Develop + +For details about the APIs, see [AudioVolumeManager in Audio Management](../reference/apis/js-apis-audio.md#audiovolumemanager9) + +1. Obtain an **AudioVolumeGroupManager** instance. + + Before using an API in **AudioVolumeGroupManager**, you must use **getVolumeGroupManager()** to obtain an **AudioStreamManager** instance. + + ```js + import audio from '@ohos.multimedia.audio'; + async loadVolumeGroupManager() { + const groupid = audio.DEFAULT_VOLUME_GROUP_ID; + var audioVolumeGroupManager = await audio.getAudioManager().getVolumeManager().getVolumeGroupManager(groupid); + console.error('audioVolumeGroupManager create success.'); + } + + ``` + +2. (Optional) Obtain the volume information and ringer mode. + + To obtain the volume information (such as the ringtone, voice call, media, and voice assistant) of an audio stream or obtain the ringer mode (silent, vibration, or normal) of the current device, refer to the code below. For more details, see [Audio Management](../reference/apis/js-apis-audio.md). + + ```js + import audio from '@ohos.multimedia.audio'; + async loadVolumeGroupManager() { + const groupid = audio.DEFAULT_VOLUME_GROUP_ID; + var audioVolumeGroupManager = await audio.getAudioManager().getVolumeManager().getVolumeGroupManager(groupid); + console.info('audioVolumeGroupManager create success.'); + } + + // Obtain the volume of a stream. The value ranges from 0 to 15. + async getVolume() { + await loadVolumeGroupManager(); + await audioVolumeGroupManager.getVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`getVolume success and volume is: ${value}.`); + }); + } + // Obtain the minimum volume of a stream. + async getMinVolume() { + await loadVolumeGroupManager(); + await audioVolumeGroupManager.getMinVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`getMinVolume success and volume is: ${value}.`); + }); + } + // Obtain the maximum volume of a stream. + async getMaxVolume() { + await loadVolumeGroupManager(); + await audioVolumeGroupManager.getMaxVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`getMaxVolume success and volume is: ${value}.`); + }); + } + // Obtain the ringer mode in use: silent (0) | vibrate (1) | normal (2). + async getRingerMode() { + await loadVolumeGroupManager(); + await audioVolumeGroupManager.getRingerMode().then((value) => { + console.info(`getRingerMode success and RingerMode is: ${value}.`); + }); + } + ``` + +3. (Optional) Obtain and set the microphone state, and subscribe to microphone state changes. + + To obtain and set the microphone state or subscribe to microphone state changes, refer to the following code: + + ```js + import audio from '@ohos.multimedia.audio'; + async loadVolumeGroupManager() { + const groupid = audio.DEFAULT_VOLUME_GROUP_ID; + var audioVolumeGroupManager = await audio.getAudioManager().getVolumeManager().getVolumeGroupManager(groupid); + console.info('audioVolumeGroupManager create success.'); + } + + async on() { // Subscribe to microphone state changes. + await loadVolumeGroupManager(); + await audioVolumeGroupManager.audioVolumeGroupManager.on('micStateChange', (micStateChange) => { + console.info(`Current microphone status is: ${micStateChange.mute} `); + }); + } + + async isMicrophoneMute() { // Check whether the microphone is muted. + await audioVolumeGroupManager.audioVolumeGroupManager.isMicrophoneMute().then((value) => { + console.info(`isMicrophoneMute is: ${value}.`); + }); + } + + async setMicrophoneMuteTrue() { // Mute the microphone. + await loadVolumeGroupManager(); + await audioVolumeGroupManager.audioVolumeGroupManager.setMicrophoneMute(true).then(() => { + console.info('setMicrophoneMute to mute.'); + }); + } + + async setMicrophoneMuteFalse() { // Unmute the microphone. + await loadVolumeGroupManager(); + await audioVolumeGroupManager.audioVolumeGroupManager.setMicrophoneMute(false).then(() => { + console.info('setMicrophoneMute to not mute.'); + }); + } + async test(){ // Complete process: Subscribe to microphone state changes, obtain the microphone state, mute the microphone, obtain the microphone state, and unmute the microphone. + await on(); + await isMicrophoneMute(); + await setMicrophoneMuteTrue(); + await isMicrophoneMute(); + await setMicrophoneMuteFalse(); + } + ``` diff --git a/en/application-dev/media/avsession-guidelines.md b/en/application-dev/media/avsession-guidelines.md new file mode 100644 index 0000000000000000000000000000000000000000..6106509fbfe30a7b437ec574843f50cd7bf1aceb --- /dev/null +++ b/en/application-dev/media/avsession-guidelines.md @@ -0,0 +1,629 @@ +# AVSession Development + +## Development for the Session Access End + +### Basic Concepts +- **AVMetadata**: media data related attributes, including the IDs of the current media asset, previous media asset, and next media asset, title, author, album, writer, and duration. +- **AVSessionDescriptor**: descriptor about a media session, including the session ID, session type (audio/video), custom session name (**sessionTag**), and information about the corresponding application (**elementName**). +- **AVPlaybackState**: information related to the media playback state, including the playback state, position, speed, buffered time, loop mode, and whether the media asset is favorited (**isFavorite**). + +### Available APIs +The table below lists the APIs available for the development of the session access end. The APIs use either a callback or promise to return the result. The APIs listed below use a callback, which provide the same functions as their counterparts that use a promise. For details, see [AVSession Management](../reference/apis/js-apis-avsession.md). + +Table 1 Common APIs for session access end development + +| API | Description | +|----------------------------------------------------------------------------------|-------------| +| createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback\): void | Creates a session.| +| setAVMetadata(data: AVMetadata, callback: AsyncCallback\): void | Sets session metadata. | +| setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback\): void | Sets the playback state information. | +| setLaunchAbility(ability: WantAgent, callback: AsyncCallback\): void | Sets the launcher ability.| +| getController(callback: AsyncCallback\): void | Obtains the controller of this session.| +| getOutputDevice(callback: AsyncCallback\): void | Obtains the output device information. | +| activate(callback: AsyncCallback\): void | Activates this session. | +| destroy(callback: AsyncCallback\): void | Destroys this session. | + +### How to Develop +1. Import the modules. + +```js +import avSession from '@ohos.multimedia.avsession'; +import wantAgent from '@ohos.wantAgent'; +import featureAbility from '@ohos.ability.featureAbility'; +``` + +2. Create and activate a session. +```js +// Define global variables. +let mediaFavorite = false; +let currentSession = null; +let context = featureAbility.getContext(); + +// Create an audio session. +avSession.createAVSession(context, "AudioAppSample", 'audio').then((session) => { + currentSession = session; + currentSession.activate(); // Activate the session. +}).catch((err) => { + console.info(`createAVSession : ERROR : ${err.message}`); +}); +``` + +3. Set the session information, including: +- Session metadata. In addition to the current media asset ID (mandatory), you can set the title, album, author, duration, and previous/next media asset ID. For details about the session metadata, see **AVMetadata** in the API document. +- Launcher ability, which is implemented by calling an API of **WantAgent**. Generally, **WantAgent** is used to encapsulate want information. For more information, see [wantAgent](../reference/apis/js-apis-wantAgent.md). +- Playback state information. +```js +// Set the session metadata. +let metadata = { + assetId: "121278", + title: "lose yourself", + artist: "Eminem", + author: "ST", + album: "Slim shady", + writer: "ST", + composer: "ST", + duration: 2222, + mediaImage: "https://www.example.com/example.jpg", // Set it based on your project requirements. + subtitle: "8 Mile", + description: "Rap", + lyric: "https://www.example.com/example.lrc", // Set it based on your project requirements. + previousAssetId: "121277", + nextAssetId: "121279", +}; +currentSession.setAVMetadata(metadata).then(() => { + console.info('setAVMetadata successfully'); +}).catch((err) => { + console.info(`setAVMetadata : ERROR : ${err.message}`); +}); +``` + +```js +// Set the launcher ability. +let wantAgentInfo = { + wants: [ + { + bundleName: "com.neu.setResultOnAbilityResultTest1", + abilityName: "com.example.test.MainAbility", + } + ], + operationType: wantAgent.OperationType.START_ABILITIES, + requestCode: 0, + wantAgentFlags:[wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] +} + +wantAgent.getWantAgent(wantAgentInfo).then((agent) => { + currentSession.setLaunchAbility(agent).then(() => { + console.info('setLaunchAbility successfully'); + }).catch((err) => { + console.info(`setLaunchAbility : ERROR : ${err.message}`); + }); +}); +``` + +```js +// Set the playback state information. +let PlaybackState = { + state: avSession.PlaybackState.PLAYBACK_STATE_STOP, + speed: 1.0, + position:{elapsedTime: 0, updateTime: (new Date()).getTime()}, + bufferedTime: 1000, + loopMode: avSession.LoopMode.LOOP_MODE_SEQUENCE, + isFavorite: false, +}; +currentSession.setAVPlaybackState(PlaybackState).then(() => { + console.info('setAVPlaybackState successfully'); +}).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); +}); +``` + +```js +// Obtain the controller of this session. +currentSession.getController().then((selfController) => { + console.info('getController successfully'); +}).catch((err) => { + console.info(`getController : ERROR : ${err.message}`); +}); +``` + +```js +// Obtain the output device information. +currentSession.getOutputDevice().then((outputInfo) => { + console.info(`getOutputDevice successfully, deviceName : ${outputInfo.deviceName}`); +}).catch((err) => { + console.info(`getOutputDevice : ERROR : ${err.message}`); +}); +``` + +4. Subscribe to control command events. +```js +// Subscribe to the 'play' command event. +currentSession.on('play', () => { + console.log ("Call AudioPlayer.play."); + // Set the playback state information. + currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PLAY}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + + +// Subscribe to the 'pause' command event. +currentSession.on('pause', () => { + console.log ("Call AudioPlayer.pause."); + // Set the playback state information. + currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PAUSE}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'stop' command event. +currentSession.on('stop', () => { + console.log ("Call AudioPlayer.stop."); + // Set the playback state information. + currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_STOP}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'playNext' command event. +currentSession.on('playNext', () => { + // When the media file is not ready, download and cache the media file, and set the 'PREPARE' state. + currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PREPARE}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); + // The media file is obtained. + currentSession.setAVMetadata({assetId: '58970105', title: 'See you tomorrow'}).then(() => { + console.info('setAVMetadata successfully'); + }).catch((err) => { + console.info(`setAVMetadata : ERROR : ${err.message}`); + }); + console.log ("Call AudioPlayer.play."); + // Set the playback state information. + let time = (new Data()).getTime(); + currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PLAY, position: {elapsedTime: 0, updateTime: time}, bufferedTime:2000}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'fastForward' command event. +currentSession.on('fastForward', () => { + console.log("Call AudioPlayer for fast forwarding."); + // Set the playback state information. + currentSession.setAVPlaybackState({speed: 2.0}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'seek' command event. +currentSession.on('seek', (time) => { + console.log("Call AudioPlayer.seek."); + // Set the playback state information. + currentSession.setAVPlaybackState({position: {elapsedTime: time, updateTime: (new Data()).getTime()}}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'setSpeed' command event. +currentSession.on('setSpeed', (speed) => { + console.log(`Call AudioPlayer to set the speed to ${speed}`); + // Set the playback state information. + currentSession.setAVPlaybackState({speed: speed}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'setLoopMode' command event. +currentSession.on('setLoopMode', (mode) => { + console.log(`The application switches to the loop mode ${mode}`); + // Set the playback state information. + currentSession.setAVPlaybackState({loopMode: mode}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); +}); + +// Subscribe to the 'toggleFavorite' command event. +currentSession.on('toggleFavorite', (assetId) => { + console.log(`The application favorites ${assetId}.`); + // Perform the switch based on the last status. + let favorite = mediaFavorite == false ? true : false; + currentSession.setAVPlaybackState({isFavorite: favorite}).then(() => { + console.info('setAVPlaybackState successfully'); + }).catch((err) => { + console.info(`setAVPlaybackState : ERROR : ${err.message}`); + }); + mediaFavorite = favorite; +}); + +// Subscribe to the key event. +currentSession.on('handleKeyEvent', (event) => { + console.log(`User presses the key ${event.keyCode}`); +}); + +// Subscribe to output device changes. +currentSession.on('outputDeviceChange', (device) => { + console.log(`Output device changed to ${device.deviceName}`); +}); +``` + +5. Release resources. +```js +// Unsubscribe from the events. +currentSession.off('play'); +currentSession.off('pause'); +currentSession.off('stop'); +currentSession.off('playNext'); +currentSession.off('playPrevious'); +currentSession.off('fastForward'); +currentSession.off('rewind'); +currentSession.off('seek'); +currentSession.off('setSpeed'); +currentSession.off('setLoopMode'); +currentSession.off('toggleFavorite'); +currentSession.off('handleKeyEvent'); +currentSession.off('outputDeviceChange'); + +// Deactivate the session and destroy the object. +currentSession.deactivate().then(() => { + currentSession.destory(); +}); +``` + +### Verification +Touch the play, pause, or next button on the media application. Check whether the media playback state changes accordingly. + +### FAQs + +1. Session Service Exception +- Symptoms + + The session service is abnormal, and the application cannot obtain a response from the session service. For example, the session service is not running or the communication with the session service fails. The error message "Session service exception" is displayed. + +- Possible causes + + The session service is killed during session restart. + +- Solution + + (1) The system retries the operation automatically. If the error persists for 3 seconds or more, stop the operation on the session or controller. + + (2) Destroy the current session or session controller and re-create it. If the re-creation fails, stop the operation on the session. + +2. Session Does Not Exist +- Symptoms + + Parameters are set for or commands are sent to the session that does not exist. The error message "The session does not exist" is displayed. + +- Possible causes + + The session has been destroyed, and no session record exists on the server. + +- Solution + + (1) If the error occurs on the application, re-create the session. If the error occurs on Media Controller, stop sending query or control commands to the session. + + (2) If the error occurs on the session service, query the current session record and pass the correct session ID when creating the controller. + +3. Session Not Activated +- Symptoms + + A control command or event is sent to the session when it is not activated. The error message "The session not active" is displayed. + +- Possible causes + + The session is in the inactive state. + +- Solution + + Stop sending the command or event. Subscribe to the session activation status, and resume the sending when the session is activated. + +## Development for the Session Control End (Media Controller) + +### Basic Concepts +- Remote projection: A local media session is projected to a remote device. The local controller sends commands to control media playback on the remote device. +- Sending key events: The controller controls media playback by sending key events. +- Sending control commands: The controller controls media playback by sending control commands. +- Sending system key events: A system application calls APIs to send system key events to control media playback. +- Sending system control commands: A system application calls APIs to send system control commands to control media playback. + +### Available APIs + +The table below lists the APIs available for the development of the session control end. The APIs use either a callback or promise to return the result. The APIs listed below use a callback, which provide the same functions as their counterparts that use a promise. For details, see [AVSession Management](../reference/apis/js-apis-avsession.md). + +Table 2 Common APIs for session control end development + +| API | Description | +| ------------------------------------------------------------------------------------------------ | ----------------- | +| getAllSessionDescriptors(callback: AsyncCallback\>>): void | Obtains the descriptors of all sessions. | +| createController(sessionId: string, callback: AsyncCallback\): void | Creates a controller. | +| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback\): void | Sends a key event. | +| getLaunchAbility(callback: AsyncCallback\): void | Obtains the launcher ability. | +| sendControlCommand(command: AVControlCommand, callback: AsyncCallback\): void | Sends a control command. | +| sendSystemAVKeyEvent(event: KeyEvent, callback: AsyncCallback\): void | Send a system key event. | +| sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback\): void | Sends a system control command. | +| castAudio(session: SessionToken \| 'all', audioDevices: Array\, callback: AsyncCallback\): void | Casts the media session to a remote device.| + +### How to Develop +1. Import the modules. +```js +import avSession from '@ohos.multimedia.avsession'; +import {Action, KeyEvent} from '@ohos.multimodalInput.KeyEvent'; +import wantAgent from '@ohos.wantAgent'; +import audio from '@ohos.multimedia.audio'; +``` + +2. Obtain the session descriptors and create a controller. +```js +// Define global variables. +let g_controller = new Array(); +let g_centerSupportCmd:Set = new Set(['play', 'pause', 'playNext', 'playPrevious', 'fastForward', 'rewind', 'seek','setSpeed', 'setLoopMode', 'toggleFavorite']); +let g_validCmd:Set; + +// Obtain the session descriptors and create a controller. +avSession.getAllSessionDescriptors().then((descriptors) => { + descriptors.forEach((descriptor) => { + avSession.createController(descriptor.sessionId).then((controller) => { + g_controller.push(controller); + }).catch((err) => { + console.error('createController error'); + }); + }); +}).catch((err) => { + console.error('getAllSessionDescriptors error'); +}); + +// Subscribe to the 'sessionCreate' event and create a controller. +avSession.on('sessionCreate', (session) => { + // After a session is added, you must create a controller. + avSession.createController(session.sessionId).then((controller) => { + g_controller.push(controller); + }).catch((err) => { + console.info(`createController : ERROR : ${err.message}`); + }); +}); +``` + +3. Subscribe to the session state and service changes. +```js +// Subscribe to the 'activeStateChange' event. +controller.on('activeStateChange', (isActive) => { + if (isActive) { + console.log ("The widget corresponding to the controller is highlighted."); + } else { + console.log("The widget corresponding to the controller is invalid."); + } +}); + +// Subscribe to the 'sessionDestroy' event to enable Media Controller to get notified when the session dies. +controller.on('sessionDestroy', () => { + console.info('on sessionDestroy : SUCCESS '); + controller.destroy().then(() => { + console.info('destroy : SUCCESS '); + }).catch((err) => { + console.info(`destroy : ERROR :${err.message}`); + }); +}); + +// Subscribe to the 'sessionDestroy' event to enable the application to get notified when the session dies. +avSession.on('sessionDestroy', (session) => { + let index = g_controller.findIndex((controller) => { + return controller.sessionId == session.sessionId; + }); + if (index != 0) { + g_controller[index].destroy(); + g_controller.splice(index, 1); + } +}); + +// Subscribe to the 'topSessionChange' event. +avSession.on('topSessionChange', (session) => { + let index = g_controller.findIndex((controller) => { + return controller.sessionId == session.sessionId; + }); + // Place the session on the top. + if (index != 0) { + g_controller.sort((a, b) => { + return a.sessionId == session.sessionId ? -1 : 0; + }); + } +}); + +// Subscribe to the 'sessionServiceDie' event. +avSession.on('sessionServiceDie', () => { + // The server is abnormal, and the application clears resources. + console.log("Server exception"); +}) +``` + +4. Subscribe to media session information changes. +```js +// Subscribe to metadata changes. +let metaFilter = ['assetId', 'title', 'description']; +controller.on('metadataChange', metaFilter, (metadata) => { + console.info(`on metadataChange assetId : ${metadata.assetId}`); +}); + +// Subscribe to playback state changes. +let playbackFilter = ['state', 'speed', 'loopMode']; +controller.on('playbackStateChange', playbackFilter, (playbackState) => { + console.info(`on playbackStateChange state : ${playbackState.state}`); +}); + +// Subscribe to supported command changes. +controller.on('validCommandChange', (cmds) => { + console.info(`validCommandChange : SUCCESS : size : ${cmds.size}`); + console.info(`validCommandChange : SUCCESS : cmds : ${cmds.values()}`); + g_validCmd.clear(); + for (let c of g_centerSupportCmd) { + if (cmds.has(c)) { + g_validCmd.add(c); + } + } +}); + +// Subscribe to output device changes. +controller.on('outputDeviceChange', (device) => { + console.info(`on outputDeviceChange device isRemote : ${device.isRemote}`); +}); +``` + +5. Control the session behavior. +```js +// When the user touches the play button, the control command 'play' is sent to the session. +if (g_validCmd.has('play')) { + controller.sendControlCommand({command:'play'}).then(() => { + console.info('sendControlCommand successfully'); + }).catch((err) => { + console.info(`sendControlCommand : ERROR : ${err.message}`); + }); +} + +// When the user selects the single loop mode, the corresponding control command is sent to the session. +if (g_validCmd.has('setLoopMode')) { + controller.sendControlCommand({command: 'setLoopMode', parameter: avSession.LoopMode.LOOP_MODE_SINGLE}).then(() => { + console.info('sendControlCommand successfully'); + }).catch((err) => { + console.info(`sendControlCommand : ERROR : ${err.message}`); + }); +} + +// Send a key event. +let keyItem = {code: 0x49, pressedTime: 123456789, deviceId: 0}; +let event = {action: 2, key: keyItem, keys: [keyItem]}; +controller.sendAVKeyEvent(event).then(() => { + console.info('sendAVKeyEvent Successfully'); +}).catch((err) => { + console.info(`sendAVKeyEvent : ERROR : ${err.message}`); +}); + +// The user touches the blank area on the widget to start the application. +controller.getLaunchAbility().then((want) => { + console.log("Starting the application in the foreground"); +}).catch((err) => { + console.info(`getLaunchAbility : ERROR : ${err.message}`); +}); + +// Send the system key event. +let keyItem = {code: 0x49, pressedTime: 123456789, deviceId: 0}; +let event = {action: 2, key: keyItem, keys: [keyItem]}; +avSession.sendSystemAVKeyEvent(event).then(() => { + console.info('sendSystemAVKeyEvent Successfully'); +}).catch((err) => { + console.info(`sendSystemAVKeyEvent : ERROR : ${err.message}`); +}); + +// Send a system control command to the top session. +let avcommand = {command: 'toggleFavorite', parameter: "false"}; +avSession.sendSystemControlCommand(avcommand).then(() => { + console.info('sendSystemControlCommand successfully'); +}).catch((err) => { + console.info(`sendSystemControlCommand : ERROR : ${err.message}`); +}); + +// Cast the session to another device. +let audioManager = audio.getAudioManager(); +let audioDevices; +await audioManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { + audioDevices = data; + console.info('Promise returned to indicate that the device list is obtained.'); +}).catch((err) => { + console.info(`getDevices : ERROR : ${err.message}`); +}); + +avSession.castAudio('all', audioDevices).then(() => { + console.info('createController : SUCCESS'); +}).catch((err) => { + console.info(`createController : ERROR : ${err.message}`); +}); +``` + +6. Release resources. +```js +// Unsubscribe from the events. + controller.off('metadataChange'); + controller.off('playbackStateChange'); + controller.off('sessionDestroy'); + controller.off('activeStateChange'); + controller.off('validCommandChange'); + controller.off('outputDeviceChange'); + + // Destroy the controller. + controller.destroy().then(() => { + console.info('destroy : SUCCESS '); + }).catch((err) => { + console.info(`destroy : ERROR : ${err.message}`); + }); +``` + +### Verification +When you touch the play, pause, or next button in Media Controller, the playback state of the application changes accordingly. + +### FAQs +1. Controller Does Not Exist +- Symptoms + + A control command or an event is sent to the controller that does not exist. The error message "The session controller does not exist" is displayed. + +- Possible causes + + The controller has been destroyed. + +- Solution + + Query the session record and create the corresponding controller. + +2. Remote Session Connection Failure +- Symptoms + + The communication between the local session and the remote session fails. The error information "The remote session connection failed" is displayed. + +- Possible causes + + The communication between devices is interrupted. + +- Solution + + Stop sending control commands to the session. Subscribe to output device changes, and resume the sending when the output device is changed. + +3. Invalid Session Command +- Symptoms + + The control command or event sent to the session is not supported. The error message "Invalid session command" is displayed. + +- Possible causes + + The session does not support this command. + +- Solution + + Stop sending the command or event. Query the commands supported by the session, and send a command supported. + +4. Too Many Commands or Events +- Symptoms + + The session client sends too many messages or commands to the server in a period of time, causing the server to be overloaded. The error message "Command or event overload" is displayed. + +- Possible causes + + The server is overloaded with messages or events. + +- Solution + + Control the frequency of sending commands or events. diff --git a/en/application-dev/media/avsession-overview.md b/en/application-dev/media/avsession-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..761483bf5052ef48cd9313261ead681b295d6604 --- /dev/null +++ b/en/application-dev/media/avsession-overview.md @@ -0,0 +1,52 @@ +# AVSession Overview + +## Overview + + AVSession, short for audio and video session, is also known as media session. + - Application developers can use the APIs provided by the **AVSession** module to connect their audio and video applications to the system's Media Controller. + - System developers can use the APIs provided by the **AVSession** module to display media information of system audio and video applications and carry out unified playback control. + + You can implement the following features through the **AVSession** module: + + 1. Unified playback control entry + + If there are multiple audio and video applications on the device, users need to switch to and access different applications to control media playback. With AVSession, a unified playback control entry of the system (such as Media Controller) is used for playback control of these audio and video applications. No more switching is required. + + 2. Better background application management + + When an application running in the background automatically starts audio playback, it is difficult for users to locate the application. With AVSession, users can quickly find the application that plays the audio clip in Media Controller. + +## Basic Concepts + +- AVSession + + A channel used for information exchange between applications and Media Controller. For AVSession, one end is the media application under control, and the other end is Media Controller. Through AVSession, an application can transfer the media playback information to Media Controller and receive control commands from Media Controller. + +- AVSessionController + + Object that controls media sessions and thereby controls the playback behavior of applications. Through AVSessionController, Media Controller can control the playback behavior of applications, obtain playback information, and send control commands. It can also monitor the playback state of applications to ensure synchronization of the media session information. + +- Media Controller + + Holder of AVSessionController. Through AVSessionController, Media Controller sends commands to control media playback of applications. + +## Implementation Principle + +The **AVSession** module provides two classes: **AVSession** and **AVSessionController**. + +**Figure 1** AVSession interaction + +![en-us_image_avsession](figures/en-us_image_avsession.png) + +- Interaction between the application and Media Controller: First, an audio application creates an **AVSession** object and sets session information, including media metadata, launcher ability, and playback state information. Then, Media Controller creates an **AVSessionController** object to obtain session-related information and send the 'play' command to the audio application. Finally, the audio application responds to the command and updates the playback state. + +- Distributed projection: When a connected device creates a local session, Media Controller or the audio application can select another device to be projected based on the device list, synchronize the local session to the remote device, and generate a controllable remote session. The remote session is controlled by sending control commands to the remote device's application through its AVSessionController. + +## Constraints + +- The playback information displayed in Media Controller is the media information proactively written by the media application to AVSession. +- Media Controller controls the playback of a media application based on the responses of the media application to control commands. +- AVSession can transmit media playback information and control commands. It does not display information or execute control commands. +- Do not develop Media Controller for common applications. For common audio and video applications running on OpenHarmony, the default control end is Media Controller, which is a system application. You do not need to carry out additional development for Media Controller. +- If you want to develop your own system running OpenHarmony, you can develop your own Media Controller. +- For better background management of audio and video applications, the **AVSession** module enforces background control for third-party applications. Only third-party applications that have accessed AVSession can play audio in the background. Otherwise, the system forcibly pauses the playback when a third-party application switches to the background. diff --git a/en/application-dev/media/figures/en-us_image_audio_routing_manager.png b/en/application-dev/media/figures/en-us_image_audio_routing_manager.png new file mode 100644 index 0000000000000000000000000000000000000000..710679f6cac0c30d06dffa97b0e80b3cebe80f79 Binary files /dev/null and b/en/application-dev/media/figures/en-us_image_audio_routing_manager.png differ diff --git a/en/application-dev/media/figures/en-us_image_audio_state_machine.png b/en/application-dev/media/figures/en-us_image_audio_state_machine.png index 7497edd0edbdcfccbc448e9f2f48268ebb75e72e..22b7aeaa1db5b369d3daf44854d7f7f9a00f775b 100644 Binary files a/en/application-dev/media/figures/en-us_image_audio_state_machine.png and b/en/application-dev/media/figures/en-us_image_audio_state_machine.png differ diff --git a/en/application-dev/media/figures/en-us_image_audio_volume_manager.png b/en/application-dev/media/figures/en-us_image_audio_volume_manager.png new file mode 100644 index 0000000000000000000000000000000000000000..0d47fbfacce9c1ff48811e1cf5d764231bdb596b Binary files /dev/null and b/en/application-dev/media/figures/en-us_image_audio_volume_manager.png differ diff --git a/en/application-dev/media/figures/en-us_image_avsession.png b/en/application-dev/media/figures/en-us_image_avsession.png new file mode 100644 index 0000000000000000000000000000000000000000..3289bc4ca3c54eb3e99c9230c821380f8f7c0c5b Binary files /dev/null and b/en/application-dev/media/figures/en-us_image_avsession.png differ diff --git a/en/application-dev/media/image.md b/en/application-dev/media/image.md index f3bb5fc9b59c8b290692e877033e78a5d9d4edef..048716dfdcd76d0e35f4ed3ad70a5eeb266ac8cc 100644 --- a/en/application-dev/media/image.md +++ b/en/application-dev/media/image.md @@ -21,23 +21,27 @@ let opts = { alphaType: 0, editable: true, pixelFormat: 4, scaleMode: 1, size: { // Create a PixelMap object. const color = new ArrayBuffer(96); let opts = { alphaType: 0, editable: true, pixelFormat: 4, scaleMode: 1, size: { height: 2, width: 3 } } -image.createPixelMap(color, opts, pixelmap => { +image.createPixelMap(color, opts, (err, pixelmap) => { console.log('Succeeded in creating pixelmap.'); }) // Read pixels. -pixelmap.readPixels(area,(data) => { - if(data !== null) { - var bufferArr = new Uint8Array(area.pixels); - var res = true; - for (var i = 0; i < bufferArr.length; i++) { - console.info(' buffer ' + bufferArr[i]); - if(res) { - if(bufferArr[i] == 0) { - res = false; - console.log('readPixels end.'); - break; - } +const area = { + pixels: new ArrayBuffer(8), + offset: 0, + stride: 8, + region: { size: { height: 1, width: 2 }, x: 0, y: 0 } +} +pixelmap.readPixels(area,() => { + var bufferArr = new Uint8Array(area.pixels); + var res = true; + for (var i = 0; i < bufferArr.length; i++) { + console.info(' buffer ' + bufferArr[i]); + if(res) { + if(bufferArr[i] == 0) { + res = false; + console.log('readPixels end.'); + break; } } } @@ -96,7 +100,7 @@ pixelmap.writeBufferToPixels(writeColor).then(() => { }) // Obtain image information. -pixelmap.getImageInfo( imageInfo => { +pixelmap.getImageInfo((error, imageInfo) => { if (imageInfo !== null) { console.log('Succeeded in getting imageInfo'); } @@ -128,7 +132,7 @@ imageSourceApi.release(() => { const imagePackerApi = image.createImagePacker(); const imageSourceApi = image.createImageSource(0); let packOpts = { format:"image/jpeg", quality:98 }; -imagePackerApi.packing(imageSourceApi, packOpts, data => { +imagePackerApi.packing(imageSourceApi, packOpts, (err, data) => { console.log('Succeeded in packing'); }) @@ -156,7 +160,7 @@ let decodingOptions = { }; // Create a pixel map in callback mode. -imageSourceApi.createPixelMap(decodingOptions, pixelmap => { +imageSourceApi.createPixelMap(decodingOptions, (err, pixelmap) => { console.log('Succeeded in creating pixelmap.'); }) @@ -171,17 +175,13 @@ catch(error => { }) // Obtain the number of bytes in each line of pixels. -pixelmap.getBytesNumberPerRow( num => { - console.log('Succeeded in getting BytesNumber PerRow.'); -}) +var num = pixelmap.getBytesNumberPerRow(); // Obtain the total number of pixel bytes. -pixelmap.getPixelBytesNumber(num => { - console.log('Succeeded in getting PixelBytesNumber.'); -}) +var pixelSize = pixelmap.getPixelBytesNumber(); // Obtain the pixel map information. -pixelmap.getImageInfo( imageInfo => {}) +pixelmap.getImageInfo().then( imageInfo => {}); // Release the PixelMap object. pixelmap.release(()=>{ @@ -229,7 +229,7 @@ imagePackerApi.packing(imageSourceApi, packOpts) imagePackerApi.release(); // Obtain the image source information. -imageSourceApi.getImageInfo(imageInfo => { +imageSourceApi.getImageInfo((err, imageInfo) => { console.log('Succeeded in getting imageInfo'); }) @@ -249,8 +249,9 @@ public async init(surfaceId: any) { var receiver = image.createImageReceiver(8 * 1024, 8, image.ImageFormat.JPEG, 1); // Obtain the surface ID. - var surfaceId = await receiver.getReceivingSurfaceId(); - + receiver.getReceivingSurfaceId((err, surfaceId) => { + console.info("receiver getReceivingSurfaceId success"); + }); // Register a surface listener, which is triggered after the buffer of the surface is ready. receiver.on('imageArrival', () => { // Obtain the latest buffer of the surface. diff --git a/en/application-dev/napi/drawing-guidelines.md b/en/application-dev/napi/drawing-guidelines.md index 7cbf0e3d9e10bb6d8d346e8f6a9910771c523434..1355a27dcf7fb5e54a283ccd5c39a4f1b19de381 100644 --- a/en/application-dev/napi/drawing-guidelines.md +++ b/en/application-dev/napi/drawing-guidelines.md @@ -4,11 +4,11 @@ The Native Drawing module provides APIs for drawing 2D graphics and text. The following scenarios are common for drawing development: * Drawing 2D graphics -* Drawing and painting text +* Drawing text drawing ## Available APIs -| API| Description| +| API| Description| | -------- | -------- | | OH_Drawing_BitmapCreate (void) | Creates a bitmap object.| | OH_Drawing_BitmapBuild (OH_Drawing_Bitmap *, const uint32_t width, const uint32_t height, const OH_Drawing_BitmapFormat *) | Initializes the width and height of a bitmap object and sets the pixel format for the bitmap.| @@ -19,7 +19,7 @@ The Native Drawing module provides APIs for drawing 2D graphics and text. The fo | OH_Drawing_CanvasDrawPath (OH_Drawing_Canvas *, const OH_Drawing_Path *) | Draws a path.| | OH_Drawing_PathCreate (void) | Creates a path object.| | OH_Drawing_PathMoveTo (OH_Drawing_Path *, float x, float y) | Sets the start point of a path.| -| OH_Drawing_PathLineTo (OH_Drawing_Path *, float x, float y) | Draws a line segment from the last point of a path to the target point. | +| OH_Drawing_PathLineTo (OH_Drawing_Path *, float x, float y) | Draws a line segment from the last point of a path to the target point.| | OH_Drawing_PathClose (OH_Drawing_Path *) | Closes a path. A line segment from the start point to the last point of the path is added.| | OH_Drawing_PenCreate (void) | Creates a pen object.| | OH_Drawing_PenSetAntiAlias (OH_Drawing_Pen *, bool) | Checks whether anti-aliasing is enabled for a pen. If anti-aliasing is enabled, edges will be drawn with partial transparency.| @@ -138,7 +138,7 @@ The following steps describe how to use the canvas and brush of the Native Drawi OH_Drawing_BitmapDestory(cBitmap); ``` -## Development Procedure for Text Drawing and Display +## Development Procedure for Text Drawing The following steps describe how to use the text drawing and display feature of the Native Drawing module. 1. **Create a canvas and a bitmap.** @@ -196,7 +196,8 @@ The following steps describe how to use the text drawing and display feature of // Set the maximum width. double maxWidth = 800.0; OH_Drawing_TypographyLayout(typography, maxWidth); - // Set the start position for text display. + // Set the start position for drawing the text on the canvas. double position[2] = {10.0, 15.0}; + // Draw the text on the canvas. OH_Drawing_TypographyPaint(typography, cCanvas, position[0], position[1]); ``` diff --git a/en/application-dev/napi/native-window-guidelines.md b/en/application-dev/napi/native-window-guidelines.md index b92ccc54234c9162dad4b35242dcf9d992e5eeec..a71a261c8d2dc6cee74e79deff99d50814a00007 100644 --- a/en/application-dev/napi/native-window-guidelines.md +++ b/en/application-dev/napi/native-window-guidelines.md @@ -1,107 +1,99 @@ -# NativeWindow Development +# Native Window Development ## When to Use -`NativeWindow` is a local platform window of OpenHarmony. It provides APIs for you to create a native window from `Surface`, create a native window buffer from `SurfaceBuffer`, and request and flush a buffer. +**NativeWindow** is a local platform-based window of OpenHarmony that represents the producer of a graphics queue. It provides APIs for you to create a native window from **Surface**, create a native window buffer from **SurfaceBuffer**, and request and flush a buffer. The following scenarios are common for native window development: -* Drawing content using native C++ code and displaying the content on the screen -* Requesting and flushing a buffer when adapting to EGL `eglswapbuffer` +* Request a graphics buffer by using the NAPI provided by **NativeWindow**, write the produced graphics content to the buffer, and flush the buffer to the graphics queue. +* Request and flush a buffer when adapting to the **eglswapbuffer** interface at the EGL. ## Available APIs | API| Description| | -------- | -------- | -| OH_NativeWindow_CreateNativeWindowFromSurface (void \*pSurface) | Creates a `NativeWindow` instance. A new `NativeWindow` instance is created each time this function is called.| -| OH_NativeWindow_DestroyNativeWindow (struct NativeWindow \*window) | Decreases the reference count of a `NativeWindow` instance by 1 and, when the reference count reaches 0, destroys the instance.| -| OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void \*pSurfaceBuffer) | Creates a `NativeWindowBuffer` instance. A new `NativeWindowBuffer` instance is created each time this function is called.| -| OH_NativeWindow_DestroyNativeWindowBuffer (struct NativeWindowBuffer \*buffer) | Decreases the reference count of a `NativeWindowBuffer` instance by 1 and, when the reference count reaches 0, destroys the instance.| -| OH_NativeWindow_NativeWindowRequestBuffer (struct NativeWindow \*window struct NativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests a `NativeWindowBuffer` through a `NativeWindow` instance for content production.| -| OH_NativeWindow_NativeWindowFlushBuffer (struct NativeWindow \*window, struct NativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the `NativeWindowBuffer` filled with the content to the buffer queue through a `NativeWindow` instance for content consumption.| -| OH_NativeWindow_NativeWindowCancelBuffer (struct NativeWindow \*window, struct NativeWindowBuffer \*buffer) | Returns the `NativeWindowBuffer` to the buffer queue through a `NativeWindow` instance, without filling in any content. The `NativeWindowBuffer` can be used for another request.| -| OH_NativeWindow_NativeWindowHandleOpt (struct NativeWindow \*window, int code,...) | Sets or obtains the attributes of a native window, including the width, height, and content format.| -| OH_NativeWindow_GetBufferHandleFromNative (struct NativeWindowBuffer \*buffer) | Obtains the pointer to a `BufferHandle` of a `NativeWindowBuffer` instance.| +| OH_NativeWindow_CreateNativeWindowFromSurface (void \*pSurface) | Creates a **NativeWindow** instance. A new **NativeWindow** instance is created each time this function is called.| +| OH_NativeWindow_DestroyNativeWindow (OHNativeWindow \*window) | Decreases the reference count of a **NativeWindow** instance by 1 and, when the reference count reaches 0, destroys the instance.| +| OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void \*pSurfaceBuffer) | Creates a **NativeWindowBuffer** instance. A new **NativeWindowBuffer** instance is created each time this function is called.| +| OH_NativeWindow_DestroyNativeWindowBuffer (OHNativeWindowBuffer \*buffer) | Decreases the reference count of a **NativeWindowBuffer** instance by 1 and, when the reference count reaches 0, destroys the instance.| +| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests a **NativeWindowBuffer** through a **NativeWindow** instance for content production.| +| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the **NativeWindowBuffer** filled with the content to the buffer queue through a **NativeWindow** instance for content consumption.| +| OH_NativeWindow_NativeWindowAbortBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer) | Returns the **NativeWindowBuffer** to the buffer queue through a **NativeWindow** instance, without filling in any content. The **NativeWindowBuffer** can be used for another request.| +| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of a native window, including the width, height, and content format.| +| OH_NativeWindow_GetBufferHandleFromNative (OHNativeWindowBuffer \*buffer) | Obtains the pointer to a **BufferHandle** of a **NativeWindowBuffer** instance.| | OH_NativeWindow_NativeObjectReference (void \*obj) | Adds the reference count of a native object.| | OH_NativeWindow_NativeObjectUnreference (void \*obj) | Decreases the reference count of a native object and, when the reference count reaches 0, destroys this object.| | OH_NativeWindow_GetNativeObjectMagic (void \*obj) | Obtains the magic ID of a native object.| - +| OH_NativeWindow_NativeWindowSetScalingMode (OHNativeWindow \*window, uint32_t sequence, OHScalingMode scalingMode) | Sets the scaling mode of the native window.| +| OH_NativeWindow_NativeWindowSetMetaData(OHNativeWindow \*window, uint32_t sequence, int32_t size, const OHHDRMetaData \*metaData) | Sets the HDR static metadata of the native window.| +| OH_NativeWindow_NativeWindowSetMetaDataSet(OHNativeWindow \*window, uint32_t sequence, OHHDRMetadataKey key, int32_t size, const uint8_t \*metaData) | Sets the HDR static metadata set of the native window.| +| OH_NativeWindow_NativeWindowSetTunnelHandle(OHNativeWindow \*window, const OHExtDataHandle \*handle) | Sets the tunnel handle to the native window.| ## How to Develop -The following steps describe how to use `OH_NativeXComponent` in OpenHarmony to draw content using native C++ code and display the content on the screen. - -1. Define an `XComponent` of the `texture` type in `index.ets` for content display. - ```js - XComponent({ id: 'xcomponentId', type: 'texture', libraryname: 'nativerender'}) - .borderColor(Color.Red) - .borderWidth(5) - .onLoad(() => {}) - .onDestroy(() => {}) - ``` - -2. Obtain an `OH_NativeXComponent` instance (named `nativeXComponent` in this example) by calling `napi_get_named_property`, and obtain a `NativeWindow` instance by registering the callback of the `OH_NativeXComponent` instance. +The following describes how to use the NAPI provided by **NativeWindow** to request a graphics buffer, write the produced graphics content to the buffer, and flush the buffer to the graphics queue. +1. Obtain a **NativeWindow** instance. For example, use **Surface** to create a **NativeWindow** instance. ```c++ - // Define a NAPI instance. - napi_value exportInstance = nullptr; - // Define an OH_NativeXComponent instance. - OH_NativeXComponent *nativeXComponent = nullptr; - // Use the OH_NATIVE_XCOMPONENT_OBJ export instance. - napi_getname_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance); - // Convert the NAPI instance to the OH_NativeXComponent instance. - napi_unwarp(env, exportInstance, reinterpret_cast(&nativeXComponent)); + sptr cSurface = Surface::CreateSurfaceAsConsumer(); + sptr listener = new BufferConsumerListenerTest(); + cSurface->RegisterConsumerListener(listener); + sptr producer = cSurface->GetProducer(); + sptr pSurface = Surface::CreateSurfaceAsProducer(producer); + OHNativeWindow* nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface); ``` -3. Define the callback `OnSurfaceCreated`. During the creation of a `Surface`, the callback is used to initialize the rendering environment, for example, the `Skia` rendering environment, and write the content to be displayed to `NativeWindow`. - +2. Set the attributes of a native window buffer by using **OH_NativeWindow_NativeWindowHandleOpt**. ```c++ - void OnSurfaceCreatedCB(NativeXComponent* component, void* window) { - // Obtain the width and height of the native window. - uint64_t width_ = 0, height_ = 0; - OH_NativeXComponent_GetXComponentSize(nativeXComponent, window, &width_, &height_); - // Convert void* into a NativeWindow instance. NativeWindow is defined in native_window/external_window.h. - NativeWindow* nativeWindow_ = (NativeWindow*)(window); - - // Set or obtain the NativeWindow attributes by calling OH_NativeWindow_NativeWindowHandleOpt. - // 1. Use SET_USAGE to set the usage attribute of the native window, for example, to HBM_USE_CPU_READ. - OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_USAGE, HBM_USE_CPU_READ | HBM_USE_CPU_WRITE |HBM_USE_MEM_DMA); - // 2. Use SET_BUFFER_GEOMETRY to set the width and height attributes of the native window. - OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_BUFFER_GEOMETRY, width_, height_); - // 3. Use SET_FORMAT to set the format attribute of the native window, for example, to PIXEL_FMT_RGBA_8888. - OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_FORMAT, PIXEL_FMT_RGBA_8888); - // 4. Use SET_STRIDE to set the stride attribute of the native window. - OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_STRIDE, 0x8); - - // Obtain the NativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer. - struct NativeWindowBuffer* buffer = nullptr; - int fenceFd; - OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd); - - // Obtain the buffer handle by calling OH_NativeWindow_GetNativeBufferHandleFromNative. - BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer); + // Set the read and write scenarios of the native window buffer. + int code = SET_USAGE; + int32_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA; + int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage); + // Set the width and height of the native window buffer. + code = SET_BUFFER_GEOMETRY; + int32_t width = 0x100; + int32_t height = 0x100; + ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height); + // Set the step of the native window buffer. + code = SET_STRIDE; + int32_t stride = 0x8; + ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride); + // Set the format of the native window buffer. + code = SET_FORMAT; + int32_t format = PIXEL_FMT_RGBA_8888; + ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format); + ``` - // Create a Skia bitmap using BufferHandle. - SkBitmap bitmap; - SkImageInfo imageInfo = ... - bitmap.setInfo(imageInfo, bufferHandle->stride); - bitmap.setPixels(bufferHandle->virAddr); - // Create Skia Canvas and write the content to the native window. - ... +3. Request a native window buffer from the graphics queue. + ```c++ + struct NativeWindowBuffer* buffer = nullptr; + int fenceFd; + // Obtain the NativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer. + OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd); + // Obtain the buffer handle by calling OH_NativeWindow_GetNativeBufferHandleFromNative. + BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer); + ``` - // After the write operation is complete, flush the buffer by using OH_NativeWindow_NativeWindowFlushBuffer so that the data is displayed on the screen. - Region region{nullptr, 0}; - OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region) +4. Write the produced content to the native window buffer. + ```c++ + auto image = static_cast(buffer->sfbuffer->GetVirAddr()); + static uint32_t value = 0x00; + value++; + + uint32_t *pixel = static_cast(image); + for (uint32_t x = 0; x < width; x++) { + for (uint32_t y = 0; y < height; y++) { + *pixel++ = value; + } } ``` -4. Register the callback `OnSurfaceCreated` by using `OH_NativeXComponent_RegisterCallback`. +5. Flush the native window buffer to the graphics queue. ```c++ - OH_NativeXComponent_Callback &callback_; - callback_->OnSurfaceCreated = OnSurfaceCreatedCB; - callback_->OnSurfaceChanged = OnSurfaceChangedCB; - callback_->OnSurfaceDestoryed = OnSurfaceDestoryedCB; - callback_->DispatchTouchEvent = DispatchTouchEventCB; - OH_NativeXComponent_RegisterCallback(nativeXComponent, callback_) + // Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the native window buffer are changed. + Region region{nullptr, 0}; + // Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen. + OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region); ``` diff --git a/en/application-dev/notification/background-agent-scheduled-reminder-guide.md b/en/application-dev/notification/background-agent-scheduled-reminder-guide.md index b789e20218f1d8508ce5dbf1b515179e6f23b9ef..71ffeb0b07acfb088988163a68f72882d267f49b 100644 --- a/en/application-dev/notification/background-agent-scheduled-reminder-guide.md +++ b/en/application-dev/notification/background-agent-scheduled-reminder-guide.md @@ -37,7 +37,7 @@ For details about the APIs, see [reminderAgent](../reference/apis/js-apis-remind import reminderAgent from '@ohos.reminderAgent'; import notification from '@ohos.notification'; export default { - // eTS project: + // ArkTS project: let timer : reminderAgent.ReminderRequestTimer = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 10, @@ -67,7 +67,7 @@ For details about the APIs, see [reminderAgent](../reference/apis/js-apis-remind Sample code for defining a reminder agent for a calendar event: ```js - // eTS project: + // ArkTS project: let calendar : reminderAgent.ReminderRequestCalendar = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, dateTime: { @@ -113,7 +113,7 @@ For details about the APIs, see [reminderAgent](../reference/apis/js-apis-remind Sample code for defining a reminder agent for an alarm: ```js - // eTS project: + // ArkTS project: let alarm : reminderAgent.ReminderRequestAlarm = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, hour: 11, diff --git a/en/application-dev/quick-start/Readme-EN.md b/en/application-dev/quick-start/Readme-EN.md index 0a7533ea2389f74866ced1742937daeffe134fcc..9b89cfd83f8a3af29bda3fe76016d269561282cb 100644 --- a/en/application-dev/quick-start/Readme-EN.md +++ b/en/application-dev/quick-start/Readme-EN.md @@ -1,12 +1,22 @@ # Quick Start - - Getting Started - - [Preparations](start-overview.md) - - [Getting Started with eTS in Stage Model](start-with-ets-stage.md) - - [Getting Started with eTS in FA Model](start-with-ets-fa.md) - - [Getting Started with JavaScript in FA Model](start-with-js-fa.md) + - [Before You Start](start-overview.md) + - [Getting Started with ArkTS in Stage Model](start-with-ets-stage.md) + - [Getting Started with ArkTS in FA Model](start-with-ets-fa.md) + - [Getting Started with JavaScript in FA Model](start-with-js-fa.md) - Development Fundamentals - [Application Package Structure Configuration File (FA Model)](package-structure.md) - [Application Package Structure Configuration File (Stage Model)](stage-structure.md) - [SysCap](syscap.md) - - [HarmonyAppProvision Configuration File](app-provision-structure.md) + - [Resource Categories and Access](resource-categories-and-access.md) + - Learning ArkTS + - [Getting Started with ArkTS](arkts-get-started.md) + - ArkTS Syntax (Declarative UI) + - [Basic UI Description](arkts-basic-ui-description.md) + - State Management + - [Basic Concepts](arkts-state-mgmt-concepts.md) + - [State Management with Page-level Variables](arkts-state-mgmt-page-level.md) + - [State Management with Application-level Variables](arkts-state-mgmt-application-level.md) + - [Dynamic UI Element Building](arkts-dynamic-ui-elememt-building.md) + - [Rendering Control](arkts-rendering-control.md) + - [Restrictions and Extensions](arkts-restrictions-and-extensions.md) \ No newline at end of file diff --git a/en/application-dev/quick-start/arkts-basic-ui-description.md b/en/application-dev/quick-start/arkts-basic-ui-description.md new file mode 100644 index 0000000000000000000000000000000000000000..d20efe12859e944d9d78fb71688dc4aada729228 --- /dev/null +++ b/en/application-dev/quick-start/arkts-basic-ui-description.md @@ -0,0 +1,205 @@ +# Basic UI Description + +In ArkTS, you define a custom component by using decorators **@Component** and **@Entry** to decorate a data structure declared with the **struct** keyword. A custom component provides a **build** function, where you must write the basic UI description in chain call mode. For details about the UI description, see [UI Description Specifications](#ui-description-specifications). + +## Basic Concepts + +- struct: a data structure that can be used to implement custom components and cannot have inheritance. The **new** keyword can be omitted when initializing a struct. + +- Decorator: a special type of declaration that can be applied to classes, structures, or class attributes to add new functionality to them. Multiple decorators can be applied to the same target element and defined on a single line or multiple lines. It is recommended that the decorators be defined on multiple lines. + + ```ts + @Entry + @Component + struct MyComponent { + } + ``` + +- **build** function: a function that complies with the **Builder** API definition and is used to define the declarative UI description of components. A **build** function must be defined for custom components, and custom constructors are prohibited for custom components. + + ```ts + interface Builder { + build: () => void + } + ``` + +- **@Component**: a decorator applied to a struct to equip it with the component-based capability. The **build** method must be implemented for UI creation. + +- **@Entry**: a decorator applied to a struct to make it the entry to a page, which is rendered and displayed when the page is loaded. + +- **@Preview**: a decorator applied to struct to make it previewable in the DevEco Studio Previewer. The decorated component is created and displayed when the residing page is loaded. + + > **NOTE** + > + > In a single source file, you can use up to 10 **@Preview** decorators to decorate custom components. For details, see [Previewing ArkTS Components](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-previewing-app-service-0000001218760596#section146052489820). + +- Chain call: a syntax for configuring the attribute methods, event methods, and more of UI components by using the dot notation. + +## UI Description Specifications + +### Structs Without Parameters + +A struct without parameters is a component whose API definition has empty parentheses. No parameter needs to be passed to this type of component, for example, the **Divider** component in the following snippet: + +```ts +Column() { + Text('item 1') + Divider() + Text('item 2') +} +``` + +### Structs with Mandatory Parameters + +A struct with mandatory parameters is a component whose API definition expects parameters enclosed in the parentheses. You can use constants to assign values to the parameters. + +Sample code: + +- Set the mandatory parameter **src** of the **\** component as follows: + + ```ts + Image('https://xyz/test.jpg') + ``` + +- Set the mandatory parameter **content** of the **\** component as follows: + + ```ts + Text('test') + ``` + +You can use variables or expressions to assign values to parameters. The result type returned by an expression must meet the parameter type requirements. For details about the variables, see [State Management with Page-level Variables](arkts-state-mgmt-page-level.md) and [State Management with Application-level Variables](arkts-state-mgmt-application-level.md). For example, set a variable or expression to construct the **\** and **\** components: + +```ts +Image(this.imagePath) +Image('https://' + this.imageUrl) +Text(`count: ${this.count}`) +``` + +### Attribute Configuration + +Component attributes are configured using an attribute method, which follows the corresponding component and is bound to the component using the "**.**" operator. + +- Example of configuring the font size attribute of the **\** component: + + ```ts + Text('test') + .fontSize(12) + ``` + +- Example of configuring multiple attributes at the same time by using the "**.**" operator to implement chain call: + + ```ts + Image('test.jpg') + .alt('error.jpg') + .width(100) + .height(100) + ``` + +- Example of passing variables or expressions in addition to constants: + + ```ts + Text('hello') + .fontSize(this.size) + Image('test.jpg') + .width(this.count % 2 === 0 ? 100 : 200) + .height(this.offset + 100) + ``` + +- For attributes of built-in components, ArkUI also provides some predefined [enumeration types](../reference/arkui-ts/ts-appendix-enums.md), which you can pass as parameters to methods if they meet the parameter type requirements. For example, you can configure the font color and weight attributes of the **\** component as follows: + + ```ts + Text('hello') + .fontSize(20) + .fontColor(Color.Red) + .fontWeight(FontWeight.Bold) + ``` + +### Event Configuration + +Events supported by components are configured using event methods, which each follow the corresponding component and are bound to the component using the "**.**" operator. + +- Example of using a lambda expression to configure the event of a component: + + ```ts + Button('add counter') + .onClick(() => { + this.counter += 2 + }) + ``` + +- Example of using an anonymous function expression to configure the event of a component (**bind** must be used to ensure that the contained components are referenced by **this** in the function body): + + ```ts + Button('add counter') + .onClick(function () { + this.counter += 2 + }.bind(this)) + ``` + +- Example of using a component's member function to configure the event of the component: + + ```ts + myClickHandler(): void { + this.counter += 2 + } + + ... + + Button('add counter') + .onClick(this.myClickHandler) + ``` + +### Child Component Configuration + +For a component that supports child components, for example, a container component, add the UI descriptions of the child components inside parentheses. The **\**, **\**, **\**, **\**, and **\** components are all container components. + +- Simple example of the **\** component: + + ```ts + Column() { + Text('Hello') + .fontSize(100) + Divider() + Text(this.myText) + .fontSize(100) + .fontColor(Color.Red) + } + ``` + +- Example of nesting multiple child components in the **\** component: + + ```ts + Column() { + Row() { + Image('test1.jpg') + .width(100) + .height(100) + Button('click +1') + .onClick(() => { + console.info('+1 clicked!') + }) + } + + Divider() + Row() { + Image('test2.jpg') + .width(100) + .height(100) + Button('click +2') + .onClick(() => { + console.info('+2 clicked!') + }) + } + + Divider() + Row() { + Image('test3.jpg') + .width(100) + .height(100) + Button('click +3') + .onClick(() => { + console.info('+3 clicked!') + }) + } + } + ``` diff --git a/en/application-dev/quick-start/arkts-dynamic-ui-elememt-building.md b/en/application-dev/quick-start/arkts-dynamic-ui-elememt-building.md new file mode 100644 index 0000000000000000000000000000000000000000..a781f1d81c83a306c135b412b14ded55d032cb02 --- /dev/null +++ b/en/application-dev/quick-start/arkts-dynamic-ui-elememt-building.md @@ -0,0 +1,385 @@ +# Dynamic UI Element Building + +After you've created a custom component (as described in [Basic UI Description](arkts-basic-ui-description.md)), you can customize the internal UI structure for the component, by drawing on the capability of dynamic UI element building. + +## @Builder + +The **@Builder** decorator is used to decorate a function for quickly generating multiple layouts in a custom component. This function can be declared outside the **build** function and used in the **build** function or other **@Builder** decorated functions. The following example shows how to use **@Builder**. + +```ts +// xxx.ets +@Component +struct CompB { + @State CompValue: string = '' + + aboutToAppear() { + console.info('CompB aboutToAppear.') + } + + aboutToDisappear() { + console.info('CompB aboutToDisappear.') + } + + build() { + Column() { + Button(this.CompValue) + .margin(5) + } + } +} + +@Entry +@Component +struct CompA { + size1: number = 100 + @State CompValue1: string = "Hello,CompValue1" + @State CompValue2: string = "Hello,CompValue2" + @State CompValue3: string = "Hello,CompValue3" + + // Use the custom component CompB in the @Builder decorated function CompC. + @Builder CompC(value: string) { + CompB({ CompValue: value }) + } + + @Builder SquareText(label: string) { + Text(label) + .fontSize(18) + .width(1 * this.size1) + .height(1 * this.size1) + } + + // Use the @Builder decorated function SquareText in the @Builder decorated function RowOfSquareTexts. + @Builder RowOfSquareTexts(label1: string, label2: string) { + Row() { + this.SquareText(label1) + this.SquareText(label2) + } + .width(2 * this.size1) + .height(1 * this.size1) + } + + build() { + Column() { + Row() { + this.SquareText("A") + this.SquareText("B") + } + .width(2 * this.size1) + .height(1 * this.size1) + + this.RowOfSquareTexts("C", "D") + Column() { + // Use the @Builder decorated custom components three times. + this.CompC(this.CompValue1) + this.CompC(this.CompValue2) + this.CompC(this.CompValue3) + } + .width(2 * this.size1) + .height(2 * this.size1) + } + .width(2 * this.size1) + .height(2 * this.size1) + } +} +``` +![builder](figures/builder.PNG) + +## @BuilderParam8+ + +The **@BuilderParam** decorator is used to decorate the function type attributes (for example, **@BuilderParam noParam: () => void**) in a custom component. When the custom component is initialized, the attributes decorated by **@BuilderParam** must be assigned values. + +### Background + +In certain circumstances, you may need to add a specific function, such as a click-to-jump action, to a custom component. However, embedding an event method directly inside of the component will add the function to all places where the component is imported. This is where the **@BuilderParam** decorator comes into the picture. When initializing a custom component, you can assign a **@Builder** decorated method to the **@BuilderParam** decorated attribute, thereby adding the specific function to the custom component. + +### Component Initialization Through Parameters + +When initializing a custom component through parameters, assign a **@Builder** decorated method to the **@BuilderParam** decorated attribute — **content**, and call the value of **content** in the custom component. If no parameter is passed when assigning a value to the **@BuilderParam** decorated attribute (for example, **noParam: this.specificNoParam**), define the type of the attribute as a function without a return value (for example, **@BuilderParam noParam: () => void**). If any parameter is passed when assigning a value to the **@BuilderParam** decorated attribute (for example, **withParam: this.SpecificWithParam('WithParamA')**), define the type of the attribute as **any** (for example, **@BuilderParam withParam: any**). + +```ts +// xxx.ets +@Component +struct CustomContainer { + header: string = '' + @BuilderParam noParam: () => void + @BuilderParam withParam: any + footer: string = '' + + build() { + Column() { + Text(this.header) + .fontSize(30) + this.noParam() + this.withParam() + Text(this.footer) + .fontSize(30) + } + } +} + +@Entry +@Component +struct CustomContainerUser { + @Builder specificNoParam() { + Column() { + Text('noParam').fontSize(30) + } + } + + @Builder SpecificWithParam(label: string) { + Column() { + Text(label).fontSize(30) + } + } + + build() { + Column() { + CustomContainer({ + header: 'HeaderA', + noParam: this.specificNoParam, + withParam: this.SpecificWithParam('WithParamA'), + footer: 'FooterA' + }) + Divider() + .strokeWidth(3) + .margin(10) + CustomContainer({ + header: 'HeaderB', + noParam: this.specificNoParam, + withParam: this.SpecificWithParam('WithParamB'), + footer: 'FooterB' + }) + } + } +} +``` + +![builder1](figures/builder1.PNG) + +### Component Initialization Through Trailing Closure + +In a custom component, the **@BuilderParam** decorated attribute can be initialized using a trailing closure. During initialization, the component name is followed by a pair of braces ({}) to form a trailing closure (**CustomContainer(){}**). You can consider a trailing closure as a container and add content to it. For example, you can add a component (**{Column(){...}**) to the closure. The syntax of the closure is the same as that of **build**. In this scenario, the custom component has one and only one **@BuilderParam** decorated attribute. + +Example: Add a **\** component and a click event to the closure, and call the **specificParam** method decorated by **@Builder** in the new **\** component. After the **\** component is clicked, the value of the **CustomContainer** component's **header** attribute will change from **header** to **changeHeader**. When the component is initialized, the content of the trailing closure will be assigned to the **closer** attribute decorated by **@BuilderParam**. + +```ts +// xxx.ets +@Component +struct CustomContainer { + header: string = '' + @BuilderParam closer: () => void + + build() { + Column() { + Text(this.header) + .fontSize(30) + this.closer() + } + } +} + +@Builder function specificParam(label1: string, label2: string) { + Column() { + Text(label1) + .fontSize(30) + Text(label2) + .fontSize(30) + } +} + +@Entry +@Component +struct CustomContainerUser { + @State text: string = 'header' + + build() { + Column() { + CustomContainer({ + header: this.text, + }) { + Column() { + specificParam('testA', 'testB') + }.backgroundColor(Color.Yellow) + .onClick(() => { + this.text = 'changeHeader' + }) + } + } + } +} +``` + +![builder2](figures/builder2.gif) + +## @Styles + +The **@Styles** decorator helps avoid repeated style setting, by extracting multiple style settings into one method. When declaring a component, you can invoke this method and use the **@Styles** decorator to quickly define and reuse the custom styles of a component. **@Styles** supports only universal attributes. + +**@Styles** can be defined inside or outside a component declaration. When it is defined outside a component declaration, the component name must be preceded by the keyword **function**. + +```ts +// xxx.ets +@Styles function globalFancy () { + .width(150) + .height(100) + .backgroundColor(Color.Pink) +} + +@Entry +@Component +struct FancyUse { + @Styles componentFancy() { + .width(100) + .height(200) + .backgroundColor(Color.Yellow) + } + + build() { + Column({ space: 10 }) { + Text('FancyA') + .globalFancy() + .fontSize(30) + Text('FancyB') + .globalFancy() + .fontSize(20) + Text('FancyC') + .componentFancy() + .fontSize(30) + Text('FancyD') + .componentFancy() + .fontSize(20) + } + } +} +``` + +![styles](figures/styles.PNG) + +**@Styles** can also be used inside the **[StateStyles](../reference/arkui-ts/ts-universal-attributes-polymorphic-style.md)** attribute declaration of a component, to assign state-specific attributes to the component. + +In **StateStyles**, **@Styles** decorated methods defined outside the component can be directly called, while those defined inside can be called only with the keyword **this**. + +```ts +// xxx.ets +@Styles function globalFancy () { + .width(120) + .height(120) + .backgroundColor(Color.Green) +} + +@Entry +@Component +struct FancyUse { + @Styles componentFancy() { + .width(80) + .height(80) + .backgroundColor(Color.Red) + } + + build() { + Row({ space: 10 }) { + Button('Fancy') + .stateStyles({ + normal: { + .width(100) + .height(100) + .backgroundColor(Color.Blue) + }, + disabled: this.componentFancy, + pressed: globalFancy + }) + } + } +} +``` + +![styles1](figures/styles1.gif) + +## @Extend + +The **@Extend** decorator adds new attribute methods to built-in components, such as **\**, **\**, and **\