diff --git a/FAQ/AbilityKit/.gitignore b/FAQ/AbilityKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/AbilityKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/AbilityKit/AppScope/app.json5 b/FAQ/AbilityKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3c4e34f50a8e08090d8fecf263cfec16096525fb --- /dev/null +++ b/FAQ/AbilityKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.abilitykit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/AbilityKit/AppScope/resources/base/element/string.json b/FAQ/AbilityKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..98971656e57767a2f78c6acdef9f44f8e7fa5584 --- /dev/null +++ b/FAQ/AbilityKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "AbilityKit" + } + ] +} diff --git a/FAQ/AbilityKit/AppScope/resources/base/media/background.png b/FAQ/AbilityKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/AbilityKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/AbilityKit/AppScope/resources/base/media/foreground.png b/FAQ/AbilityKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/AbilityKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/AbilityKit/AppScope/resources/base/media/layered_image.json b/FAQ/AbilityKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/AbilityKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/build-profile.json5 b/FAQ/AbilityKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/AbilityKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/code-linter.json5 b/FAQ/AbilityKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/AbilityKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/.gitignore b/FAQ/AbilityKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/AbilityKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/build-profile.json5 b/FAQ/AbilityKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/AbilityKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/hvigorfile.ts b/FAQ/AbilityKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/AbilityKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/AbilityKit/entry/obfuscation-rules.txt b/FAQ/AbilityKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/AbilityKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/oh-package.json5 b/FAQ/AbilityKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/AbilityKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/AbilityKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/AbilityKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/AbilityKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/ets/pages/EmitterAndEventHub.ets b/FAQ/AbilityKit/entry/src/main/ets/pages/EmitterAndEventHub.ets new file mode 100644 index 0000000000000000000000000000000000000000..30e1ee61c375c8ec4435a00a8e55ab644892a2f0 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/ets/pages/EmitterAndEventHub.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:关于emitter、eventHub的使用场景 + */ + +// DocsCode 2 +// 定义一个eventId为1的事件 +let event: emitter.InnerEvent = { + eventId: 1 +}; + +// 收到eventId为1的事件后执行该回调 +let callback = (eventData: emitter.EventData): void => { + this.getUIContext().getPromptAction().showToast({ + message: JSON.stringify(eventData) + }); +}; + +// 订阅eventId为1的事件 +emitter.on(event, callback); +this.getUIContext().getPromptAction().showToast({ + message: $r('app.string.emitter_subscribe_success_toast') +}); +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/ets/pages/Index.ets b/FAQ/AbilityKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/ets/pages/PullUpBrowserApplication.ets b/FAQ/AbilityKit/entry/src/main/ets/pages/PullUpBrowserApplication.ets new file mode 100644 index 0000000000000000000000000000000000000000..c6b010fdeafcde7be6df3d380ce0984d09d1680a --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/ets/pages/PullUpBrowserApplication.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何拉起浏览器应用 + */ + +// DocsCode 1 +import { common, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +function startBrowsableAbility(context: common.UIAbilityContext): void { + let want: Want = { + action: 'ohos.want.action.viewData', + entities: ['entity.system.browsable'], + uri: 'https://www.huawei.com/', + parameters: { + 'ohos.ability.params.showDefaultPicker': true + } + }; + context.startAbility(want) + .then(() => { + console.error('Start browsableAbility successfully.'); + }) + .catch((err: BusinessError) => { + console.error(`Failed to startAbility. Code: ${err.code}, message: ${err.message}`); + }); +} + +@Entry +@Component +struct BrowsableAbilityView { + @State message: string = '拉起浏览器并打开华为官网'; + + build() { + Row() { + Column() { + Button(this.message) + .fontSize(24) + .fontWeight(FontWeight.Bold) + .onClick(() => { + const context: common.UIAbilityContext = this.getUIContext().getHostContext()! as common.UIAbilityContext; + startBrowsableAbility(context); + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/ets/pages/PullUpCamera.ets b/FAQ/AbilityKit/entry/src/main/ets/pages/PullUpCamera.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d66c2db4d9ea2eb18730c2edc98ddf026aa9e34 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/ets/pages/PullUpCamera.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何拉起相机界面 + */ + +// DocsCode 1 +import { common } from '@kit.AbilityKit'; +import { camera, cameraPicker } from '@kit.CameraKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +let context = UIContext.getHostContext() as common.Context; + +async function startCameraPicker() { + try { + let pickerProfile: cameraPicker.PickerProfile = { + cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK + }; + let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(context, + [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile); + console.log("the pick pickerResult is:" + JSON.stringify(pickerResult)); + } catch (error) { + let err = error as BusinessError; + console.error(`the pick call failed. error code: ${err.code}`); + } +} + +@Entry +@Component +struct StartCameraPickerView { + build() { + Column() { + Button("点击拉起相机") + .onClick(() => startCameraPicker()) + } + .width("100%") + .height("100%") + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Center) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/module.json5 b/FAQ/AbilityKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/element/color.json b/FAQ/AbilityKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/element/float.json b/FAQ/AbilityKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/element/string.json b/FAQ/AbilityKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/media/background.png b/FAQ/AbilityKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/AbilityKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/media/foreground.png b/FAQ/AbilityKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/AbilityKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/AbilityKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/AbilityKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/AbilityKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/AbilityKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/AbilityKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..83e757edffd0df0c9640cd78bdee45f887e55861 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,7 @@ +{ + "src": [ + "pages/Index", + "pages/PullUpBrowserApplication", + "pages/PullUpCamera" + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/main/resources/dark/element/color.json b/FAQ/AbilityKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/mock/mock-config.json5 b/FAQ/AbilityKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/AbilityKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/AbilityKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/ohosTest/module.json5 b/FAQ/AbilityKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/AbilityKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/AbilityKit/entry/src/test/List.test.ets b/FAQ/AbilityKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/AbilityKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/AbilityKit/entry/src/test/LocalUnit.test.ets b/FAQ/AbilityKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/AbilityKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/AbilityKit/hvigor/hvigor-config.json5 b/FAQ/AbilityKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/AbilityKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/AbilityKit/hvigorfile.ts b/FAQ/AbilityKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/AbilityKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/AbilityKit/oh-package-lock.json5 b/FAQ/AbilityKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/AbilityKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/AbilityKit/oh-package.json5 b/FAQ/AbilityKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/AbilityKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/ArkDataKit/.gitignore b/FAQ/ArkDataKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/ArkDataKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/ArkDataKit/AppScope/app.json5 b/FAQ/ArkDataKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6751b91906064b3ed4e66ef7669a79cb385c8fa5 --- /dev/null +++ b/FAQ/ArkDataKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.arkdatakit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/ArkDataKit/AppScope/resources/base/element/string.json b/FAQ/ArkDataKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..ca85cec401f7ea044aed185f61cf6c645ec31acc --- /dev/null +++ b/FAQ/ArkDataKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "ArkDataKit" + } + ] +} diff --git a/FAQ/ArkDataKit/AppScope/resources/base/media/background.png b/FAQ/ArkDataKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ArkDataKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/ArkDataKit/AppScope/resources/base/media/foreground.png b/FAQ/ArkDataKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ArkDataKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/ArkDataKit/AppScope/resources/base/media/layered_image.json b/FAQ/ArkDataKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ArkDataKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/build-profile.json5 b/FAQ/ArkDataKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/ArkDataKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/code-linter.json5 b/FAQ/ArkDataKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/ArkDataKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/.gitignore b/FAQ/ArkDataKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/ArkDataKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/build-profile.json5 b/FAQ/ArkDataKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/ArkDataKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/hvigorfile.ts b/FAQ/ArkDataKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/ArkDataKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ArkDataKit/entry/obfuscation-rules.txt b/FAQ/ArkDataKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/ArkDataKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/oh-package.json5 b/FAQ/ArkDataKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/ArkDataKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/ArkDataKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/ArkDataKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/ArkDataKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/ets/pages/Index.ets b/FAQ/ArkDataKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/ets/pages/LocalDatabaseReader.ets b/FAQ/ArkDataKit/entry/src/main/ets/pages/LocalDatabaseReader.ets new file mode 100644 index 0000000000000000000000000000000000000000..02bec50f72f86bb7675597925b4953d0c42636b9 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/ets/pages/LocalDatabaseReader.ets @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何读取本地/预制数据库 +*/ + +// DocsCode 1 +import { fileIo, ReadOptions } from '@kit.CoreFileKit'; +import { resourceManager } from '@kit.LocalizationKit'; +import { relationalStore } from '@kit.ArkData'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +let RDBDirectory = context.getHostContext()!.databaseDir; +let resource = context.getHostContext()!.resourceManager; + +function saveFileToCache(file: resourceManager.RawFileDescriptor, dbName: string) { + // 创建缓存文件(当前是覆盖式创建) + let cFile = RDBDirectory + '/entry/rdb/' + dbName; + let cacheFile = fileIo.openSync(cFile, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + + // 读取缓冲区大小 + let bufferSize = 30000; + let buffer = new ArrayBuffer(bufferSize); //创建buffer缓冲区 + + // 要copy的文件的offset + let currentOffset = file.offset; + + let readOption: ReadOptions = { + offset: currentOffset, //期望读取文件的位置。可选,默认从当前位置开始读 + length: bufferSize //每次期望读取数据的长度。可选,默认缓冲区长度 + }; + + // 后面len会一直减,直到没有 + while (true) { + // 读取buffer容量的内容 + let readLength = fileIo.readSync(file.fd, buffer, readOption); + // 写入buffer容量的内容 + fileIo.writeSync(cacheFile.fd, buffer, { length: readLength }); //写到cacheFile里 + // 判断后续内容 修改读文件的参数 + // buffer没读满代表文件读完了 + if (readLength < bufferSize) { + break; + } + if (readOption.offset != undefined) { + readOption.offset += readLength; + } + } + console.log('Copy Success!!!') + fileIo.close(cacheFile); +} + +function INIT() { + // 创建数据库沙箱目录 + try { + let dirPath = RDBDirectory + '/entry'; + fileIo.mkdirSync(dirPath); + dirPath = dirPath + '/rdb'; + fileIo.mkdirSync(dirPath); + } catch (error) { + console.error(`mkdir rdbPath failed, error code: ${error.code}, message: ${error.message}.`); + } + + //数据库名称 + let dbName: string = 'Company.db'; + + //读取rawfile目录下db文件 + try { + resource.getRawFd('rdb/' + dbName, (error, value) => { + if (error != null) { + console.log(`callback getRawFd failed error code: ${error.code}, message: ${error.message}.`); + } else { + console.info(value.length.toString()); + saveFileToCache(value, dbName); + } + }); + } catch (error) { + console.error(`callback getRawFd failed, error code: ${error.code}, message: ${error.message}.`); + } +} +// DocsCode 1 + +// DocsCode 2 +function getRDB(): relationalStore.RdbStore | undefined { + let result: relationalStore.RdbStore | undefined = undefined; + const STORE_CONFIG: relationalStore.StoreConfig = { + name: 'Company.db', + securityLevel: relationalStore.SecurityLevel.S1 + }; + + relationalStore.getRdbStore(context, STORE_CONFIG, (err, store) => { + if (err) { + console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`); + return; + } else { + console.info(`Succeeded in getting RdbStore.`); + } + result = store; + }) + return result; +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/ets/pages/PredicateQuery.ets b/FAQ/ArkDataKit/entry/src/main/ets/pages/PredicateQuery.ets new file mode 100644 index 0000000000000000000000000000000000000000..82e72259c09ed863ea6588206d85d80fd82ce191 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/ets/pages/PredicateQuery.ets @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何通过谓词查询方式获取数据 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { distributedKVStore } from '@kit.ArkData'; + +let kvStore: undefined | distributedKVStore.SingleKVStore = undefined; + +@Entry +@Component +export struct ReadingTheLocalDatabase { + build() { + Row() { + Column({ space: 20 }) { + Button('创建数据库') + .fontSize(20) + .fontWeight(FontWeight.Bold) + .onClick(async () => { + try { + let name = new distributedKVStore.FieldNode('name'); // 创建FieldNode对象 + name.type = distributedKVStore.ValueType.STRING; // 指定节点类型对应的数据类型为string + name.nullable = false; // 节点数据不能为空 + name.default = 'cake'; // 默认值 + + let schema1 = new distributedKVStore.Schema(); // 创建Schema对象 + schema1.root.appendChild(name); // 添加子节点 + schema1.indexes = ['$.name']; // 定义索引字段 + // 创建KVManager对象 + let kvManager = distributedKVStore.createKVManager({ + bundleName: 'TEST_CRASH_APP', + context: this.getUIContext().getHostContext() + }); + // 创建并获取分布式键值数据库 + await kvManager.getKVStore('storeIds', { + createIfMissing: true, + backup: false, + encrypt: false, + autoSync: false, + schema: schema1, + kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, + securityLevel: distributedKVStore.SecurityLevel.S2 + }).then((store: distributedKVStore.SingleKVStore) => { + kvStore = store; + }).catch((err: BusinessError) => { + console.info(`getKVStore error is: ${err.code}, msg is: ${err.message}`); + }) + if (kvStore === undefined) { + return; + } + let entries: distributedKVStore.Entry[] = []; + for (let i = 0; i < 10; i++) { + let ent: distributedKVStore.Entry = { + key: 'test' + i, + value: { + type: distributedKVStore.ValueType.STRING, + value: '{"name":"cake"}' + } + } + entries.push(ent); + } + // 批量插入键值对到数据库中 + kvStore.putBatch(entries) + .then((data) => { + console.info('Succeeded in putting Batch'); + }) + .catch((err: BusinessError) => { + console.info(`putBatch error is: ${err.code}, msg is: ${err.message}`); + }) + } catch (e) { + console.info(`putBatch e is: ${e.code}, msg is: ${e.message}`); + } + }) + + Button('like查询') + .fontSize(20) + .onClick(() => { + try { + if (kvStore === undefined) { + return; + } + // 使用谓词查询具有与指定字符串值相似的指定字段,并获取与指定Query对象匹配的键值对列表 + kvStore.getEntries(new distributedKVStore.Query().like('$.name', 'c%')) + .then((value) => { + for (let i = 0; i < value.length; i++) { + console.info('key:' + value[i].key + 'value : ' + JSON.stringify(value[i].value)) + } + }) + .catch((err: BusinessError) => { + console.info(`getEntries error is: ${err.code}, msg is: ${err.message}`); + }) + } catch (e) { + console.info(`getEntries e is: ${e.code}, msg is: ${e.message}`); + } + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/module.json5 b/FAQ/ArkDataKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/element/color.json b/FAQ/ArkDataKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/element/float.json b/FAQ/ArkDataKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/element/string.json b/FAQ/ArkDataKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/media/background.png b/FAQ/ArkDataKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ArkDataKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/media/foreground.png b/FAQ/ArkDataKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ArkDataKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/ArkDataKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/ArkDataKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/ArkDataKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/ArkDataKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/ArkDataKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/FAQ/ArkDataKit/entry/src/main/resources/dark/element/color.json b/FAQ/ArkDataKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/mock/mock-config.json5 b/FAQ/ArkDataKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/ArkDataKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/ArkDataKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/ohosTest/module.json5 b/FAQ/ArkDataKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/ArkDataKit/entry/src/test/List.test.ets b/FAQ/ArkDataKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/entry/src/test/LocalUnit.test.ets b/FAQ/ArkDataKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/ArkDataKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/hvigor/hvigor-config.json5 b/FAQ/ArkDataKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/ArkDataKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/ArkDataKit/hvigorfile.ts b/FAQ/ArkDataKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/ArkDataKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ArkDataKit/oh-package-lock.json5 b/FAQ/ArkDataKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c6f99f5c73b06c5fdef7ec6f491b74b7befebe2e --- /dev/null +++ b/FAQ/ArkDataKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/ArkDataKit/oh-package.json5 b/FAQ/ArkDataKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/ArkDataKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/ArkUIKit/.gitignore b/FAQ/ArkUIKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/ArkUIKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/ArkUIKit/AppScope/app.json5 b/FAQ/ArkUIKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..8bff5a306558a4808d775ab15e41b6d3fdcd176e --- /dev/null +++ b/FAQ/ArkUIKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.newsdemo", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/ArkUIKit/AppScope/resources/base/element/string.json b/FAQ/ArkUIKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..c90fc83afa24888d48cfea70e9ebf4703348a0f9 --- /dev/null +++ b/FAQ/ArkUIKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "ArkUIKit" + } + ] +} diff --git a/FAQ/ArkUIKit/AppScope/resources/base/media/background.png b/FAQ/ArkUIKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ArkUIKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/ArkUIKit/AppScope/resources/base/media/foreground.png b/FAQ/ArkUIKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ArkUIKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/ArkUIKit/AppScope/resources/base/media/layered_image.json b/FAQ/ArkUIKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ArkUIKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/build-profile.json5 b/FAQ/ArkUIKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/ArkUIKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/code-linter.json5 b/FAQ/ArkUIKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/ArkUIKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/.gitignore b/FAQ/ArkUIKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/ArkUIKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/build-profile.json5 b/FAQ/ArkUIKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/ArkUIKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/hvigorfile.ts b/FAQ/ArkUIKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/ArkUIKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ArkUIKit/entry/obfuscation-rules.txt b/FAQ/ArkUIKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/ArkUIKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/oh-package.json5 b/FAQ/ArkUIKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/ArkUIKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/ArkUIKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/ArkUIKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/ArkUIKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/AddComponentInTabbar.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/AddComponentInTabbar.ets new file mode 100644 index 0000000000000000000000000000000000000000..2553655e6908f6b6ac61bfeac2e03824e8490e46 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/AddComponentInTabbar.ets @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Tabs的tabBar中添加其他组件 + */ + +// DocsCode 1 +import { componentUtils } from '@kit.ArkUI'; + +@Entry +@Component +struct TabsDemo { + @State tabArray: Array = [0, 1, 2]; + @State tabArrayVal: number = this.tabArray.length - 1; + @State currentIndex: number = 0; + @State animationDuration: number = 300; + @State indicatorLeftMargin: number = 0; + @State indicatorWidth: number = 0; + private controller: TabsController = new TabsController(); + private tabsWidth: number = 0; + + // 单独的页签 + @Builder + tab(tabName: string, tabItem: number, tabIndex: number) { + Row({ space: 20 }) { + Text(tabName).fontSize(18) + .fontColor(tabItem === this.currentIndex ? Color.Red : Color.Black) + .id(tabIndex.toString()) + .onAreaChange((oldValue: Area, newValue: Area) => { + if (this.currentIndex === tabIndex && (this.indicatorLeftMargin === 0 || this.indicatorWidth === 0)) { + if (newValue.position.x !== undefined) { + let positionX = Number.parseFloat(newValue.position.x.toString()); + this.indicatorLeftMargin = Number.isNaN(positionX) ? 0 : positionX; + } + let width = Number.parseFloat(newValue.width.toString()); + this.indicatorWidth = Number.isNaN(width) ? 0 : width; + } + }) + } + .justifyContent(FlexAlign.Center) + .constraintSize({ minWidth: 35 }) + .width(80) + .height(35) + .borderRadius({ + topLeft: 10, + topRight: 10 + }) + .onClick(() => { + this.controller.changeIndex(tabIndex); + this.currentIndex = tabIndex; + }) + } + + build() { + Column() { + // 页签 + Stack({ alignContent: Alignment.TopStart }) { + Scroll() { + Row() { + ForEach(this.tabArray, (item: number, index: number) => { + this.tab('页签' + item, item, index); + }) + Text('+') + .width(36) + .height(50) + .fontSize(28) + .borderRadius(5) + .padding({ + left: 5, + bottom: 2 + }) + .onClick(() => { + this.tabArray.push(++this.tabArrayVal); + }) + } + .justifyContent(FlexAlign.SpaceBetween) + } + .align(Alignment.Start) + .scrollable(ScrollDirection.Horizontal) + .scrollBar(BarState.Off) + .width('100%') + + Column() + .width(this.indicatorWidth) + .height(2) + .backgroundColor(Color.Red) + .borderRadius(2) + .margin({ + left: this.indicatorLeftMargin, + top: 38 + }) + } + .width('100%') + + Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { + ForEach(this.tabArray, (item: number, index: number) => { + TabContent() { + Text('我是页面' + item + '的内容') + .height(300) + .width('100%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + .backgroundColor(Color.Pink) + }) + } + .onAreaChange((oldValue: Area, newValue: Area) => { + let width = Number.parseFloat(newValue.width.toString()); + this.tabsWidth = Number.isNaN(width) ? 0 : width; + }) + .barWidth('100%') + .barHeight(0) + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + .animationDuration(this.animationDuration) + .onChange((index: number) => { + this.currentIndex = index; // 监听索引index的变化,实现页签内容的切换。 + }) + .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => { + // 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。 + this.currentIndex = targetIndex; + let targetIndexInfo = this.getTextInfo(targetIndex); + this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width); + }) + .onAnimationEnd((index: number, event: TabsAnimationEvent) => { + // 切换动画结束时触发该回调。下划线动画停止。 + let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event); + this.startAnimateTo(0, currentIndicatorInfo.left, currentIndicatorInfo.width); + }) + .onGestureSwipe((index: number, event: TabsAnimationEvent) => { + // 在页面跟手滑动过程中,逐帧触发该回调。 + let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event); + this.currentIndex = currentIndicatorInfo.index; + this.indicatorLeftMargin = currentIndicatorInfo.left; + this.indicatorWidth = currentIndicatorInfo.width; + }) + } + .height('100%') + } + + // 获取组件大小、位置、平移缩放旋转及仿射矩阵属性信息。 + private getTextInfo(index: number): Record { + let modePosition: componentUtils.ComponentInfo = componentUtils.getRectangleById(index.toString()); + return { 'left': this.getUIContext().px2vp(modePosition.windowOffset.x), 'width': this.getUIContext().px2vp(modePosition.size.width) }; + } + + private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record { + let nextIndex = index; + if (index > 0 && event.currentOffset > 0) { + nextIndex--; + } else if (index < 3 && event.currentOffset < 0) { + nextIndex++; + } + let indexInfo = this.getTextInfo(index); + let nextIndexInfo = this.getTextInfo(nextIndex); + let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth); + // 页面滑动超过一半,tabBar切换到下一页。 + let currentIndex = swipeRatio > 0.5 ? nextIndex : index; + let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * swipeRatio; + let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * swipeRatio; + return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth }; + } + + private startAnimateTo(duration: number, leftMargin: number, width: number) { + animateTo({ + // 动画时长 + duration: duration, + // 动画曲线 + curve: Curve.Linear, + // 播放次数 + iterations: 1, + // 动画模式 + playMode: PlayMode.Normal, + onFinish: () => { + console.info('play end'); + } + }, () => { + this.indicatorLeftMargin = leftMargin; + this.indicatorWidth = width; + }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/AvoidAreaHeight.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/AvoidAreaHeight.ets new file mode 100644 index 0000000000000000000000000000000000000000..162f3f93652c390f7d6b4a6885ce2d60a37e6462 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/AvoidAreaHeight.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取屏幕顶部状态栏、底部导航栏和导航条的高度 +*/ + +// DocsCode 1 +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct GetAvoidAreaHeight { + context = this.getUIContext(); + + build() { + Column() { + Button('GetAvoidAreaHeight') + .onClick(() => { + let type1 = window.AvoidAreaType.TYPE_SYSTEM; + let type2 = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; + window.getLastWindow(this.context.getHostContext()).then((data) => { + // 获取系统默认区域,一般包括状态栏、导航栏 + let avoidArea1 = data.getWindowAvoidArea(type1); + // 顶部状态栏高度 + let statusBarHeight = avoidArea1.topRect.height; + // 底部导航栏高度 + let bottomNavHeight = avoidArea1.bottomRect.height; + // 获取导航条区域 + let avoidArea2 = data.getWindowAvoidArea(type2); + // 获取到导航条区域的高度 + let indicatorHeight = avoidArea2.bottomRect.height; + console.info(`statusBarHeight is ${statusBarHeight}`); + console.info(`bottomNavHeight is ${bottomNavHeight}`); + console.info(`indicatorHeight is ${indicatorHeight}`); + }).catch((err: BusinessError) => { + console.error(`Failed to obtain the window. Cause: ${JSON.stringify(err)}`); + }); + }) + } + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomNavBarHeight.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomNavBarHeight.ets new file mode 100644 index 0000000000000000000000000000000000000000..c03f2f44bf8b27edb2217c57da026758bbaff188 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomNavBarHeight.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取底部手势横条的高度 +*/ + +// DocsCode 1 + +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct GetBottomNavBarHeight { + context = this.getUIContext(); + + build() { + Column() { + Button('获取底部手势横条的高度') + .onClick(() => { + let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; + window.getLastWindow(this.context.getHostContext()).then((data) => { + let avoidArea = data.getWindowAvoidArea(type); + // 获取到导航条区域的高度 + let bottomRectHeight = avoidArea.bottomRect.height; + console.info(`window bottomRectHeight is: ${bottomRectHeight}`); + }).catch((err: BusinessError) => { + console.error(`Failed to obtain the window. Cause: ${JSON.stringify(err)}`); + }); + }) + } + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomPopsUpAsTheTopOfKeyboard.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomPopsUpAsTheTopOfKeyboard.ets new file mode 100644 index 0000000000000000000000000000000000000000..3e232cf8579f870dec1f7a8cf87238431acd6c95 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomPopsUpAsTheTopOfKeyboard.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:输入框拉起键盘时,如何将底部布局弹起到键盘顶部 +*/ + +// DocsCode 1 +import { window } from '@kit.ArkUI'; + +@Entry +struct BottomPopsUpAsTheTopOfKeyboard { + context = this.getUIContext(); + scroller: Scroller = new Scroller(); + private arr: number[] = [0, 1, 2, 3, 4, 5]; + @State scrollHeight: number = 0; + @State isRebuild: boolean = false; + @State keyHeight: number = 0; + @State text: string = ''; + aboutToAppear() { + window.getLastWindow(this.context.getHostContext()).then(currentWindow => { + // 设置窗口的布局为沉浸式布局 + currentWindow.setWindowLayoutFullScreen(true); + let property = currentWindow.getWindowProperties(); + // 初始化窗口高度 + let avoidArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + this.scrollHeight = px2vp(property.windowRect.height - avoidArea.bottomRect.height); + // 监听软键盘的隐藏和显示 + currentWindow.on('avoidAreaChange', data => { + if (data.type == window.AvoidAreaType.TYPE_KEYBOARD) { + this.keyHeight = px2vp(data.area.bottomRect.height); + this.scrollHeight = + px2vp(currentWindow.getWindowProperties().windowRect.height - data.area.bottomRect.height); + return; + } + }) + }) + } + build() { + Stack({ alignContent: Alignment.TopStart }) { + Column() { + Scroll(this.scroller) { + Column() { + TextInput({ text: this.text, placeholder: 'input your word...' }) + .placeholderFont({ + size: 14, + weight: 400 + }) + .width(320) + .height(40) + .margin(200) + .fontSize(14) + .fontColor(Color.Black) + .backgroundColor(Color.White) + ForEach(this.arr, (item: number) => { + Text(item.toString()) + .width('90%') + .height(150) + .backgroundColor(0xFFFFFF) + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .margin({ top: 10 }) + }) + } + .width('100%') + } + .width('100%') + .height(this.scrollHeight) + .layoutWeight(1) + Text('这是一个测试文本') + .width('100%') + .height(50) + .backgroundColor(Color.Red) + .margin({ bottom: this.keyHeight }) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Start) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomSlideAndOut.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomSlideAndOut.ets new file mode 100644 index 0000000000000000000000000000000000000000..dffdc8b352854701346e29299b2c0f2713d0eee8 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/BottomSlideAndOut.ets @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:自定义组件间如何实现从底部滑入滑出的效果 +*/ + +// DocsCode 1 +@Entry +@Component +struct ComponentTransition { + @State flag: boolean = true; + + build() { + Stack({ alignContent: Alignment.Bottom }) { + if (this.flag) { + ComponentChild1({ flag: $flag }) + .transition({ type: TransitionType.Insert,translate: { x: 0, y: 200 } }) + } + if (!this.flag) { + ComponentChild2({ flag: $flag }) + .transition({ type: TransitionType.Insert, translate: { x: 0, y: 200 } }) + } + }.height('100%').width('100%') + } +} + +@Component +struct ComponentChild1 { + @Link flag: boolean + + build() { + Column() { + Image($r('app.media.ic_banner01'))//resources\base\media路径 + .width('100%') + .height(200) + .onClick(() => { + this.getUIContext().animateTo({ duration: 1000 }, () => { + this.flag = !this.flag; + }) + }) + } + } +} + +@Component +struct ComponentChild2 { + @Link flag: boolean + + build() { + Column() { + Image($r('app.media.ic_banner02'))//resources\base\media路径 + .width('100%') + .height(200) + .onClick(() => { + this.getUIContext().animateTo({ duration: 1000 }, () => { + this.flag = !this.flag; + }) + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ControlLevelOfCustomDialog.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ControlLevelOfCustomDialog.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c4e7e163788ffccb95a7066930c5c1b5b5e7625 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ControlLevelOfCustomDialog.ets @@ -0,0 +1,176 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何控制CustomDialog显示层级 + */ + +// DocsCode 1 +@Component +struct Test1 { + @State message: string = 'Hello World'; + + build() { + NavDestination() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } + .onBackPressed(() => { + this.getUIContext().getPromptAction().showToast({ message: '123' }); + return false; + }) + } +} + +@Entry +@Component +struct CustomDialogDisplayLevel { + @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack(); + @State textValue: string = '输入'; + // 显隐控制设置为不占用 + @State visible: Visibility = Visibility.None; + + @Builder + pageMap(name: string) { + if (name === 'pageOne') { + Test1() + } + } + + build() { + Navigation(this.pageInfos) { + Column() { + Stack() { + Row() { + Column() { + Text('我是第一个页面') + .fontSize(30) + .fontWeight(FontWeight.Bold) + Button('按钮') + .onClick(() => { + console.info('hit me!'); + if (this.visible === Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }) + .backgroundColor(0x777474) + .fontColor(0x000000) + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.Start) + .alignItems(HorizontalAlign.Center) + } + .height('100%') + .backgroundColor('#FFF') + + Text('') + .onClick(() => { + if (this.visible === Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }) + .width('100%') + .height('100%') + // 透明度可以自己调节一下 + .opacity(0.5) + .backgroundColor(Color.Black) + .visibility(this.visible) + Column() { + GridRow({ + columns: { + xs: 1, + sm: 4, + md: 8, + lg: 12 + }, + breakpoints: { + value: ['400vp', '600vp', '800vp'], + reference: BreakpointsReference.WindowSize + }, + }) { + GridCol({ + span: { + xs: 1, + sm: 2, + md: 4, + lg: 8 + }, + offset: { + xs: 0, + sm: 1, + md: 2, + lg: 2 + } + }) { + Column() { + Text('安全隐私') + .fontSize(20) + .margin({ + top: 10, + bottom: 10 + }) + Text('是否跳转到隐私详情页面?') + .fontSize(16) + .margin({ bottom: 10 }) + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Button('取消') + .onClick(() => { + if (this.visible === Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }) + .backgroundColor(0xffffff) + .fontColor(Color.Black) + Button('确定') + .onClick(() => { + this.pageInfos.pushPath({ name: 'pageOne' }); + }) + .backgroundColor(0xffffff) + .fontColor(Color.Red) + } + .margin({ bottom: 10 }) + } + .backgroundColor(0xffffff) + .visibility(this.visible) + .clip(true) + .borderRadius(20) + } + } + } + //设置弹窗宽度 + .width('100%') + } + } + .width('100%') + .margin({ top: 5 }) + } + .navDestination(this.pageMap) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/CopyContentDirectlyClipboard.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/CopyContentDirectlyClipboard.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb208cef8a0554dba1f5bd291eb570a57c78ac49 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/CopyContentDirectlyClipboard.ets @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将内容直接复制到剪贴板 + */ + +// DocsCode 1 +import { pasteboard } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct CopyText { + private textContent: string = '复制我'; + + build() { + Column() { + Text(this.textContent) + .fontSize(20) + .borderRadius(9) + .borderWidth(1) + .padding({ + left: 8, + right: 8 + }) + .fontColor($r('sys.color.ohos_id_color_text_primary')) + .fontWeight(FontWeight.Medium) + .opacity($r('sys.float.ohos_id_alpha_content_secondary')) + .onClick(() => copyText(this.textContent)) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + .alignSelf(ItemAlign.Center) + } +} + +// 定义方法 +function copyText(text: string) { + // 创建剪贴板内容对象 + const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); + // 获取系统剪贴板对象 + const systemPasteboard = pasteboard.getSystemPasteboard(); + systemPasteboard.setData(pasteboardData); // 将数据放入剪贴板 + systemPasteboard.getData().then((data) => { // 读取剪贴板内容 + if (data) { + this.getUIContext().getPromptAction().showToast({ message: '复制成功' }); + } else { + this.getUIContext().getPromptAction().showToast({ message: '复制失败' }); + } + }) +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/CustomDialogVariableToPage.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/CustomDialogVariableToPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..15cc7dedd2b15c0f8cf2baa58a8d9e2614944c7b --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/CustomDialogVariableToPage.ets @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:自定义弹窗中的变量如何传递给页面 +*/ + +// DocsCode 1 +@CustomDialog +struct CustomDialog01 { + @Link inputValue: string; + controller: CustomDialogController; + + build() { + Column() { + Text('Change text') + .fontSize(20) + .margin({ top: 10, bottom: 10 }) + TextInput({ placeholder: '', text: this.inputValue }) + .height(60) + .width('90%') + .onChange((value: string) => { + this.inputValue = value; + }) + } + } +} + +@Entry +@Component +struct DialogDemo01 { + @State inputValue: string = 'click me'; + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialog01({ + inputValue: $inputValue + }) + }) + + build() { + Column() { + Button(this.inputValue) + .onClick(() => { + this.dialogController.open(); + }) + .backgroundColor(0x317aff) + } + .width('100%') + .margin({ top: 5 }) + } +} +// DocsCode 1 + +// DocsCode 2 +@CustomDialog +struct CustomDialog02 { + private inputValue: string = ''; + changeInputValue: (val: string) => void = () => { + }; + controller: CustomDialogController; + + build() { + Column() { + Text('Change text') + .fontSize(20) + .margin({ top: 10, bottom: 10 }) + TextInput({ placeholder: '', text: this.inputValue }) + .height(60) + .width('90%') + .onChange((value: string) => { + this.changeInputValue(value); + }) + } + } +} + +@Entry +@Component +struct DialogDemo02 { + @State inputValue: string = 'click me'; + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialog02({ + inputValue: this.inputValue, + changeInputValue: (val: string) => { + this.inputValue = val; + } + }) + }) + + build() { + Column() { + Button(this.inputValue) + .onClick(() => { + this.dialogController.open(); + }) + .backgroundColor(0x317aff) + } + .width('100%') + .margin({ top: 5 }) + } +} +// DocsCode 2 + +// DocsCode 3 +let storage = LocalStorage.getShared(); +@CustomDialog +struct CustomDialog03 { + @LocalStorageLink('inputVal') inputValue: string = ''; + controller: CustomDialogController; + + build() { + Column() { + Text('Change text') + .fontSize(20) + .margin({ top: 10, bottom: 10 }) + TextInput({ placeholder: '', text: this.inputValue }) + .height(60) + .width('90%') + .onChange((value: string) => { + this.inputValue = value; + }) + } + } +} + +@Entry(storage) +@Component +struct DialogDemo03 { + @LocalStorageLink('inputVal') inputValue: string = 'click me'; + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialog03() + }); + + build() { + Column() { + Button(this.inputValue) + .onClick(() => { + this.dialogController.open(); + }) + .backgroundColor(0x317aff) + } + .width('100%') + .margin({ top: 5 }) + } +} +// DocsCode 3 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/DynamicallyLoadSOLibrary.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/DynamicallyLoadSOLibrary.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d4e117731a42cd0ebd9721e023e8a382c2e2821 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/DynamicallyLoadSOLibrary.ets @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:ArkTS侧与Native侧分别如何动态加载SO库 +*/ + +// DocsCode 1 +import { hilog } from '@kit.PerformanceAnalysisKit'; +// import testNapi from 'libentry.so'; + +@Entry +@Component +struct LoadSoLibrary { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(async() => { + let testNapi = await import("libentry.so") // 加载so库 + hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.default.add(2, 3)); // 通过default调用库函数 + // hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3)); + }) + } + .width('100%') + } + .height('100%') + } +} + +// DocsCode 2 +import { hilog } from '@kit.PerformanceAnalysisKit'; +import testNapi from 'libentry.so'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + context = this.getUIContext(); + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + let path = this.context.getHostContext()?.bundleCodeDir; // 获取项目路径 + hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.addByLibPath(2, 3, path + '/libs/arm64/liba.so')); // 传递参数路径信息到Native侧 + }) + } + .width('100%') + } + .height('100%') + } +} + +// DocsCode 3 +#include "napi/native_api.h" +#include + typedef double (*FUNC_ADD)(int, int); +static napi_value Add(napi_env env, napi_callback_info info) { + size_t requireArgc = 3; + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + double value0; + napi_get_value_double(env, args[0], &value0); + double value1; + napi_get_value_double(env, args[1], &value1); + char path[255]; + size_t size = 255; + napi_get_value_string_utf8(env, args[2], path, 255, &size); // 获取动态库路径信息 + void *handle = dlopen(path, RTLD_LAZY); // 打开一个动态链接库.路径为path + dlerror(); + FUNC_ADD add_func = (FUNC_ADD)dlsym(handle, "add"); // 获取函数名为add的函数 + if (dlerror()) { + return nullptr; + } + double res = add_func(value0, value1); // 调用add并传递参数信息 + dlclose(handle); // 最后记得close动态库 + napi_value sum; + napi_create_double(env, res, &sum); + return sum; +} +// ... \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ExcavationScreenAdaptation.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ExcavationScreenAdaptation.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d654b126d454595e7b6337ff7535ad2c8197c34 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ExcavationScreenAdaptation.ets @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何完成挖孔屏的适配 + */ + +// DocsCode 2 +import { display, window } from '@kit.ArkUI'; +import { common } from '@kit.AbilityKit'; +import { batteryInfo } from '@kit.BasicServicesKit'; + +class TextMargin { + left: number = 0; // 状态栏左偏移量 + right: number = 0; // 状态栏右偏移量 +} + +@Entry +@Component +struct Index { + @State date: Date = new Date(); + @State currentTime: string = ''; // 顶部状态栏时间 + @State boundingRect: display.Rect[] = []; // 不可用区域数据 + @State screenWidth: number = 0; // 屏幕宽度 + @State displayClass: display.Display | null = null; + @State topTextMargin: TextMargin = { left: 0, right: 0 }; // 顶部状态栏偏移量 + @StorageLink('context') context: common.UIAbilityContext | undefined = + AppStorage.get('context'); // 获取UIAbilityContext + + aboutToAppear(): void { + this.displayClass = display.getDefaultDisplaySync(); + display.getDefaultDisplaySync().getCutoutInfo((err, data) => { + if (err.code !== 0) { + console.log('getCutoutInfo failed. error is:', JSON.stringify(err)); + return; + } + this.boundingRect = data.boundingRects; + this.topTextMargin = this.getBoundingRectPosition(); + }) + // 获取小时 + let hours = this.date.getHours(); + // 获取分钟 + let minutes = this.date.getMinutes(); + // 分钟小于10在前面加0 + this.currentTime = hours.toString() + ':' + (minutes < 10 ? '0' + minutes : minutes.toString()); + } + + // 退出当前页面时将窗口重新设置成初始状态 + aboutToDisappear() { + if (this.context !== undefined) { + window.getLastWindow(this.context, async (err, data) => { + if (err.code !== 0) { + console.log('getLastWindow failed. error is:', JSON.stringify(err)); + data.setWindowSystemBarEnable(['status', 'navigation']); + data.setWindowLayoutFullScreen(false); + } + }) + } + } + + getBoundingRectPosition(): TextMargin { + if (this.boundingRect !== null && this.displayClass !== null && this.boundingRect[0] !== undefined) { + // 不可用区域右侧到屏幕右边界的距离:屏幕宽度减去左侧宽度和不可用区域宽度 + let boundingRectRight: number = + this.displayClass.width - (this.boundingRect[0].left + this.boundingRect[0].width); + // 不可用区域左侧到屏幕左边界的距离:getCutoutInfo接口可以直接获取 + let boundingRectLeft: number = this.boundingRect[0].left; + // 部分设备不可用区域在中间时存在左右距离会有10像素以内的差距,获取到的左右距离差值绝对值小于10都按照不可用区域位于中间处理 + if (Math.abs(boundingRectLeft - boundingRectRight) <= 10) { + return { left: 0, right: 0 }; + } + if (boundingRectLeft > boundingRectRight) { + // 不可用区域在右边 + return { left: 0, right: this.displayClass.width - boundingRectLeft }; + } else if (boundingRectLeft < boundingRectRight) { + // 不可用区域在左边 + return { left: this.boundingRect[0].left + this.boundingRect[0].width, right: 0 }; + } + } + return { left: 0, right: 0 }; + } + + build() { + Stack() { + Image($r('app.media.digging_hole_screen_2048game')) + .objectFit(ImageFit.Fill) + .width('100%') + .height('100%') + .onClick(() => { + this.getUIContext().getPromptAction().showToast({ + message: '该功能暂未开发', + duration: 2000 + }) + }) + Column() { + Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) { + Text(this.currentTime) // 时间 + .fontSize(16) + .fontColor(Color.Black) + .fontWeight(FontWeight.Regular) + .padding({ left: 12 }) + .margin({ + left: this.getUIContext().px2vp(this.topTextMargin.left), + top: 14 + }) // 获取的偏移量单位为px需要进行转换 + Text(batteryInfo.batterySOC.toString() + '%')// 电池电量 + .fontSize(16) + .fontColor(Color.Black) + .fontWeight(FontWeight.Regular) + .padding({ right: 16 }) + .margin({ + right: this.getUIContext().px2vp(this.topTextMargin.right), + top: 14 + }) // 获取的偏移量单位为px需要进行转换 + } + .width('100%') + } + .width('100%') + } + .width('100%') + .height('100%') + .alignContent(Alignment.TopStart) + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/FontSetting.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/FontSetting.ets new file mode 100644 index 0000000000000000000000000000000000000000..bf195975473202ea3510343238499941e467fd0b --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/FontSetting.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置Text的字体,可以不受系统设置里显示字体大小的影响 + */ + +// DocsCode 1 +@Entry +@Component +struct CustomDialogDisplayLevel { + @State message: string = 'hello world'; + + build() { + Column() { + Text(this.message) + .fontSize(53) // 默认单位为fp,会跟随系统显示大小变化 + Text(this.message) + .fontSize(this.getUIContext().px2fp(160) + 'px') // 使用像素单位,不会跟随系统显示大小变化 + Blank() + .color(0xff0000) + .height(30) + .width(226) + .margin({ bottom: 20 }) // 默认单位 vp会跟随系统显示大小变化 + Blank() + .color(0xff0000) + .height(30 + 'px') + .width(this.getUIContext().px2vp(672) + 'px') // 使用像素单位,不会跟随系统显示大小变化 + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/FullNavigationSubcomponent.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/FullNavigationSubcomponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e708a4d01544bbba507876d622dc7a974704abb --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/FullNavigationSubcomponent.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Navigation容器中,如何设置子组件的高度为100%,撑满父容器 +*/ + +// DocsCode 1 +import { window } from '@kit.ArkUI'; + +@Entry +@Component +struct FullNavigationSubcomponent { + context = this.getUIContext(); + + onPageShow(): void { + window.getLastWindow(this.context.getHostContext(), (err, win) => { + win.setWindowLayoutFullScreen(true); + }) + } + + build() { + Navigation() { + Column() { + } + .width('100%') + .height('100%') + .backgroundColor(Color.Black) + } + .width('100%') + .height('100%') + .title('个性化设置') + .titleMode(NavigationTitleMode.Mini) + .backgroundColor(Color.Grey) + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetAppInformation.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetAppInformation.ets new file mode 100644 index 0000000000000000000000000000000000000000..c630b9ab3184fcfa1174236d62e3e012174ded63 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetAppInformation.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取App版本号,版本名,屏幕分辨率等信息 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { bundleManager } from '@kit.AbilityKit'; +// ... +bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION).then((bundleInfo)=>{ + let versionName = bundleInfo.versionName;//应用版本名 + let versionNo = bundleInfo.versionCode;//应用版本号 +}).catch((error: BusinessError )=>{ + console.error("get bundleInfo failed,error is "+error) +}) +// DocsCode 2 +import { common } from '@kit.AbilityKit'; +// ... +context = this.getUIContext(); + +let context = this.context.getHostContext() as common.UIAbilityContext; +let screenDensity = context.config.screenDensity; \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetComponentRenderingTime.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetComponentRenderingTime.ets new file mode 100644 index 0000000000000000000000000000000000000000..632ddf74d34ab65a7668a3bf9754b30a133a004a --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetComponentRenderingTime.ets @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取组件渲染完成时间 +*/ + +// DocsCode 1 +import { inspector } from '@kit.ArkUI'; + +@Entry +@Component +struct GetComponentRenderTime { + @State startTime: number = 0; + private listener: inspector.ComponentObserver = this.getUIContext().getUIInspector().createComponentObserver('IMAGE_ID'); + private onDrawComplete = () => { + // 2.图片组件绘制完成的时间 + console.info('onDrawComplete', new Date().getTime()); + }; + + aboutToAppear() { + // 1.渲染开始的时间 + this.startTime = new Date().getTime(); + console.info('aboutToAppear', this.startTime); + + // layout: 组件布局完成 + // draw: 组件绘制完成 + this.listener.on('draw', this.onDrawComplete); + } + + aboutToDisappear() { + // 销毁之前取消注册回调 + this.listener.off('draw', this.onDrawComplete); + } + + build() { + Column() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) { + Row({ space: 5 }) { + Image($r('app.media.app_icon')) + .width(110) + .height(110) + .id('IMAGE_ID') + } + } + } + .height(320) + .width(360) + .padding({ + right: 10, + top: 10 + }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetCoordinatesFromTouchPoint.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetCoordinatesFromTouchPoint.ets new file mode 100644 index 0000000000000000000000000000000000000000..14a95795368ca095fd4d820835629f9045db8118 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetCoordinatesFromTouchPoint.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在长按手势回调方法里获取手指触摸点的坐标 + */ + +// DocsCode 1 +@Component +struct CoordinatesOfTheFingerTouchPoint { + @State count: number = 0; + private touchAreaRight: number = 0; + private touchAreaBottom: number = 0; + @State positionX: number = 0; + @State positionY: number = 0; + @State gestureEventInfo: string = ''; + + build() { + Column() { + Row() { + Column() { + Text('+') + .fontSize(28) + .position({ x: this.positionX, y: this.positionY }) + } + .height(200) + .width('100%') + .backgroundColor('#F1F3F5') + .onAreaChange((oldValue: Area, newValue: Area) => { + this.touchAreaRight = newValue.width as number; + this.touchAreaBottom = newValue.height as number; + }) + .gesture( + // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件 + GestureGroup(GestureMode.Sequence, + LongPressGesture({ repeat: true }) + .onAction((event: GestureEvent) => { + if (event.repeat) { + this.count++; + } + }), + PanGesture() + .onActionStart(() => { + this.getUIContext().getPromptAction().showToast({ message: 'Pan start', duration: 1000 }); + }) + .onActionUpdate((event: GestureEvent) => { + for (let i = 0; i < event.fingerList.length; i++) { + if (event.fingerList[i] == undefined + || event.fingerList[i].localX < 0 + || event.fingerList[i].localY < 0 + || event.fingerList[i].localX > this.touchAreaRight + || event.fingerList[i].localY > this.touchAreaBottom) { + return; + } + this.positionX = event.fingerList[i].localX; + this.positionY = event.fingerList[i].localY; + } + this.gestureEventInfo = 'sequence gesture\n' + 'LongPress onAction' + this.count + + '\nX:' + this.positionX + '\nY:' + this.positionY; + }) + .onActionEnd(() => { + this.getUIContext().getPromptAction().showToast({ message: 'Pan end', duration: 1000 }); + }) + ) + .onCancel(() => { + this.getUIContext().getPromptAction().showToast({ message: '取消', duration: 1000 }); + }) + ) + } + .padding(12) + .borderRadius(24) + .backgroundColor(Color.White) + + Text(this.gestureEventInfo) + .fontSize(18) + .width('100%') + .textAlign(TextAlign.Start) + .padding({ left: 18, top: 30 }) + } + .height('100%') + .width('100%') + .backgroundColor('#F1F3F5') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetDarkModeColorSync.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetDarkModeColorSync.ets new file mode 100644 index 0000000000000000000000000000000000000000..660648f0639428d153aa9f7a29ddc68f6c6dec62 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetDarkModeColorSync.ets @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在系统深色模式下使用getColorSync(resource)返回深色颜色值 +*/ + +// DocsCode 1 +this.getUIContext().getHostContext()!.resourceManager.getColorSync($r('app.color.xxx').id); +// DocsCode 1 + +// DocsCode 2 +"metadata": [ + { + "name": "ContextResourceConfigLoadFromParentTemp", + "value": "true" + } +] +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetHorizontalAndVerticalScreenStatus.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetHorizontalAndVerticalScreenStatus.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e6c87345c2bb4ec8d35e633e8c6864d3d08da59 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetHorizontalAndVerticalScreenStatus.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取设备屏幕横竖屏状态 +*/ + +// DocsCode 1 +import { mediaquery, UIContext } from '@kit.ArkUI'; + +let listener = UIContext.getMediaQuery().matchMediaSync('(orientation: landscape)'); //监听横屏事件 +function onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) { + console.info('mediaQueryResult.matches:' + mediaQueryResult.matches) + if (mediaQueryResult.matches) { + // do something here + } else { + // do something here + } +} +listener.on('change', onPortrait) // 注册回调 +listener.off('change', onPortrait) // 取消注册回调 + +@Entry +@Component +struct Index { + build() { + Column() { + Column() { + Text('test') + } + .width('100%') + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.End) + } +} +// DocsCode 1 + +// DocsCode 2 +import { display, window } from '@kit.ArkUI'; + +@Entry +@Component +struct windowRotation { + build() { + Text("Scroll Area") + .width("100%") + .height("100%") + .backgroundColor(0X330000FF) + .fontSize(16) + .textAlign(TextAlign.Center) + .onClick(() => { + window.getLastWindow(this.getUIContext().getHostContext(), (err, win) => { + let cutOutInfo = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE) + console.log(JSON.stringify(cutOutInfo)) + if (window.Orientation.AUTO_ROTATION) { + let rotation: number = display.getDefaultDisplaySync().orientation // 获取当前屏幕的枚举值 + console.log('' + rotation); + if (rotation == 0) { + console.log("CutOutInfo 竖屏数据: " + JSON.stringify(cutOutInfo)); + } else if (rotation == 1) { + console.log("CutOutInfo 横屏数据: " + JSON.stringify(cutOutInfo)); + } else if (rotation == 2) { + console.log("CutOutInfo 反向竖屏数据: " + JSON.stringify(cutOutInfo)); + } else { + console.log("CutOutInfo 反向横屏数据: " + JSON.stringify(cutOutInfo)); + } + } + }) + }) + }} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetRouterBackParam.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetRouterBackParam.ets new file mode 100644 index 0000000000000000000000000000000000000000..5ff4d98fe9ee02aa437cfd18a8b4bb50d875d8d6 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetRouterBackParam.ets @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取router.back传递的参数 +*/ + +// DocsCode 1 +class InfoTmp { + age: number = 0 +} + +class RouTmp { + id: object = () => { + } + info: InfoTmp = new InfoTmp() +} + +const params: RouTmp = this.getUIContext().getRouter().getParams() as RouTmp; // 获取传递过来的参数对象 +const id: object = params.id // 获取id属性的值 +const age: number = params.info.age // 获取age属性的值 +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetTextWidth.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetTextWidth.ets new file mode 100644 index 0000000000000000000000000000000000000000..b929b0ebc4df286119781e7c2ffe7c61c02611e9 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetTextWidth.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取Text组件中文字的宽度 +*/ + +// DocsCode 1 +@Entry +@Component +struct Index { + @State textWidth: number = this.getUIContext().getMeasureUtils().measureText({ + textContent: "Hello word", + fontSize: '50px' + }) + + build() { + Row() { + Column() { + Text(`The width of 'Hello World': ${this.textWidth}`) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/GetWindowStageInstanceInPage.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetWindowStageInstanceInPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..bfad6ed8f1ef8c3a1680b1f3dcd08433555cdbce --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/GetWindowStageInstanceInPage.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Page中获取WindowStage实例 +*/ + +// DocsCode 1 +import { UIAbility } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +export default class EntryAbility extends UIAbility { + // ... + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + console.info('windowStage+++', JSON.stringify(windowStage)) + AppStorage.setAndLink('windowStage', windowStage) + } + + // ... +} +// DocsCode 1 + +// DocsCode 2 +// Index.ets +import common from '@ohos.app.ability.common'; + +@Entry +@Component +struct Index { + @State showAbility: string = 'get windowStage' + + build() { + Row() { + Column() { + Text(this.showAbility) + .fontSize(30) + .fontWeight(FontWeight.Bold) + .onClick(() => { + let context = this.getUIContext().getHostContext() as common.UIAbilityContext; + console.info('获取到的WindowStage实例:',JSON.stringify(context.windowStage)) + }); + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/HandleDraw9PatchReplacementRegimen.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/HandleDraw9PatchReplacementRegimen.ets new file mode 100644 index 0000000000000000000000000000000000000000..b2c2afa90c5bb4b5c2ad180f91b011a0bb06a07b --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/HandleDraw9PatchReplacementRegimen.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:是否有处理"9图"(又称"draw9patch"、".9图"、"点9图"等)的平替方案 +*/ + +// DocsCode 1 +@Entry +@Component +struct NineMapPrinciple { + build() { + Row() { + Image($r('app.media.startIcon')) + .resizable({ slice: { top: 10, left: 10, bottom: 50, right: 50 } }) + } + .height('50%') + } +} +// DocsCode 1 + + +// DocsCode 2 +@Entry +@Component +struct ChatBubbleStretchDemo { + @State text: string = 'Hello World Hello World Hello World Hello World'; + @State left: number = 10; + @State right: number = 10; + @State top: number = 10; + @State bottom: number = 10; + @State line: number = 2; + @State textSize: SizeOptions = this.getUIContext().getMeasureUtils().measureTextSize({ + textContent: this.text + }); + + build() { + Column() { + Stack() { + Image($r('app.media.lightBluexhdpi')) + .width(px2vp(Number(`${this.textSize.width}`)) < 350 ? 60 + px2vp + (Number(`${this.textSize.width}`)) : 350) + .height(this.text.length < 40 ? 50 + px2vp(Number(`${this.textSize.height}`)) + : 50 + (px2vp(Number(`${this.textSize.height}`)) * this.line)) + .resizable({ + slice: { + top: `${this.top}px`, + left: `${this.left}px`, + bottom: `${this.bottom}px`, + right: `${this.right}px` + } + }) + Text(this.text) + } + .width(350) + .height(200) + } + .height('100%') + .width('100%') + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ImageCanNotUseBindContextMenu.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ImageCanNotUseBindContextMenu.ets new file mode 100644 index 0000000000000000000000000000000000000000..916712871edc98fdca0c7b156224454d4fa24944 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ImageCanNotUseBindContextMenu.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Image无法使用bindContextMenu +*/ + +// DocsCode 1 +@Entry +@Component +struct Index { + @Builder + MenuBuilder() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Button('Test ContextMenu1') + Divider().strokeWidth(2).margin(5).color(Color.Black) + Button('Test ContextMenu2') + Divider().strokeWidth(2).margin(5).color(Color.Black) + Button('Test ContextMenu3') + } + .width(200) + .height(160) + } + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Column() { + Image($r('app.media.icon')) + .draggable(false) + .width('100vp') + } + .bindContextMenu(this.MenuBuilder, ResponseType.LongPress) + .onDragStart(() => { + // 拖拽时关闭菜单 + this.getUIContext().getContextMenuController().close() + }) + + } + .width('100%') + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/Index.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/InertialSlidingEffect.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/InertialSlidingEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..81c2ee26be66aad1a8b914fc13b3c927a511bfb0 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/InertialSlidingEffect.ets @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现手指离开屏幕后的惯性滑动效果 +*/ + +// DocsCode 1 +@Entry +@Component +struct PanGestureExample { + @State offsetX: number = 0; + @State offsetY: number = 0; + @State positionX: number = 0; + @State positionY: number = 0; + private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Up | PanDirection.Down }); + + build() { + Column() { + Text('PanGesture offset:\nX: ' + this.offsetX + '\n' + 'Y: ' + this.offsetY) + } + .height(300) + .width(300) + .padding(20) + .border({ width: 3 }) + .margin(30) + .translate({ x: this.offsetX, y: this.offsetY, z: 0 }) // 以组件左上角为坐标原点进行移动 + // 上下拖动触发该手势事件 + .gesture( + PanGesture(this.panOption) + .onActionStart((event?: GestureEvent) => { + console.info('Pan start'); + }) + .onActionUpdate((event?: GestureEvent) => { + if (event) { + this.getUIContext().animateTo({ + curve: Curve.LinearOutSlowIn, + iterations: 1, + tempo: 10000, + playMode: PlayMode.Normal, + onFinish: () => { + console.info('play end'); + } + }, () => { + this.offsetX = this.positionX + event.offsetX; + this.offsetY = this.positionY + event.offsetY; + }) + } + }) + .onActionEnd((event?: GestureEvent) => { + if (event) { + this.getUIContext().animateTo({ + curve: Curve.LinearOutSlowIn, + iterations: 1, + playMode: PlayMode.Normal, + onFinish: () => { + console.info('play end'); + } + }, () => { + this.offsetX = this.positionX + event.offsetX * 2; + this.offsetY = this.positionY + event.offsetY * 2; + }) + } + this.positionX = this.offsetX; + this.positionY = this.offsetY; + console.info('Pan end'); + }) + ) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/InsertComponentInTabBar.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/InsertComponentInTabBar.ets new file mode 100644 index 0000000000000000000000000000000000000000..b6033927396ca3d2558ed5915219d2299817259e --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/InsertComponentInTabBar.ets @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Tabs的tabBar中添加其他组件 +*/ + +// DocsCode 1 +import { componentUtils } from '@kit.ArkUI'; + +@Entry +@Component +struct TabsDemo { + @State tabArray: Array = [0, 1, 2]; + @State tabArrayVal: number = this.tabArray.length - 1; + @State currentIndex: number = 0; + @State animationDuration: number = 300; + @State indicatorLeftMargin: number = 0; + @State indicatorWidth: number = 0; + private controller: TabsController = new TabsController(); + private tabsWidth: number = 0; + + // 单独的页签 + @Builder + tab(tabName: string, tabItem: number, tabIndex: number) { + Row({ space: 20 }) { + Text(tabName).fontSize(18) + .fontColor(tabItem === this.currentIndex ? Color.Red : Color.Black) + .id(tabIndex.toString()) + .onAreaChange((oldValue: Area, newValue: Area) => { + if (this.currentIndex === tabIndex && (this.indicatorLeftMargin === 0 || this.indicatorWidth === 0)) { + if (newValue.position.x !== undefined) { + let positionX = Number.parseFloat(newValue.position.x.toString()); + this.indicatorLeftMargin = Number.isNaN(positionX) ? 0 : positionX; + } + let width = Number.parseFloat(newValue.width.toString()); + this.indicatorWidth = Number.isNaN(width) ? 0 : width; + } + }) + } + .justifyContent(FlexAlign.Center) + .constraintSize({ minWidth: 35 }) + .width(80) + .height(35) + .borderRadius({ + topLeft: 10, + topRight: 10 + }) + .onClick(() => { + this.controller.changeIndex(tabIndex); + this.currentIndex = tabIndex; + }) + } + + build() { + Column() { + // 页签 + Stack({ alignContent: Alignment.TopStart }) { + Scroll() { + Row() { + ForEach(this.tabArray, (item: number, index: number) => { + this.tab('页签' + item, item, index); + }) + Text('+') + .width(36) + .height(50) + .fontSize(28) + .borderRadius(5) + .padding({ + left: 5, + bottom: 2 + }) + .onClick(() => { + this.tabArray.push(++this.tabArrayVal); + }) + } + .justifyContent(FlexAlign.SpaceBetween) + } + .align(Alignment.Start) + .scrollable(ScrollDirection.Horizontal) + .scrollBar(BarState.Off) + .width('100%') + + Column() + .width(this.indicatorWidth) + .height(2) + .backgroundColor(Color.Red) + .borderRadius(2) + .margin({ + left: this.indicatorLeftMargin, + top: 38 + }) + } + .width('100%') + + Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { + ForEach(this.tabArray, (item: number, index: number) => { + TabContent() { + Text('我是页面' + item + '的内容') + .height(300) + .width('100%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + .backgroundColor(Color.Pink) + }) + } + .onAreaChange((oldValue: Area, newValue: Area) => { + let width = Number.parseFloat(newValue.width.toString()); + this.tabsWidth = Number.isNaN(width) ? 0 : width; + }) + .barWidth('100%') + .barHeight(0) + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + .animationDuration(this.animationDuration) + .onChange((index: number) => { + this.currentIndex = index; // 监听索引index的变化,实现页签内容的切换。 + }) + .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => { + // 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。 + this.currentIndex = targetIndex; + let targetIndexInfo = this.getTextInfo(targetIndex); + this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width); + }) + .onAnimationEnd((index: number, event: TabsAnimationEvent) => { + // 切换动画结束时触发该回调。下划线动画停止。 + let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event); + this.startAnimateTo(0, currentIndicatorInfo.left, currentIndicatorInfo.width); + }) + .onGestureSwipe((index: number, event: TabsAnimationEvent) => { + // 在页面跟手滑动过程中,逐帧触发该回调。 + let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event); + this.currentIndex = currentIndicatorInfo.index; + this.indicatorLeftMargin = currentIndicatorInfo.left; + this.indicatorWidth = currentIndicatorInfo.width; + }) + } + .height('100%') + } + + // 获取组件大小、位置、平移缩放旋转及仿射矩阵属性信息。 + private getTextInfo(index: number): Record { + let modePosition: componentUtils.ComponentInfo = componentUtils.getRectangleById(index.toString()); + return { 'left': px2vp(modePosition.windowOffset.x), 'width': px2vp(modePosition.size.width) }; + } + + private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record { + let nextIndex = index; + if (index > 0 && event.currentOffset > 0) { + nextIndex--; + } else if (index < 3 && event.currentOffset < 0) { + nextIndex++; + } + let indexInfo = this.getTextInfo(index); + let nextIndexInfo = this.getTextInfo(nextIndex); + let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth); + // 页面滑动超过一半,tabBar切换到下一页。 + let currentIndex = swipeRatio > 0.5 ? nextIndex : index; + let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * swipeRatio; + let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * swipeRatio; + return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth }; + } + + private startAnimateTo(duration: number, leftMargin: number, width: number) { + this.getUIContext().animateTo({ + // 动画时长 + duration: duration, + // 动画曲线 + curve: Curve.Linear, + // 播放次数 + iterations: 1, + // 动画模式 + playMode: PlayMode.Normal, + onFinish: () => { + console.info('play end'); + } + }, () => { + this.indicatorLeftMargin = leftMargin; + this.indicatorWidth = width; + }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/IntegrateSOLibrary.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/IntegrateSOLibrary.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b47acfccbe67a309d365e8ddb4a0615b97d45eb --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/IntegrateSOLibrary.ets @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在Native侧如何集成三方SO库 +*/ + +// DocsCode 1 +// sub.h +extern "C" { + double sub(double a, double b); +} +// sub.cpp +#include +#include "sub.h" +double sub(double a, double b) +{ + return a - b; +} +// CMakeLists.txt +cmake_minimum_required(VERSION 3.4.1) +project(libSub) +#编译源码 +add_library(nativeSub SHARED sub.cpp) +// DocsCode 2 +# CMakeLists.txt +cmake_minimum_required(VERSION 3.4.1) +project(hello) +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${NATIVERENDER_ROOT_PATH} +${NATIVERENDER_ROOT_PATH}/include) +add_library(library SHARED hello.cpp) +target_link_libraries(library PUBLIC libace_napi.z.so libhilog_ndk.z.so) +target_link_libraries(library PUBLIC ${NATIVERENDER_ROOT_PATH}/../../../libs/arm64-v8a/libnativeSub.so) +// DocsCode 3 +#include "sub.h" +static napi_value Sub(napi_env env, napi_callback_info info) +{ + size_t requireArgc = 2; + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); + napi_valuetype valuetype0; + napi_typeof(env, args[0], &valuetype0); + napi_valuetype valuetype1; + napi_typeof(env, args[1], &valuetype1); + double value0; + napi_get_value_double(env, args[0], &value0); + double value1; + napi_get_value_double(env, args[1], &value1); + napi_value sum; + napi_create_double(env, sub(value0 - value1), &sum); + return sum; +} +// DocsCode 4 +import { hilog } from '@kit.PerformanceAnalysisKit'; +import testNapi from 'libentry.so'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + context = this.getUIContext(); + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + let path = this.context.getHostContext()?.bundleCodeDir; // 获取项目路径 + hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.subSobyDlOpenSo(2, 3, path + '/libs/arm64/libnativeSub.so')); // 传递参数路径信息到Native侧 + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 5 +#include + typedef double (*Sub)(double, double); +static napi_value SubSobyDlOpenSo(napi_env env, napi_callback_info info) { + size_t requireArgc = 3; + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + double value0; + napi_get_value_double(env, args[0], &value0); + double value1; + napi_get_value_double(env, args[1], &value1); + char* path = new char[1024]; + size_t size = 1024; + napi_get_value_string_utf8(env, args[2], path, 255, &size); // 获取动态库路径信息 + void *handle = dlopen(path, RTLD_LAZY); // 打开一个动态链接库.路径为path + napi_value result; + Sub sub_func = (Sub)dlsym(handle, "sub"); // 获取函数名为sub的函数 + napi_create_double(env, sub_func(value0, value1), &result); + dlclose(handle); // 最后记得close动态库 + return result; +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/JumpSystemFileManagement.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/JumpSystemFileManagement.ets new file mode 100644 index 0000000000000000000000000000000000000000..e4ddcd35d6d2181fc99e0c48014839c22e6ae57c --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/JumpSystemFileManagement.ets @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何跳转到系统文件管理App界面 +*/ + +// DocsCode 1 +import { common, OpenLinkOptions } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const TAG: string = '[UIAbilityComponentsOpenLink]'; +const DOMAIN_NUMBER: number = 0xFF00; + +@Entry +@Component +struct Index { + @State message: string = '拉起文件管理'; + context = this.getUIContext(); + + build() { + Row() { + Column() { + Button(this.message) + .width('100%') + .fontWeight(FontWeight.Bold) + .onClick(() => { + let context: common.UIAbilityContext = this.context.getHostContext() as common.UIAbilityContext; + let link: string = 'filemanager://openDirectory'; + let openLinkOptions: OpenLinkOptions = { + parameters: { + 'fileUri': '' + } + }; + try { + context.openLink(link, openLinkOptions) + .then(() => { + hilog.info(DOMAIN_NUMBER, TAG, 'open link success.'); + }).catch((err: BusinessError) => { + hilog.error(DOMAIN_NUMBER, TAG, `open link failed. Code is ${err.code}, message is ${err.message}`); + }); + } catch (paramError) { + hilog.error(DOMAIN_NUMBER, TAG, + `Failed to start link. Code is ${paramError.code}, message is ${paramError.message}`); + } + }) + } + .padding({ left: 16, right: 16 }) + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ListFoldAnimationEffect.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ListFoldAnimationEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..87efb505b4c9db1e406b009f667cec51025450ff --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ListFoldAnimationEffect.ets @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现List的折叠动画效果 +*/ + +// DocsCode 1 +@Entry +@Component +struct ListCollapseExpand { + private arr: number[] = [0, 1, 2, 3, 4, 5, 6]; + @State isContentShow: boolean = true; + @State selectItem: number = 0; + + build() { + Column() { + List({ initialIndex: 0 }) { + ForEach(this.arr, (item: number, index: number) => { + ListItem() { + Column() { + Row() { + Text(item.toString()) + Button(this.isContentShow && this.selectItem === item ? '收起' : '展开') + .onClick(() => { + this.getUIContext().animateTo({ + duration: 300, + onFinish: () => { + console.info('animation end'); + } + }, () => { + this.isContentShow = !this.isContentShow; + this.selectItem = item; + }) + }) + } + .width('100%') + .justifyContent(FlexAlign.SpaceBetween) + + if (this.isContentShow && this.selectItem === item) { + Text('这是内容区域') + .backgroundColor(Color.Gray) + .width('100%') + .height(100) + } + } + .backgroundColor(0xFFFFFF) + .width('100%') + .padding({ + top: 12, + bottom: 12 + }) + .margin({ top: 10 }) + } + }, (item: string) => item.toString()) + } + .scrollBar(BarState.Off) + .height('100%') + .width('100%') + } + .backgroundColor(0xF1F3F5) + .padding(12) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ListenForScreenRotation.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ListenForScreenRotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..9543ebe8840c8089554b1f63b57a81bdbd7704a4 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ListenForScreenRotation.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何监听屏幕旋转 +*/ + +// DocsCode 1 +import { mediaquery, UIContext } from '@kit.ArkUI'; +let listener = UIContext.getMediaQuery().matchMediaSync('(orientation: landscape)'); // 监听横屏事件 +function onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) { + if (mediaQueryResult.matches) { + // do something here + } else { + // do something here + } +} +listener.on('change', onPortrait) // 注册回调 +listener.off('change', onPortrait) // 取消注册回调 +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/MultiSoInterdependenceDecoupling.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/MultiSoInterdependenceDecoupling.ets new file mode 100644 index 0000000000000000000000000000000000000000..f9f697d570f07bbf6a47187fa862d6700ebd0e05 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/MultiSoInterdependenceDecoupling.ets @@ -0,0 +1,193 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:多so相互依赖场景下如何解耦 +*/ + +// DocsCode 1 +// a.cpp +extern "C" { // 一定要用extern "C" {}括起来 + #include "a.h" + #include + #include "stdio.h" + typedef int (*FUNC_SUB)(int, int); + int add(int a, int b) { return a + b; } + int getb(char *path, int a, int b) { // path:从ArkTS侧传递So文件的沙箱路径(注意路径要从arkts侧传递、不然有可能找不到路径、具体代码后续会列出) + void *handle = dlopen(path, RTLD_LAZY); // 打开一个动态链接库.路径为path + if (!handle) { + return 0; + } + FUNC_SUB sub_func = (FUNC_SUB)dlsym(handle, "sub"); // 获取函数名为sub的函数 + int res = sub_func(a, b); // 调用函数 + dlclose(handle); // close动态链接库 + return res; + } +} +// a.h +extern "C" { + #ifndef DemoSO_a_H + #define DemoSO_a_H + int add(int a, int b); + int getb(char *path, int a, int b); + #endif // DemoSO_a_H +} +// b.cpp +extern "C" { // 一定要用extern "C" {}括起来 + #include "b.h" + #include + #include "stdio.h" + typedef int (*FUNC_ADD)(int, int); + int sub(int a, int b) { return a - b; } + int geta(char *path, int a, int b) { // path:从ArkTS侧传递So文件的沙箱路径(注意路径要从arkts侧传递、不然有可能找不到路径、具体代码后续会列出) + void *handle = dlopen(path, RTLD_LAZY); // 打开一个动态链接库.路径为path + if (!handle) { + return 0; + } + FUNC_ADD add_func = (FUNC_ADD)dlsym(handle, "add"); // 获取函数名为add的函数 + int res = add_func(a, b); // 调用函数 + dlclose(handle); // close动态链接库 + return res; + } +} +// b.h +extern "C" { + #ifndef DemoSO_b_H + #define DemoSO_b_H + int sub(int a, int b); + int geta(char *path, int a, int b); + #endif // DemoSO_b_H +} +// CMakeLists.txt +cmake_minimum_required(VERSION 3.4.1) +project(liba) +add_library(a SHARED a.cpp) // 编译库liba.so +target_link_libraries(a PUBLIC libace_napi.z.so libhilog_ndk.z.so) +project(libb) +add_library(b SHARED b.cpp) // 编译库libb.so +target_link_libraries(b PUBLIC libace_napi.z.so libhilog_ndk.z.so) +// DocsCode 2 +// CMakeLists.txt +cmake_minimum_required(VERSION 3.4.1) +project(DemoSO) +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${NATIVERENDER_ROOT_PATH} +${NATIVERENDER_ROOT_PATH}/include) +add_library(demoso SHARED hello.cpp) // 添加libdemoso.so文件 +// 添加依赖库liba.so、libb.so。 注意需要带上路径、不然无法找到对应的so库 +target_link_libraries(demoso PUBLIC libace_napi.z.so ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/liba.so ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libb.so) + +// index.ets +import { hilog } from '@kit.LancetKit'; +import testNapi from 'libdemoso.so'; +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + private path: string = ''; + context = this.getUIContext(); + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.path = this.context.getHostContext()?.bundleCodeDir; // 获取路径 + hilog.info(0x0000, 'testTag', 'Test NAPI 5 + 3 = %{public}d', testNapi.add(5, 3, this.path + '/libs/arm64/liba.so')); // 调用native侧函数 + hilog.info(0x0000, 'testTag', 'Test NAPI 5 - 3 = %{public}d', testNapi.sub(5, 3, this.path + '/libs/arm64/libb.so')); + }) + } + .width('100%') + } + .height('100%') + } +} + +// index.d.ts +export const add: (a: number, b: number, path: string) => number; +export const sub: (a: number, b: number, path: string) => number; + +// hello.cpp +#include "a.h" +#include "b.h" +#include "napi/native_api.h" + +static napi_value Add(napi_env env, napi_callback_info info) { + size_t requireArgc = 3; + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_valuetype valuetype0; + napi_typeof(env, args[0], &valuetype0); + napi_valuetype valuetype1; + napi_typeof(env, args[1], &valuetype1); + napi_valuetype valuetype2; + napi_typeof(env, args[2], &valuetype2); + int value0; + napi_get_value_int32(env, args[0], &value0); + int value1; + napi_get_value_int32(env, args[1], &value1); + char path[255]; + size_t size = 255; + napi_get_value_string_utf8(env, args[2], path, 255, &size); + int res = geta(path, value0, value1); // 调用函数并传递沙箱路径 + napi_value sum; + napi_create_int32(env, res, &sum); + return sum; +} +static napi_value Sub(napi_env env, napi_callback_info info) { + size_t requireArgc = 3; + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_valuetype valuetype0; + napi_typeof(env, args[0], &valuetype0); + napi_valuetype valuetype1; + napi_typeof(env, args[1], &valuetype1); + napi_valuetype valuetype2; + napi_typeof(env, args[2], &valuetype2); + int value0; + napi_get_value_int32(env, args[0], &value0); + int value1; + napi_get_value_int32(env, args[1], &value1); + char path[255]; + size_t size = 255; + napi_get_value_string_utf8(env, args[2], path, 255, &size); + int res = getb(path, value0, value1); // 调用函数并传递沙箱路径 + napi_value sum; + napi_create_int32(env, res, &sum); + return sum; +} +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor desc[] = {{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"sub", nullptr, Sub, nullptr, nullptr, nullptr, napi_default, nullptr}}; +napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "demoso", + .nm_priv = ((void *)0), + .reserved = {0}, +}; +extern "C" __attribute__((constructor)) void RegisterDemosoModule(void) { napi_module_register(&demoModule); } \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideAccessRawfile.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideAccessRawfile.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d45dcca9c6a7014d45f5e11fc1feaa2e753ace4 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideAccessRawfile.ets @@ -0,0 +1,109 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Native侧访问应用包内Rawfile资源 +*/ + +// DocsCode 1 +import { resourceManager } from "@kit.LocalizationKit"; +export const getRawFileContent: (resMgr: resourceManager.ResourceManager, path: string) => Uint8Array; +// DocsCode 2 +#include "napi/native_api.h" +#include +#include +#include "hilog/log.h" + +const int GLOBAL_RESMGR = 0xFF00; +const char *TAG = "[Sample_rawfile]"; +namespace { + napi_value CreateJsArrayValue(napi_env env, std::unique_ptr &data, long length) + { + napi_value buffer; + napi_status status = napi_create_external_arraybuffer( + env, data.get(), length, + [](napi_env env, void *data, void *hint) { + delete[] static_cast(data); + }, + nullptr, &buffer); + if (status != napi_ok) { + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create external array buffer"); + return nullptr; + } + napi_value result = nullptr; + status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); + if (status != napi_ok) { + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create media typed array"); + return nullptr; + } + data.release(); + return result; + } +} +static napi_value GetRawFileContent(napi_env env, napi_callback_info info) +{ + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "GetFileContent Begin"); + size_t requireArgc = 3; + size_t argc = 2; + napi_value argv[2] = { nullptr }; + // 获取参数信息 + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 + NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); + size_t strSize; + char strBuf[256]; + napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); + std::string filename(strBuf, strSize); + // 获取rawfile指针对象 + RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); + if (rawFile != nullptr) { + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "OH_ResourceManager_OpenRawFile success"); + } + // 获取rawfile大小并申请内存 + long len = OH_ResourceManager_GetRawFileSize(rawFile); + std::unique_ptr data= std::make_unique(len); + // 一次性读取rawfile全部内容 + int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); + // 关闭打开的指针对象 + OH_ResourceManager_CloseRawFile(rawFile); + OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); + // 转为js对象 + return CreateJsArrayValue(env, data, len); +} +// DocsCode 3 +import testNapi from 'libnativeaccessres.so' // 导入so + +@Entry +@Component +struct Index { + @State message: string = 'Native Access Resource'; + context = this.getUIContext(); + private resMgr = this.context.getHostContext()?.resourceManager; // 获取本应用包的资源对象 + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + let rawfileContext = testNapi.getRawFileContent(this.resMgr, 'rawfile.txt'); + console.log("rawfileContext" + rawfileContext); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideCrossModuleAccessR.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideCrossModuleAccessR.ets new file mode 100644 index 0000000000000000000000000000000000000000..308a24e7f8808b129802d547f66ce89d9e1f07a8 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideCrossModuleAccessR.ets @@ -0,0 +1,109 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Native侧跨模块访问资源 +*/ + +// DocsCode 1 +import { resourceManager } from "@kit.LocalizationKit"; +export const getRawFileContent: (resMgr: resourceManager.ResourceManager, path: string) => Uint8Array; +// DocsCode 2 +#include "napi/native_api.h" +#include +#include +#include "hilog/log.h" + +const int GLOBAL_RESMGR = 0xFF00; +const char *TAG = "[Sample_rawfile]"; +namespace { + napi_value CreateJsArrayValue(napi_env env, std::unique_ptr &data, long length) + { + napi_value buffer; + napi_status status = napi_create_external_arraybuffer( + env, data.get(), length, + [](napi_env env, void *data, void *hint) { + delete[] static_cast(data); + }, + nullptr, &buffer); + if (status != napi_ok) { + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create external array buffer"); + return nullptr; + } + napi_value result = nullptr; + status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); + if (status != napi_ok) { + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create media typed array"); + return nullptr; + } + data.release(); + return result; + } +} +static napi_value GetRawFileContent(napi_env env, napi_callback_info info) +{ + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "GetFileContent Begin"); + size_t requireArgc = 3; + size_t argc = 2; + napi_value argv[2] = { nullptr }; + // 获取参数信息 + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 + NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); + size_t strSize; + char strBuf[256]; + napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); + std::string filename(strBuf, strSize); + // 获取rawfile指针对象 + RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); + if (rawFile != nullptr) { + OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "OH_ResourceManager_OpenRawFile success"); + } + // 获取rawfile大小并申请内存 + long len = OH_ResourceManager_GetRawFileSize(rawFile); + std::unique_ptr data= std::make_unique(len); + // 一次性读取rawfile全部内容 + int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); + // 关闭打开的指针对象 + OH_ResourceManager_CloseRawFile(rawFile); + OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); + // 转为js对象 + return CreateJsArrayValue(env, data, len); +} +// DocsCode 3 +import testNapi from 'libnativecrossmoduleaccessres.so'; + +@Entry +@Component +struct Index { + @State message: string = 'Native Cross Module Access Resource'; + context = this.getUIContext(); + private resMgr = this.context.getHostContext()?.createModuleContext('NativeAccessRes').resourceManager; // 获取本应用包的资源对象 + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + let rawfileContext = testNapi.getRawFileContent(this.resMgr, 'rawfile.txt'); + console.log("rawfileContext" + rawfileContext); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideOperableFileDirectory.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideOperableFileDirectory.ets new file mode 100644 index 0000000000000000000000000000000000000000..da488292d992c0d0880ed10f2c00482204c877a1 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/NativeSideOperableFileDirectory.ets @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Native侧如何获取可操作的文件目录 +*/ + +// DocsCode 1 +import { common } from '@kit.AbilityKit'; + +context = this.getUIContext(); +let hostContext = this.context.getHostContext() as common.UIAbilityContext; +let filesDir = hostContext.filesDir; \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/NinePictureReplacemetPan.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/NinePictureReplacemetPan.ets new file mode 100644 index 0000000000000000000000000000000000000000..3199f31b5acaf2110b99dff6e1e2bd792847eaf7 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/NinePictureReplacemetPan.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:是否有处理"9图"(又称"draw9patch"、".9图"、"点9图"等)的平替方案 + */ + +// DocsCode 2 +import { MeasureText } from '@kit.ArkUI'; + +@Entry +@Component +struct ChatBubbleStretchDemo { + @State text: string = 'Hello World Hello World Hello World Hello World'; + @State left: number = 10; + @State right: number = 10; + @State top: number = 10; + @State bottom: number = 10; + @State line: number = 2; + @State textSize: SizeOptions = MeasureText.measureTextSize({ + textContent: this.text + }); + + build() { + Column() { + Stack() { + Image($r('app.media.lightBluexhdpi')) + .width(this.getUIContext().px2vp(Number(`${this.textSize.width}`)) < 350 ? 60 + this.getUIContext().px2vp + (Number(`${this.textSize.width}`)) : 350) + .height(this.text.length < 40 ? 50 + this.getUIContext().px2vp(Number(`${this.textSize.height}`)) + : 50 + (this.getUIContext().px2vp(Number(`${this.textSize.height}`)) * this.line)) + .resizable({ + slice: { + top: `${this.top}px`, + left: `${this.left}px`, + bottom: `${this.bottom}px`, + right: `${this.right}px` + } + }) + Text(this.text) + } + .width(350) + .height(200) + } + .height('100%') + .width('100%') + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/OpenFileCSide.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/OpenFileCSide.ets new file mode 100644 index 0000000000000000000000000000000000000000..247578378fa1ac7efa7489cbe5c5a5c2e91ccb1f --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/OpenFileCSide.ets @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:C侧如何打开文件 +*/ + +// DocsCode 1 +import { fileIo, picker } from '@kit.CoreFileKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import testNapi from 'libentry.so'; + +@Entry +@Component +struct Index { + @State message: string = '打开文件'; + context = this.getUIContext(); + + async open() { + const photoSelectOptions = new picker.PhotoSelectOptions(); + photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE + photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目 + let uris: Array = []; + const photoViewPicker = new picker.PhotoViewPicker(); + await photoViewPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => { + uris = photoSelectResult.photoUris; + console.info('photoViewPicker.select to file succeed and uris are:' + uris); + }).catch((err: BusinessError) => { + console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`); + }) + let uri: string = uris[0]; + let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let fd = file.fd + let filesDir = this.context.getHostContext()?.filesDir; + fileIo.copyFileSync(fd, filesDir + '/test2.jpg') + let file2 = fileIo.openSync(filesDir + '/test2.jpg', fileIo.OpenMode.READ_ONLY); + let file3 = fileIo.openSync(filesDir + '/test3.jpg', fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + testNapi.ReadFile(file2.fd, file3.fd) + } + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .onClick(() => { + this.open(); + }) + .width('100%') + } + .height('100%') + } +} + +// DocsCode 2 +static napi_value OpenFile(unsigned int fd, unsigned int fd2) { + OH_LOG_INFO(LOG_APP, "OpenFile"); + + if (fd != -1) { + char buffer[4096]; + ssize_t bytesRead; + // 读取文件内容到缓冲区中 + bytesRead = read(fd, buffer, sizeof(buffer)); + if (bytesRead == -1) { + OH_LOG_INFO(LOG_APP, "读取文件失败"); + close(fd); // 关闭文件描述符 + return nullptr; + } + while (bytesRead != 0) { + OH_LOG_INFO(LOG_APP, "读取文件大小 %{public}lu", bytesRead); + OH_LOG_INFO(LOG_APP, "读取文件cg"); + char *pData1 = buffer; + OH_LOG_INFO(LOG_APP, "文件内容: \n%{public}s", pData1); + ssize_t bytesWrite; + bytesWrite = write(fd2, pData1, bytesRead); + if (bytesWrite == -1) { + OH_LOG_INFO(LOG_APP, "写文件失败"); + close(fd2); // 关闭文件描述符 + return nullptr; + } + bytesRead = read(fd, buffer, sizeof(buffer)); + } + // 关闭文件描述符 + close(fd); + close(fd2); // 关闭文件描述符 + } + return nullptr; +} +static napi_value ReadFile(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + unsigned int fd = -1; + napi_get_value_uint32(env, args[0], &fd); + unsigned int fd2 = -1; + napi_get_value_uint32(env, args[1], &fd2); + OpenFile(fd, fd2); + return nullptr; +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/PrivacyDetailsPage.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/PrivacyDetailsPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..63f2cab96a38dadf988359e74e7a81ab40518bc8 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/PrivacyDetailsPage.ets @@ -0,0 +1,153 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使当前页面弹窗在页面跳转返回之后还存在(隐私详情页场景) +*/ + +// DocsCode 1 +@Component +struct DialogJumpRetained { + @State visible: Visibility = Visibility.None; + + build() { + Stack() { + Row() { + Column() { + Text('Hello World') + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button('click') + .onClick(() => { + if (this.visible === Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }) + .backgroundColor(0x777474) + .fontColor(0x000000) + } + .width('100%') + } + .height('100%') + .backgroundColor(Color.Orange) + + Text('') + .onClick(() => { + if (this.visible == Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }) + .width('100%') + .height('100%') + .opacity(0.5) + .backgroundColor(0x000000) + .visibility(this.visible) + Column() { + GridRow({ + columns: { + xs: 1, + sm: 4, + md: 8, + lg: 12 + }, + breakpoints: { + value: ['400vp', '600vp', '800vp'], + reference: BreakpointsReference.WindowSize + } + }) { + GridCol({ + span: { + xs: 1, + sm: 2, + md: 4, + lg: 8 + }, + offset: { + xs: 0, + sm: 1, + md: 2, + lg: 2 + } + }) { + Column() { + Text('隐私弹窗') + .fontSize(20) + .margin({ + top: 10, + bottom: 10 + }) + Text('是否查看隐私详情') + .fontSize(16) + .margin({ bottom: 10 }) + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Button('关闭弹窗') + .onClick(() => { + if (this.visible === Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }).backgroundColor(0xffffff).fontColor(Color.Black) + Button('跳转详情页') + .onClick(() => { + this.getUIContext().getRouter().pushUrl({ + url: 'pages/Second' + }); + }) + .backgroundColor(0xffffff) + .fontColor(Color.Red) + } + .margin({ bottom: 10 }) + } + .backgroundColor(0xffffff) + .visibility(this.visible) + .clip(true) + .borderRadius(20) + } + } + } + .width('95%') + } + } +} +// DocsCode 1 + +// DocsCode 2 +@Entry +@Component +struct Second { + @State message: string = '隐私详情页'; + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button('返回').onClick(() => { + this.getUIContext().getRouter().back({ + url: 'pages/DialogJumpRetained' + }); + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/PullupTheKeyboard.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/PullupTheKeyboard.ets new file mode 100644 index 0000000000000000000000000000000000000000..5a30cf9583267340bc205d953f123406fcb0848d --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/PullupTheKeyboard.ets @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:输入框拉起键盘时,如何将底部布局弹起到键盘顶部 + */ + +// DocsCode 1 +import { window } from '@kit.ArkUI'; +import { common } from '@kit.AbilityKit'; + +@Entry +struct BottomPopsUpAsTheTopOfKeyboard { + scroller: Scroller = new Scroller(); + private arr: number[] = [0, 1, 2, 3, 4, 5]; + @State scrollHeight: number = 0; + @State isRebuild: boolean = false; + @State keyHeight: number = 0; + @State text: string = ''; + aboutToAppear() { + window.getLastWindow(this.getUIContext().getHostContext() as common.UIAbilityContext).then(currentWindow => { + // 设置窗口的布局为沉浸式布局 + currentWindow.setWindowLayoutFullScreen(true); + let property = currentWindow.getWindowProperties(); + // 初始化窗口高度 + let avoidArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + this.scrollHeight = this.getUIContext().px2vp(property.windowRect.height - avoidArea.bottomRect.height); + // 监听软键盘的隐藏和显示 + currentWindow.on('avoidAreaChange', data => { + if (data.type == window.AvoidAreaType.TYPE_KEYBOARD) { + this.keyHeight = this.getUIContext().px2vp(data.area.bottomRect.height); + this.scrollHeight = + this.getUIContext().px2vp(currentWindow.getWindowProperties().windowRect.height - data.area.bottomRect.height); + return; + } + }) + }) + } + build() { + Stack({ alignContent: Alignment.TopStart }) { + Column() { + Scroll(this.scroller) { + Column() { + TextInput({ text: this.text, placeholder: 'input your word...' }) + .placeholderFont({ + size: 14, + weight: 400 + }) + .width(320) + .height(40) + .margin(200) + .fontSize(14) + .fontColor(Color.Black) + .backgroundColor(Color.White) + ForEach(this.arr, (item: number) => { + Text(item.toString()) + .width('90%') + .height(150) + .backgroundColor(0xFFFFFF) + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .margin({ top: 10 }) + }) + } + .width('100%') + } + .width('100%') + .height(this.scrollHeight) + .layoutWeight(1) + Text('这是一个测试文本') + .width('100%') + .height(50) + .backgroundColor(Color.Red) + .margin({ bottom: this.keyHeight }) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Start) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ReplaceDefaultTimeSet.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ReplaceDefaultTimeSet.ets new file mode 100644 index 0000000000000000000000000000000000000000..decf141b2fc999312ef8b4855e3cd3069036f0c8 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ReplaceDefaultTimeSet.ets @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Grid onItemDragStart默认时间设置替代方案、以及多列GridItem实现通用示例 +*/ + +// DocsCode 1 +import { curves } from '@kit.ArkUI'; + +@Entry +@Component +struct Page { + //元素数组 + @State numbers: number[] = []; + @State row: number = 4; + //元素数组中最后一个元素的索引 + @State lastIndex: number = 0; + @State dragItem: number = -1; + @State scaleItem: number = -1; + @State item: number = -1; + @State offsetX: number = 0; + @State offsetY: number = 0; + // row 设置网格列数 + private str: string = ''; + private dragRefOffsetx: number = 0; + private dragRefOffsety: number = 0; + private FIX_VP_X: number = 108; + private FIX_VP_Y: number = 120; + + aboutToAppear() { + for (let i = 1; i <= 110; i++) { + this.numbers.push(i); + } + this.lastIndex = this.numbers.length - 1; + + // 多列 + for (let i = 0; i < this.row; i++) { + this.str = this.str + '1fr '; + } + } + + itemMove(index: number, newIndex: number): void { + if (!this.isDraggable(newIndex)) { + return; + } + let tmp = this.numbers.splice(index, 1); + this.numbers.splice(newIndex, 0, tmp[0]); + } + + //向下滑 + down(index: number): void { + // 指定固定GridItem不响应事件 + if (!this.isDraggable(index + this.row)) { + return; + } + this.offsetY -= this.FIX_VP_Y; + this.dragRefOffsety += this.FIX_VP_Y; + // 多列 + this.itemMove(index, index + this.row); + } + + //向下滑(右下角为空) + down2(index: number): void { + if (!this.isDraggable(index + 3)) { + return; + } + this.offsetY -= this.FIX_VP_Y; + this.dragRefOffsety += this.FIX_VP_Y; + this.itemMove(index, index + 3); + } + + //向上滑 + up(index: number): void { + if (!this.isDraggable(index - this.row)) { + return; + } + this.offsetY += this.FIX_VP_Y; + this.dragRefOffsety -= this.FIX_VP_Y; + this.itemMove(index, index - this.row); + } + + //向左滑 + left(index: number): void { + if (!this.isDraggable(index - 1)) { + return; + } + this.offsetX += this.FIX_VP_X; + this.dragRefOffsetx -= this.FIX_VP_X; + this.itemMove(index, index - 1); + } + + //向右滑 + right(index: number): void { + if (!this.isDraggable(index + 1)) { + return; + } + this.offsetX -= this.FIX_VP_X; + this.dragRefOffsetx += this.FIX_VP_X; + this.itemMove(index, index + 1); + } + + //向右下滑 + lowerRight(index: number): void { + if (!this.isDraggable(index + this.row + 1)) { + return; + } + this.offsetX -= this.FIX_VP_X; + this.dragRefOffsetx += this.FIX_VP_X; + this.offsetY -= this.FIX_VP_Y; + this.dragRefOffsety += this.FIX_VP_Y; + this.itemMove(index, index + this.row + 1); + } + + //向右上滑 + upperRight(index: number): void { + if (!this.isDraggable(index - (this.row - 1))) { + return; + } + this.offsetX -= this.FIX_VP_X; + this.dragRefOffsetx += this.FIX_VP_X; + this.offsetY += this.FIX_VP_Y; + this.dragRefOffsety -= this.FIX_VP_Y; + this.itemMove(index, index - (this.row - 1)); + } + + //向左下滑 + lowerLeft(index: number): void { + if (!this.isDraggable(index + (this.row - 1))) { + return; + } + this.offsetX += this.FIX_VP_X; + this.dragRefOffsetx -= this.FIX_VP_X; + this.offsetY -= this.FIX_VP_Y; + this.dragRefOffsety += this.FIX_VP_Y; + this.itemMove(index, index + (this.row - 1)); + } + + //向左上滑 + upperLeft(index: number): void { + if (!this.isDraggable(index - (this.row + 1))) { + return; + } + this.offsetX += this.FIX_VP_X; + this.dragRefOffsetx -= this.FIX_VP_X; + this.offsetY += this.FIX_VP_Y; + this.dragRefOffsety -= this.FIX_VP_Y; + this.itemMove(index, index - (this.row + 1)); + } + + //通过元素的索引,控制对应元素是否能移动排序 + isDraggable(index: number): boolean { + return index > -1; //恒成立,所有元素均可移动排序 + } + + build() { + Column() { + Grid() { + ForEach(this.numbers, (item: number) => { + GridItem() { + Text(item + '') + .fontSize(16) + .width('100%') + .textAlign(TextAlign.Center) + .height(100) + .borderRadius(10) + .backgroundColor(0xFFFFFF) + .shadow(this.scaleItem == item ? { + radius: 70, + color: '#15000000', + offsetX: 0, + offsetY: 0 + } : + { + radius: 0, + color: '#15000000', + offsetX: 0, + offsetY: 0 + }) + .animation({ + curve: Curve.Sharp, + duration: 300 + }) + } + .onAreaChange((_oldVal, newVal) => { + // 多列 + this.FIX_VP_X = Math.round(newVal.width as number); + this.FIX_VP_Y = Math.round(newVal.height as number); + }) + // 指定固定GridItem不响应事件 + .hitTestBehavior(this.isDraggable(this.numbers.indexOf(item)) ? HitTestMode.Default : HitTestMode.None) + .scale({ x: this.scaleItem === item ? 1.05 : 1, y: this.scaleItem === item ? 1.05 : 1 }) + .zIndex(this.dragItem === item ? 1 : 0) + .translate(this.dragItem === item ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 }) + .padding(10) + .gesture( + //以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件 + GestureGroup(GestureMode.Sequence, + LongPressGesture({ + repeat: true, + duration: 50 + })//控制触发拖动的长按事件的时间,默认500毫秒,设置小于0为默认值,这里设置为50毫秒 + .onAction((_event?: GestureEvent) => { + this.getUIContext().animateTo({ + curve: Curve.Friction, + duration: 300 + }, () => { + this.scaleItem = item; + }); + }) + .onActionEnd(() => { + this.getUIContext().animateTo({ + curve: Curve.Friction, + duration: 300 + }, () => { + this.scaleItem = -1; + }); + }), + PanGesture({ + fingers: 1, + direction: null, + distance: 0 + }) + .onActionStart(() => { + this.dragItem = item; + this.dragRefOffsetx = 0; + this.dragRefOffsety = 0; + }) + .onActionUpdate((event: GestureEvent) => { + this.offsetY = event.offsetY - this.dragRefOffsety; + this.offsetX = event.offsetX - this.dragRefOffsetx; + + this.getUIContext().animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => { + let index = this.numbers.indexOf(this.dragItem); + // 44 宽度一半 减间距 + if (this.offsetY >= this.FIX_VP_Y / 2 && + (this.offsetX <= this.FIX_VP_X / 2 && this.offsetX >= -this.FIX_VP_X / 2) + && (index + this.row <= this.lastIndex)) { + //向下滑 + this.down(index); + } else if (this.offsetY <= -this.FIX_VP_Y / 2 && + (this.offsetX <= this.FIX_VP_X / 2 && this.offsetX >= -this.FIX_VP_X / 2) + && index - this.row >= 0) { + //向上滑 + this.up(index); + } else if (this.offsetX >= this.FIX_VP_X / 2 && + (this.offsetY <= this.FIX_VP_Y / 2 && this.offsetY >= -this.FIX_VP_Y / 2) + && !(((index - (this.row - 1)) % this.row === 0) || index === this.lastIndex)) { + // ) { + //向右滑 + this.right(index); + } else if (this.offsetX <= -this.FIX_VP_X / 2 && + (this.offsetY <= this.FIX_VP_Y / 2 && this.offsetY >= -this.FIX_VP_Y / 2) + && !(index % this.row === 0)) { + //向左滑 + this.left(index); + } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2 + && ((index + this.row + 1 <= this.lastIndex && !((index - (this.row - 1)) % this.row === 0)) || + !((index - (this.row - 1)) % this.row === 0))) { + //向右下滑 + this.lowerRight(index); + } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY <= -this.FIX_VP_Y / 2 + && !((index - this.row < 0) || ((index - (this.row - 1)) % this.row === 0))) { + //向右上滑 + this.upperRight(index); + } else if (this.offsetX <= -this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2 + && (!(index % this.row === 0) && (index + (this.row - 1) <= this.lastIndex))) { + //向左下滑 + this.lowerLeft(index); + } else if (this.offsetX <= -this.FIX_VP_X / 2 && this.offsetY <= -this.FIX_VP_Y / 2 + && !((index <= this.row - 1) || (index % this.row === 0))) { + //向左上滑 + this.upperLeft(index); + } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2 + && (index === this.lastIndex)) { + //向右下滑(右下角为空) + this.down2(index); + } + }); + }) + .onActionEnd(() => { + this.getUIContext().animateTo({ + curve: curves.interpolatingSpring(0, 1, 400, 38) + }, () => { + this.dragItem = -1; + }); + this.getUIContext().animateTo({ + curve: curves.interpolatingSpring(14, 1, 170, 17), + delay: 150 + }, () => { + this.scaleItem = -1; + }); + }) + ) + .onCancel(() => { + this.getUIContext().animateTo({ + curve: curves.interpolatingSpring(0, 1, 400, 38) + }, () => { + this.dragItem = -1; + }); + this.getUIContext().animateTo({ + curve: curves.interpolatingSpring(14, 1, 170, 17) + }, () => { + this.scaleItem = -1; + }); + }) + ) + }, (item: number) => item.toString()) + } + .width('90%') + .editMode(true) + .scrollBar(BarState.Off) + // 多列 + .columnsTemplate(this.str) + } + .width('100%') + .height('100%') + .backgroundColor('#0D182431') + .padding({ top: 5 }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ResourceNesting.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ResourceNesting.ets new file mode 100644 index 0000000000000000000000000000000000000000..630f51f79b6cf928bb3abd6948cec1dc90c0f2c3 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ResourceNesting.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:通过$r访问应用资源是否支持嵌套形式 +*/ + +// DocsCode 1 + +@Entry +@Component +struct Page16 { + context = this.getUIContext(); + + build() { + Row() { + Column() { + Text($r('app.string.EntryAbility1_label2', + this.context.getHostContext()!.resourceManager.getStringSync($r('app.string.EntryAbility_label'))))//resources\base\element\string.json + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ScreenRotation.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ScreenRotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..474ee501983899a344350395617ead8e5cb1f8a8 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ScreenRotation.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置窗口旋转 +*/ + +// DocsCode 1 +AppStorage.setOrCreate('windowStage',windowStage); + +// DocsCode 2 +import { display, window } from '@kit.ArkUI'; + +@Component +struct ScreenRotation { + windowStage: window.WindowStage = AppStorage.get('windowStage') as window.WindowStage; + // 获取主窗口的方式 + mainWin: window.Window = this.windowStage.getMainWindowSync(); + context = this.getUIContext(); + + onPageShow() { + // 获取最上层窗口的方式 + window.getLastWindow(this.context.getHostContext()); + this.mainWin.setPreferredOrientation(window.Orientation.LANDSCAPE); + // 使用display接口获取当前旋转方向,可以放置在监听中持续获取 + display.getDefaultDisplaySync().rotation; + } + + build() { + Row() { + Column({ space: 10 }) { + Text('屏幕旋转demo') + .fontSize(25) + .margin(20) + .fontColor(0x3399FF) + }.width('100%') + }.height('100%').backgroundColor(Color.White) + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ScreenorizontalVerticalStatus.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ScreenorizontalVerticalStatus.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ee8ee066a553d53a68ac1fbfb3b24ef20b1f081 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ScreenorizontalVerticalStatus.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何监听当前屏幕的横竖屏状态?如何实现页面跟随屏幕横竖屏自动旋转 +*/ + +// DocsCode 1 +import { window, display } from '@kit.ArkUI'; + +const TAG = 'foo' +const ORIENTATION: Array = ['垂直', '水平', '反向垂直', '反向水平'] + +@Entry +@Component +struct ScreenTest { + context = this.getUIContext(); + @State rotation: number = 0 + @State message: string = ORIENTATION[this.rotation] + + aboutToAppear() { + this.setOrientation() + + let callback = async () => { + // ... + } + try { + display.on("change", callback); // 监听屏幕状态改变 + } catch (exception) { + console.error(TAG, 'Failed to register callback. Code: ' + JSON.stringify(exception)); + } + } + + setOrientation() { + try { + window.getLastWindow(this.context.getHostContext(), (err, data) => { // 获取window实例 + if (err.code) { + console.error(TAG, 'Failed to obtain the top window. Cause: ' + JSON.stringify(err)); + return; + } + let windowClass = data; + console.info(TAG, 'Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)); + + let orientation = window.Orientation.AUTO_ROTATION; // 设置窗口方向为传感器自动旋转模式。 + try { + windowClass.setPreferredOrientation(orientation, (err) => { + if (err.code) { + console.error(TAG, 'Failed to set window orientation. Cause: ' + JSON.stringify(err)); + return; + } + console.info(TAG, 'Succeeded in setting window orientation.'); + }); + } catch (exception) { + console.error(TAG, 'Failed to set window orientation. Cause: ' + JSON.stringify(exception)); + } + ; + }); + } catch (exception) { + console.error(TAG, 'Failed to obtain the top window. Cause: ' + JSON.stringify(exception)); + } + ; + } + + build() { + Row() { + Column() { + Text(`${this.rotation}`).fontSize(25) + Text(`${this.message}`).fontSize(25) + } + .width("100%") + } + .height("100%") + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SetAppAutomaticallyRestart.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetAppAutomaticallyRestart.ets new file mode 100644 index 0000000000000000000000000000000000000000..95cc564eb98273f41337387eb6d00cec8ed7e160 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetAppAutomaticallyRestart.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置应用自动重启 +*/ + +// DocsCode 1 +import { Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { common } from '@kit.AbilityKit'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + private context = this.getUIContext().getHostContext() as common.UIAbilityContext; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + + Button('RESTART').onClick(() => { + let applicationContext = this.context.getApplicationContext(); + let want: Want = { + bundleName: 'com.example.myapp', + abilityName: 'EntryAbility' + }; + try { + applicationContext.restartApp(want); + hilog.info(0x0000, 'testTag', '%{public}s', 'applicationContext.restartApp'); + } catch (error) { + console.error(`restartApp fail, error: ${JSON.stringify(error)}`); + } + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SetClickEventInCustomspan.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetClickEventInCustomspan.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc1d3f2e9b8b5eae5af9b08aa7238a4d960b60f6 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetClickEventInCustomspan.ets @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置customspan不同位置的点击事件 + */ + +// DocsCode 1 +@Entry +@Component +struct Index { + controller: RichEditorController = new RichEditorController(); + option: RichEditorOptions = { controller: this.controller }; + + @Builder + comment() { + Row() { + Text() { + Span('123123123') + ImageSpan($r('app.media.startIcon')).width(20).height(20) + Span('ggggggggggggggggggggggxxxxxxxxxxxxxxxxxxxxxxx') + } + .maxLines(1) + .wordBreak(WordBreak.BREAK_ALL) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .constraintSize({ + maxWidth: '90%' + }) + + Image($r('app.media.startIcon')) + .width(25) + .height(25) + .onClick(() => { + this.getUIContext().getPromptAction().showToast({ + message: '点我删除' + }) + }) + } + .width('100%') + .align(Alignment.Center) + .padding({ + top: 5, + bottom: 5 + }) + .borderRadius(20) + .backgroundColor(Color.Gray) + } + + build() { + Column() { + Column() { + RichEditor(this.option) + .onReady(() => { + this.controller.addBuilderSpan(() => this.comment()) + }) + .borderWidth(1) + .borderColor(Color.Green) + .width('100%') + .height('30%') + } + .borderWidth(1) + .borderColor(Color.Red) + .width('100%') + .height('70%') + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SetOffsetInBindPopup.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetOffsetInBindPopup.ets new file mode 100644 index 0000000000000000000000000000000000000000..7e56dfec32e50712ba7d6c5ad2a4c0f14deb8300 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetOffsetInBindPopup.ets @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:bindPopup适配Web组件长按菜单功能,如何设置offset控制弹窗的偏移 + */ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct BindPopupOffset { + controller: webview.WebviewController = new webview.WebviewController(); + private result: WebContextMenuResult | undefined = undefined; + @State linkUrl: string = ''; + @State offsetX: number = 0; + @State offsetY: number = 0; + @State showMenu: boolean = false; + + @Builder + MenuBuilder() { + Menu() { + MenuItem({ + content: '复制图片', + }) + .width(100) + .height(50) + .onClick(() => { + this.result?.copyImage(); + this.showMenu = false; + }) + MenuItem({ + content: '剪切' + }) + .width(100) + .height(50) + .onClick(() => { + this.result?.cut(); + this.showMenu = false; + }) + } + .width(150) + .backgroundColor('#eeeeee') + } + + build() { + Column() { + Row() + .width(0) + .height(0) + .position({ x: 0, y: 0 }) + .bindPopup(this.showMenu, + { + builder: this.MenuBuilder(), + enableArrow: false, + placement: Placement.LeftTop, + targetSpace: 0, + shadow: { + radius: 0 + }, + offset: { + x: this.offsetX - 7, + y: this.offsetY + }, + mask: false, + onStateChange: (e) => { + if (!e.isVisible) { + this.showMenu = false; + this.result!.closeContextMenu(); + } + } + }) + + Web({ src: $rawfile('index.html'), controller: this.controller })//触发自定义弹窗 + .onContextMenuShow((event) => { + if (event) { + this.result = event.result; + this.showMenu = true; + this.offsetX = Math.max(this.getUIContext().px2vp(event?.param.x() ?? 0) - 0, 0); + this.offsetY = Math.max(this.getUIContext().px2vp(event?.param.y() ?? 0) - 0, 0); + } + return true; + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SetWindowPrivacyModeInPage.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetWindowPrivacyModeInPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..6481ea0e7c9d1e568990dfd1db01e5aa63a72748 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SetWindowPrivacyModeInPage.ets @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现防截屏功能 +*/ + +// DocsCode 1 +"requestPermissions": [ +{"name": "ohos.permission.PRIVACY_WINDOW"} +] + +// DocsCode 2 +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + // 获取主窗口 + windowStage.getMainWindow((err: BusinessError, data) => { + let errCode: number = err.code; + if (errCode) { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err)); + return; + } + let windowClass: window.Window = data; + console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data)); + // 设置窗口隐私模式 + let isPrivacyMode: boolean = true; + try { + windowClass.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window to privacy mode.'); + }); + } catch (exception) { + console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(exception)); + } + }) + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} + +// DocsCode 3 +"requestPermissions": [ +{"name": "ohos.permission.PRIVACY_WINDOW"} +] +// DocsCode 4 +import { BusinessError } from '@kit.BasicServicesKit'; +import { common } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; + +class windowUtils { + static setWindowPrivacyModeInPage(context: common.UIAbilityContext, isFlag: boolean) { + window.getLastWindow(context).then((lastWindow) => { + lastWindow.setWindowPrivacyMode(isFlag, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error('Failed to set the window to privacy mode. 1Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window to privacy mode.'); + }); + }) + } +} + +@Entry +@Component +struct Index { + @State message: string = 'hello world'; + @Provide('NavPathStack') pageStack: NavPathStack = new NavPathStack(); + context = this.getUIContext(); + + @Builder + PagesMap(name: string) { + if (name === 'Index') { + Index(); + } else if (name === 'PageOne') { + PageOne(); + } + } + + build() { + Navigation(this.pageStack) { + Column() { + Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) + .width('80%') + .height(40) + .margin(20) + .onClick(() => { + this.pageStack.pushPath({ name: 'PageOne' }) //将name指定的NavDestination页面信息入栈 + }) + } + } + .navDestination(this.PagesMap) + .onNavBarStateChange((isVisible: boolean) => { + // 导航栏显示状态切换时触发该回调 + console.info('------>isVisible:' + isVisible) + windowUtils.setWindowPrivacyModeInPage(this.context.getHostContext() as common.UIAbilityContext, isVisible); + }) + } +} + +@Component +struct PageOne { + @Consume('NavPathStack') pageStack: NavPathStack; + + build() { + NavDestination() { + Column() { + Text('PageOne') + } + } + .title('pageOne') + .onBackPressed(() => { + const popDestinationInfo = this.pageStack.pop(); // 弹出路由栈栈顶元素 + return true; + }) + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SettingScreenBrightness.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SettingScreenBrightness.ets new file mode 100644 index 0000000000000000000000000000000000000000..64c7736ba4d0025df6412a76a6d180efc19ba540 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SettingScreenBrightness.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置屏幕亮度 +*/ + +// DocsCode 1 +import { window } from '@kit.ArkUI' + +@Component +struct SettingScreenBrightness { + context = this.getUIContext(); + + windowStage: window.WindowStage = AppStorage.get('windowStage') as window.WindowStage; + // 获取主窗口的方式 + mainWin: window.Window = this.windowStage.getMainWindowSync(); + + aboutToAppear(): void { + // 修改brightness即可改变屏幕亮度 + let brightness = 1; + this.windowStage = AppStorage.get('windowStage') as window.WindowStage; + // 获取主窗口的方式 + this.mainWin = this.windowStage.getMainWindowSync(); + // 获取最上层窗口的方式 + window.getLastWindow(this.context.getHostContext()); + try { + this.mainWin.setWindowBrightness(brightness, (err) => { + if (err.code) { + console.error('Failed to set the brightness. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the brightness.'); + }); + } catch (exception) { + console.error('Failed to set the brightness. Cause: ' + JSON.stringify(exception)); + } + } + + build() { + Row() { + Column({ space: 10 }) { + Text('屏幕亮度设置demo') + .fontSize(25) + .margin(20) + .fontColor(0x3399FF) + }.width('100%') + }.height('100%').backgroundColor(Color.White) + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SharePopup.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SharePopup.ets new file mode 100644 index 0000000000000000000000000000000000000000..48f3bfc5a60ab387690d1568dcca850596926986 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SharePopup.ets @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用自定义弹窗实现分享弹窗 + */ + +// DocsCode 1 +import { ComponentContent } from '@kit.ArkUI'; + +let componentContent: ComponentContent | undefined = undefined; + +class Params { + applicationSharings: string[] = []; + sharings: string[] = []; + + constructor(applicationSharings: string[], sharings: string[] = []) { + this.applicationSharings = applicationSharings; + this.sharings = sharings; + } +} + +@Builder +function buildText($$: Params) { + Column() { + Text('share') + Grid() { + ForEach($$.applicationSharings, (item: string, index) => { + GridItem() { + Column() { + Image($r('app.media.app_icon')) + .height(50) + .width(50) + Text(item) + .fontSize(10) + } + } + }) + } + .height(100) + .rowsGap(20) + .columnsGap(20) + .scrollBar(BarState.Off) + .rowsTemplate('1fr') + + Grid() { + ForEach($$.sharings, (item: string, index) => { + GridItem() { + Column() { + Image($r('app.media.app_icon')) + .height(50) + .width(50) + Text(item) + .fontSize(10) + } + } + }) + } + .height(100) + .rowsGap(20) + .columnsGap(20) + .scrollBar(BarState.Off) + .rowsTemplate('1fr') + + Button('取消') + .width('100%') + .fontColor(Color.Black) + .backgroundColor(Color.White) + .onClick(() => { + this.getUIContext().getPromptAction()?.closeCustomDialog(componentContent); + }) + } + .backgroundColor('#FFF0F0F0') + .width('90%') + .height('30%') + .borderRadius(10) +} + +@Entry +@Component +struct CustomShareDialog { + @State applicationSharings: string[] = + ['share1', 'share2', 'share3', 'share4', 'share5', 'share6', 'share7', 'share8']; + @State sharings: string[] = ['share1', 'share2', 'share3', 'share4', 'share5', 'share6', 'share7', 'share8']; + + build() { + Row() { + Column() { + Button('click me') + .onClick(() => { + let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), + new Params(this.applicationSharings, this.sharings)); + componentContent = contentNode; + this.getUIContext().getPromptAction().openCustomDialog(contentNode); + }) + } + .width('100%') + .height('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SideSlipEventInterception.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SideSlipEventInterception.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c985f8b15f4c5de3089ea5d9f06b738a87a67d3 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SideSlipEventInterception.ets @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Navigation页面中实现侧滑事件拦截 + */ + +// DocsCode 1 +import { ShowDialogSuccessResponse } from '@kit.ArkUI'; + +@Entry +@Component +struct SideslipIntercept { + controller: TextAreaController = new TextAreaController(); + @State text: string = ''; + @Provide pageStackForComponentSharedPages: NavPathStack = new NavPathStack(); + + build() { + // 应用主页用NavDestination承载,用于显示Navigation的内容区 + Navigation(this.pageStackForComponentSharedPages) { + } + .onAppear(() => { + this.pageStackForComponentSharedPages.pushPathByName('MainPage', null, false); + }) + // 创建NavDestination组件,需使用此组件的onBackPressed回调拦截返回事件 + .navDestination(this.textArea) + } + + @Builder + textArea(name: string) { + NavDestination() { + Column() { + TextArea({ + text: this.text, + placeholder: 'input your word...', + controller: this.controller + }) + .onChange((value: string) => { + this.text = value; + }) + } + .justifyContent(FlexAlign.Start) + .width('100%') + .height('100%') + } + .onBackPressed(() => { + // 此处可添加拦截处理逻辑,然后return true放行 + this.getUIContext().getPromptAction().showDialog({ + message: '是否保存', + alignment: DialogAlignment.Center, + buttons: [ + { + text: '不保存', + color: '#0000FF' + }, + { + text: '保存', + color: '#0000FF' + } + ] + }).then((data: ShowDialogSuccessResponse) => { + // 操作菜单的响应结果,选中按钮在buttons数组中的索引,从0开始,第二个索引为1 + // 点击不保存按钮 + if (data.index === 0) { + console.info('不保存') + } + // 点击保存按钮 + if (data.index === 1) { + console.info('保存') + } + }) + return true ; + }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SimilarKeyFramesEffect.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SimilarKeyFramesEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..936c2adc4b8b647f2e31ca600df5367e0ca2961a --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SimilarKeyFramesEffect.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现类似keyframes的效果 +*/ + +// DocsCode 1 +@Entry +@Component +struct AnimateToExample { + @State widthSize: number = 250; + @State heightSize: number = 100; + @State rotateAngle: number = 0; + private flag: boolean = true; + @State opacityValue: number = 1; + + build() { + Column() { + Button('change size') + .width(this.widthSize) + .height(this.heightSize) + .margin(30) + .opacity(this.opacityValue) + .onClick(() => { + if (this.flag) { + this.getUIContext().animateTo({ + duration: 2000, + curve: Curve.EaseOut, + iterations: 1, + playMode: PlayMode.Normal, + onFinish: () => { + this.getUIContext().animateTo({ + duration: 2000, + curve: Curve.EaseOut, + iterations: 1, + playMode: PlayMode.Normal, + onFinish: () => { + } + }, () => { + this.opacityValue = 0.2; + }) + } + }, () => { + this.opacityValue = 0.5; + }) + } + }) + }.width('100%').margin({ top: 5 }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SourceAppLaunch.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SourceAppLaunch.ets new file mode 100644 index 0000000000000000000000000000000000000000..186edfde5be63592f7a7ac9d081bc7c1c0613218 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SourceAppLaunch.ets @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何判断App的启动来源 +*/ + +// DocsCode 1 +import { common, Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +@Entry +@Component +struct Index { + context = this.getUIContext(); + + build() { + Row() { + Column() { + Button('open app') + .onClick(() => { + let want: Want = { + action: 'ohos.want.action.viewData', + entities: ['entity.system.home'] + } + let context = this.context.getHostContext() as common.UIAbilityContext; + context.startAbility(want, (err: BusinessError) => { + if (err.code) { + // 处理业务逻辑错误 + hilog.error(0x0000, 'testTag', `startAbility failed, code is ${err.code}, message is ${err.message}`); + return; + } + // 执行正常业务 + hilog.info(0x0000, 'testTag', 'startAbility succeed'); + }); + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 2 +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', `app resource is:${want.parameters?.['ohos.aafwk.param.callerBundleName']}`); + // ... + } + + // ... +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/StatusbarAndPageOverlap.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/StatusbarAndPageOverlap.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d403506291bb9075f2d795f06e712f01cfecc0f --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/StatusbarAndPageOverlap.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:状态栏与页面内容发生重叠,如何解决 + */ + +// DocsCode 3 +// EntryAbility.ets + +onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/AvoidStatusBar', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + + let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口 + // 1. 设置窗口全屏 + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + // 2. 缓存window窗口对象 + AppStorage.setOrCreate('windowClass', windowClass); + + // 3. 获取布局避让遮挡的区域 + let type = window.AvoidAreaType.TYPE_SYSTEM; + let avoidArea = windowClass.getWindowAvoidArea(type); + let statusBar = this.getUIContext().px2vp( avoidArea.topRect.height); // 获取状态栏的高度 + AppStorage.setOrCreate('statusBar', statusBar); + }); +} +// DocsCode 3 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/SwipeActionToNotSlide.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/SwipeActionToNotSlide.ets new file mode 100644 index 0000000000000000000000000000000000000000..45c79d13ec8a0c76b8d1ed47f0dca575626f8b8d --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/SwipeActionToNotSlide.ets @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将ListItem的swipeAction滑动效果恢复至未滑动 +*/ + +// DocsCode 1 +@Component +export struct SwiperActionRecover { + @State arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + private scrollerForList: ListScroller = new ListScroller(); + + @Builder + itemEnd() { + Row() { + Button('Delete') + Button('Set') + .onClick(() => { + this.scrollerForList.closeAllSwipeActions(); // 重点是这行代码 + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + } + + build() { + Column() { + List({ space: 5, scroller: this.scrollerForList }) { + ForEach(this.arr, (item: number) => { + ListItem() { + Text('item' + item) + .width('100%') + .height(100) + .textAlign(TextAlign.Center) + .borderRadius(10) + .backgroundColor(0xFFFFFF) + } + .transition({ + type: TransitionType.Delete, + opacity: 0 + }) + .swipeAction({ + end: { + builder: () => { + this.itemEnd(); + }, + onAction: () => { + this.getUIContext().animateTo({ duration: 1000 }, () => { + let index = this.arr.indexOf(item); + this.arr.splice(index, 1); + }); + }, + actionAreaDistance: 56 + } + }) + }, (item: string) => item) + } + } + .padding(20) + .backgroundColor(0xDCDCDC) + .width('100%') + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/TabBarAddComponent.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/TabBarAddComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4e15c0cb008e1c684910ef4b79f789e3e51a573 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/TabBarAddComponent.ets @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Tabs的tabBar中添加其他组件 +*/ + +// DocsCode 1 +import { componentUtils } from '@kit.ArkUI'; + +@Entry +@Component +struct TabsDemo { + @State tabArray: Array = [0, 1, 2]; + @State tabArrayVal: number = this.tabArray.length - 1; + @State currentIndex: number = 0; + @State animationDuration: number = 300; + @State indicatorLeftMargin: number = 0; + @State indicatorWidth: number = 0; + private controller: TabsController = new TabsController(); + private tabsWidth: number = 0; + + // 单独的页签 + @Builder + tab(tabName: string, tabItem: number, tabIndex: number) { + Row({ space: 20 }) { + Text(tabName).fontSize(18) + .fontColor(tabItem === this.currentIndex ? Color.Red : Color.Black) + .id(tabIndex.toString()) + .onAreaChange((oldValue: Area, newValue: Area) => { + if (this.currentIndex === tabIndex && (this.indicatorLeftMargin === 0 || this.indicatorWidth === 0)) { + if (newValue.position.x !== undefined) { + let positionX = Number.parseFloat(newValue.position.x.toString()); + this.indicatorLeftMargin = Number.isNaN(positionX) ? 0 : positionX; + } + let width = Number.parseFloat(newValue.width.toString()); + this.indicatorWidth = Number.isNaN(width) ? 0 : width; + } + }) + } + .justifyContent(FlexAlign.Center) + .constraintSize({ minWidth: 35 }) + .width(80) + .height(35) + .borderRadius({ + topLeft: 10, + topRight: 10 + }) + .onClick(() => { + this.controller.changeIndex(tabIndex); + this.currentIndex = tabIndex; + }) + } + + build() { + Column() { + // 页签 + Stack({ alignContent: Alignment.TopStart }) { + Scroll() { + Row() { + ForEach(this.tabArray, (item: number, index: number) => { + this.tab('页签' + item, item, index); + }) + Text('+') + .width(36) + .height(50) + .fontSize(28) + .borderRadius(5) + .padding({ + left: 5, + bottom: 2 + }) + .onClick(() => { + this.tabArray.push(++this.tabArrayVal); + }) + } + .justifyContent(FlexAlign.SpaceBetween) + } + .align(Alignment.Start) + .scrollable(ScrollDirection.Horizontal) + .scrollBar(BarState.Off) + .width('100%') + + Column() + .width(this.indicatorWidth) + .height(2) + .backgroundColor(Color.Red) + .borderRadius(2) + .margin({ + left: this.indicatorLeftMargin, + top: 38 + }) + } + .width('100%') + + Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { + ForEach(this.tabArray, (item: number, index: number) => { + TabContent() { + Text('我是页面' + item + '的内容') + .height(300) + .width('100%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + .backgroundColor(Color.Pink) + }) + } + .onAreaChange((oldValue: Area, newValue: Area) => { + let width = Number.parseFloat(newValue.width.toString()); + this.tabsWidth = Number.isNaN(width) ? 0 : width; + }) + .barWidth('100%') + .barHeight(0) + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + .animationDuration(this.animationDuration) + .onChange((index: number) => { + this.currentIndex = index; // 监听索引index的变化,实现页签内容的切换。 + }) + .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => { + // 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。 + this.currentIndex = targetIndex; + let targetIndexInfo = this.getTextInfo(targetIndex); + this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width); + }) + .onAnimationEnd((index: number, event: TabsAnimationEvent) => { + // 切换动画结束时触发该回调。下划线动画停止。 + let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event); + this.startAnimateTo(0, currentIndicatorInfo.left, currentIndicatorInfo.width); + }) + .onGestureSwipe((index: number, event: TabsAnimationEvent) => { + // 在页面跟手滑动过程中,逐帧触发该回调。 + let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event); + this.currentIndex = currentIndicatorInfo.index; + this.indicatorLeftMargin = currentIndicatorInfo.left; + this.indicatorWidth = currentIndicatorInfo.width; + }) + } + .height('100%') + } + + // 获取组件大小、位置、平移缩放旋转及仿射矩阵属性信息。 + private getTextInfo(index: number): Record { + let modePosition: componentUtils.ComponentInfo = this.getUIContext().getComponentUtils().getRectangleById(index.toString()); + return { 'left': px2vp(modePosition.windowOffset.x), 'width': px2vp(modePosition.size.width) }; + } + + private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record { + let nextIndex = index; + if (index > 0 && event.currentOffset > 0) { + nextIndex--; + } else if (index < 3 && event.currentOffset < 0) { + nextIndex++; + } + let indexInfo = this.getTextInfo(index); + let nextIndexInfo = this.getTextInfo(nextIndex); + let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth); + // 页面滑动超过一半,tabBar切换到下一页。 + let currentIndex = swipeRatio > 0.5 ? nextIndex : index; + let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * swipeRatio; + let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * swipeRatio; + return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth }; + } + + private startAnimateTo(duration: number, leftMargin: number, width: number) { + animateTo({ + // 动画时长 + duration: duration, + // 动画曲线 + curve: Curve.Linear, + // 播放次数 + iterations: 1, + // 动画模式 + playMode: PlayMode.Normal, + onFinish: () => { + console.info('play end'); + } + }, () => { + this.indicatorLeftMargin = leftMargin; + this.indicatorWidth = width; + }) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/TextExpansionAndCollapseFunctions.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/TextExpansionAndCollapseFunctions.ets new file mode 100644 index 0000000000000000000000000000000000000000..da14102d8b8a0d4c5cd74b4a7f9380c0e36ffd68 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/TextExpansionAndCollapseFunctions.ets @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现文本展开收起功能 +*/ + +// DocsCode 1 +// 文本行宽度 +const TEXT_WIDTH: number = 350; +// 收起文本显示行数 +const COLLAPSE_LINES: number = 2; +const ELLIPSIS: string = '...'; +const EXPAND_STR: string = '展开'; +const COLLAPSE_STR: string = '收起'; +const FULL_TEXT: string = + 'HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架可为开发者提供应用UI开发' + + '所必需的能力,比如多种组件、布局计算、动画能力、UI交互、绘制等。\n' + + '方舟开发框架针对不同目的和技术背景的开发者提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式开发范式”)' + + '和兼容JS的类Web开发范式(简称“类Web开发范式”)。以下是两种开发范式的简单对比。' + +@Entry +@Component +struct TextCollapseTest { + @State title: string = FULL_TEXT; + @State suffixStr: string = ''; + private expanded: Boolean = true; + private needProcess: boolean = true + aboutToAppear(): void { + this.process(); + } + + process(): void { + if (this.expanded) { + this.collapseText(); + } else { + this.expandText(); + } + } + + //展开文本 + expandText(): void { + if (this.needProcess) { + this.suffixStr = COLLAPSE_STR; + this.expanded = true; + this.title = FULL_TEXT; + } + } + + //收起文本 + collapseText(): void { + if (!this.needProcess) { + return; + } + // 展开文本的size + let expandSize: SizeOptions = this.getUIContext().getMeasureUtils().measureTextSize({ + textContent: FULL_TEXT, + constraintWidth: TEXT_WIDTH, + fontSize: 30 + }); + + // 将要收起的文本size + let collapseSize: SizeOptions = this.getUIContext().getMeasureUtils().measureTextSize({ + textContent: FULL_TEXT, + constraintWidth: TEXT_WIDTH, + fontSize: 30, + maxLines: COLLAPSE_LINES + }); + + //收起的文本高度和展开时的文本高度相等时,不进行处理 + if ((expandSize.height as number) == (collapseSize.height as number)) { + this.needProcess = false; + return; + } + + let clipTitle: string = FULL_TEXT + this.suffixStr = EXPAND_STR; + // 使用二分法查找正好两行的长度的字符串 + let leftCursor: number = 0; + let rightCursor: number = this.title.length; + let cursor: number = Math.floor(rightCursor / 2); + let tempTitle: string = ''; + while (true) { + tempTitle = this.title.substring(0, cursor) + ELLIPSIS + EXPAND_STR; + const currentLinesTextSize: SizeOptions = this.getUIContext().getMeasureUtils().measureTextSize({ + textContent: tempTitle, + fontSize: 30, + wordBreak: WordBreak.BREAK_ALL, + constraintWidth: TEXT_WIDTH + }); + + if ((currentLinesTextSize.height as number) > (collapseSize.height as number)) { + // 当前字符已超过两行,向左继续找 + rightCursor = cursor; + cursor = leftCursor + Math.floor((cursor - leftCursor) / 2); + } else { + // 当前字符小于两行了,可能已经ok,但仍需向右查找 + leftCursor = cursor; + cursor += Math.floor((rightCursor - cursor) / 2); + } + if (Math.abs(rightCursor - leftCursor) <= 1) { + // 两次指针基本重合了,代表已找到 + break; + } + } + clipTitle = this.title.substring(0, cursor - 1); + this.title = clipTitle + ELLIPSIS; + this.expanded = false; + } + + build() { + Row() { + Column() { + Text() { + Span(this.title) + if (this.needProcess) { + Span(this.suffixStr) + .fontColor(Color.Orange) + .onClick(() => { + this.process(); + }) + } + } + .fontSize(30) + .fontWeight(FontWeight.Bold) + .width(TEXT_WIDTH) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/TextSetMaxlinesIsHideText.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/TextSetMaxlinesIsHideText.ets new file mode 100644 index 0000000000000000000000000000000000000000..61b91326f41008ddb63f4170caeda74b63c3ac0a --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/TextSetMaxlinesIsHideText.ets @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Text组件设置maxLines后如何确定文本是否被隐藏 +*/ + +// DocsCode 1 +@Entry +@Component +struct TextInputExample { + @State text: string = ''; + @State truncatedHint: string = "文本未截断"; + controller: TextInputController = new TextInputController(); + + build() { + Column() { + TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller }) + .placeholderColor(Color.Grey) + .placeholderFont({ size: 14, weight: 400 }) + .caretColor(Color.Blue) + .width(400) + .height(40) + .margin(20) + .fontSize(14) + .fontColor(Color.Black) + .onChange((value: string) => { + this.text = value; + let textSizeShow1: SizeOptions = this.getUIContext().getMeasureUtils().measureTextSize({ + textContent: this.text, + constraintWidth: 100, + fontSize: 14, + overflow: TextOverflow.Ellipsis, + maxLines: 2 + }) + let textSizeShow2: SizeOptions = this.getUIContext().getMeasureUtils().measureTextSize({ + textContent: this.text + " ", + constraintWidth: 100, + fontSize: 14, + overflow: TextOverflow.Ellipsis, + maxLines: 2000000 + }) + console.log("textSizeShow1.height=" + textSizeShow1.height); + console.log("textSizeShow2.height=" + textSizeShow2.height); + + if (textSizeShow2 && textSizeShow1 && textSizeShow2?.height && textSizeShow1?.height && (textSizeShow2?.height > textSizeShow1?.height)) { + console.log("文本截断"); + this.truncatedHint = "文本截断"; + } else { + console.log("文本未截断"); + this.truncatedHint = "文本未截断"; + } + }) + Text(this.text) + .maxLines(2) + .width(100) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .border({ width: 1 }) + .minFontSize(14) + .maxFontSize(24) + Text(this.truncatedHint) + + }.width('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/TheHeaderTruncated.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/TheHeaderTruncated.ets new file mode 100644 index 0000000000000000000000000000000000000000..f599c30842cad8c80654e2c74077711ae2cecb8b --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/TheHeaderTruncated.ets @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决Web页面输入框拉起键盘后,页面头部被截断的问题 + */ + +// DocsCode 1 +// 子窗口页面布局 +import { webview } from '@kit.ArkWeb'; +import { window } from '@kit.ArkUI'; + +@Entry +@Component +export struct SubWindowPage { + @State webViewVisibility: Visibility = Visibility.Visible; + private pageWidth = 320; + private pageHeight = 500; + private controller: webview.WebviewController = new webview.WebviewController(); + @State flexAlign: FlexAlign = FlexAlign.Center; + @State screenHeight: number | string = '100%'; + + aboutToAppear() { + window.getLastWindow(getContext(this)).then(currentWindow => { + // 监视软键盘的弹出和收起 + currentWindow.on('avoidAreaChange', async data => { + let property = currentWindow.getWindowProperties(); + let avoidArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + this.screenHeight = this.getUIContext().px2vp(property.windowRect.height - avoidArea.bottomRect.height); + }); + }) + } + + build() { + Stack() { + Column() { + Web({ src: $rawfile('index.html'), controller: this.controller }) + .javaScriptAccess(true) + .fileAccess(false) + .zoomAccess(false) + .domStorageAccess(true) + .onlineImageAccess(true) + .horizontalScrollBarAccess(false) + .verticalScrollBarAccess(false) + .cacheMode(CacheMode.Online) + .width(this.pageWidth) + .height(this.pageHeight) + .border({ radius: 6 }) + .visibility(this.webViewVisibility) + .backgroundColor(Color.Pink) + } + .justifyContent(this.flexAlign) + .alignItems(HorizontalAlign.Center) + .width('100%') + .height('100%') + } + .width('100%') + .height(this.screenHeight) + .backgroundColor('#999955') + .alignContent(Alignment.Center) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/ToggleWithDelay.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/ToggleWithDelay.ets new file mode 100644 index 0000000000000000000000000000000000000000..d64e193ac06a92414b0adb44cf7da08decca21b3 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/ToggleWithDelay.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:目前Toggle组件响应点击之后会立刻渲染且立刻回调,如何延迟改变Toggle状态且延时回调? +*/ + +// DocsCode 1 +@Entry +@Component +struct ToggleDemo { + @State isDarkMode: boolean = false; + + build() { + Column() { + Column() { + Toggle({ type: ToggleType.Switch, isOn: $$this.isDarkMode }) + .onChange((isOn: boolean) => { + console.info('Toggle.onChange:isOn' + isOn); + this.isDarkMode = isOn; + this.getUIContext().getHostContext()!.getApplicationContext().setColorMode(this.isDarkMode ? 0 : 1); + }) + } + // 设置hitTestBehavior属性为HitTestMode.Block,阻塞Toggle组件响应事件。 + .hitTestBehavior(HitTestMode.Block) + .onClick(() => { + setTimeout(() => { + this.isDarkMode = !this.isDarkMode; + }, 1500); + }) + } + .width('100%') + .height('100%') + .padding(32) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/WindowProperties.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/WindowProperties.ets new file mode 100644 index 0000000000000000000000000000000000000000..4cc6f5491ec8e8aa11b7a923cbc39189111a63d1 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/WindowProperties.ets @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取窗口的宽度 +*/ + +// DocsCode 1 +import { window } from '@kit.ArkUI'; + +@Entry +@Component +struct WindowProperties { + context = this.getUIContext(); + + build() { + Text("Scroll Area") + .width("100%") + .height("100%") + .backgroundColor(0X330000FF) + .fontSize(16) + .textAlign(TextAlign.Center) + .onClick(() => { + window.getLastWindow(this.context.getHostContext()).then((data) => { + // 获取窗口属性 + let properties = data?.getWindowProperties(); + // // 获取窗口宽高 + console.log("windowClass width: " + properties.windowRect.width); + console.log("windowClass height: " + properties.windowRect.height); + }); + }) + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/ets/pages/WindowRotation.ets b/FAQ/ArkUIKit/entry/src/main/ets/pages/WindowRotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..04a63a462b4d28c1c07ca0e17093f8b4df1760d0 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/ets/pages/WindowRotation.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取设备屏幕横竖屏状态 +*/ + +// DocsCode 1 +import { mediaquery } from '@kit.ArkUI'; + +let listener = mediaquery.matchMediaSync('(orientation: landscape)'); //监听横屏事件 +function onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) { + console.info('mediaQueryResult.matches:' + mediaQueryResult.matches) + if (mediaQueryResult.matches) { + // do something here + } else { + // do something here + } +} +listener.on('change', onPortrait) // 注册回调 +listener.off('change', onPortrait) // 取消注册回调 + +@Entry +@Component +struct Index { + build() { + Column() { + Column() { + Text('test') + } + .width('100%') + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.End) + } +} + +// DocsCode 2 +import { display, window } from '@kit.ArkUI'; + +@Entry +@Component +struct windowRotation { + context = this.getUIContext(); + + build() { + Text("Scroll Area") + .width("100%") + .height("100%") + .backgroundColor(0X330000FF) + .fontSize(16) + .textAlign(TextAlign.Center) + .onClick(() => { + window.getLastWindow(this.context.getHostContext(), (err, win) => { + let cutOutInfo = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE) + console.log(JSON.stringify(cutOutInfo)) + if (window.Orientation.AUTO_ROTATION) { + let rotation: number = display.getDefaultDisplaySync().orientation // 获取当前屏幕的枚举值 + console.log('CutOutInfo rotation' + JSON.stringify(rotation)); + if (rotation == 0) { + console.log("CutOutInfo 竖屏数据: " + JSON.stringify(cutOutInfo)); + } else if (rotation == 1) { + console.log("CutOutInfo 横屏数据: " + JSON.stringify(cutOutInfo)); + } else if (rotation == 2) { + console.log("CutOutInfo 反向竖屏数据: " + JSON.stringify(cutOutInfo)); + } else { + console.log("CutOutInfo 反向横屏数据: " + JSON.stringify(cutOutInfo)); + } + } + }) + }) + }} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/module.json5 b/FAQ/ArkUIKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/element/color.json b/FAQ/ArkUIKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/element/float.json b/FAQ/ArkUIKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/element/string.json b/FAQ/ArkUIKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/media/background.png b/FAQ/ArkUIKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ArkUIKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/media/foreground.png b/FAQ/ArkUIKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ArkUIKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/ArkUIKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/ArkUIKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/ArkUIKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/ArkUIKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/ArkUIKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..d92299cfbe3a2dd279ae1322ca5c4d871743455e --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,14 @@ +{ + "src": [ + "pages/Index", + "pages/TabBarAddComponent", + "pages/CustomDialogVariableToPage", + "pages/GetHorizontalAndVerticalScreenStatus", + "pages/AdaptWebForFullScreenOfPlayer", + "pages/ListenForScreenRotation", + "pages/TextExpansionAndCollapseFunctions", + "pages/GetTextWidth", + "pages/TextSetMaxlinesIsHideText", + "pages/HandleDraw9PatchReplacementRegimen" + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/main/resources/dark/element/color.json b/FAQ/ArkUIKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/mock/mock-config.json5 b/FAQ/ArkUIKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/ArkUIKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/ArkUIKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/ohosTest/module.json5 b/FAQ/ArkUIKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/ArkUIKit/entry/src/test/List.test.ets b/FAQ/ArkUIKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/entry/src/test/LocalUnit.test.ets b/FAQ/ArkUIKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/ArkUIKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/hvigor/hvigor-config.json5 b/FAQ/ArkUIKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/ArkUIKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/ArkUIKit/hvigorfile.ts b/FAQ/ArkUIKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/ArkUIKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ArkUIKit/oh-package-lock.json5 b/FAQ/ArkUIKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c6f99f5c73b06c5fdef7ec6f491b74b7befebe2e --- /dev/null +++ b/FAQ/ArkUIKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/ArkUIKit/oh-package.json5 b/FAQ/ArkUIKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/ArkUIKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/ArkWebKit/.gitignore b/FAQ/ArkWebKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/ArkWebKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/ArkWebKit/AppScope/app.json5 b/FAQ/ArkWebKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4cfb8aeba5d4de4a04bae5b59f8d613a7056f471 --- /dev/null +++ b/FAQ/ArkWebKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.arkwebkit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/ArkWebKit/AppScope/resources/base/element/string.json b/FAQ/ArkWebKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..015917acccfe2c3cef04256900e1be232fcc1b0d --- /dev/null +++ b/FAQ/ArkWebKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "ArkWebKit" + } + ] +} diff --git a/FAQ/ArkWebKit/AppScope/resources/base/media/background.png b/FAQ/ArkWebKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ArkWebKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/ArkWebKit/AppScope/resources/base/media/foreground.png b/FAQ/ArkWebKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ArkWebKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/ArkWebKit/AppScope/resources/base/media/layered_image.json b/FAQ/ArkWebKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ArkWebKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/build-profile.json5 b/FAQ/ArkWebKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/ArkWebKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/code-linter.json5 b/FAQ/ArkWebKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/ArkWebKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/.gitignore b/FAQ/ArkWebKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/ArkWebKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/build-profile.json5 b/FAQ/ArkWebKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/ArkWebKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/hvigorfile.ts b/FAQ/ArkWebKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/ArkWebKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ArkWebKit/entry/obfuscation-rules.txt b/FAQ/ArkWebKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/ArkWebKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/oh-package.json5 b/FAQ/ArkWebKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/ArkWebKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/ArkWebKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/ArkWebKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/ArkWebKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/ConfigSaveAsParameter.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/ConfigSaveAsParameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..09c2a154f2fc367d2ad0964b097933d853fe54f0 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/ConfigSaveAsParameter.ets @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置request.agent.Config中saveas参数 +*/ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; +import { request } from '@kit.BasicServicesKit'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +let filesDir = context.getHostContext()!.filesDir; +let config: request.agent.Config = { + action: request.agent.Action.DOWNLOAD, + url: 'https://www-file.huawei.com/minisite/media/annual_report/annual_report_2023_cn.pdf', + title: 'createTest', + description: 'Sample code for create task', + mode: request.agent.Mode.FOREGROUND, + overwrite: true, + method: "get", + saveas: filesDir + '/test.pdf', + network: request.agent.Network.WIFI, + metered: false, + roaming: true, + retry: true, + redirect: true, + index: 0, + begins: 0, + ends: -1, + gauge: false, + precise: false, + token: 'it is a secret' +}; +let createOnCallback = (progress: request.agent.Progress) => { + console.info('upload task progress.'); +}; + +@Entry +@Component +struct Index { + controller: webview.WebviewController = new webview.WebviewController(); + @State uri: string = ''; + @State isChange: boolean = false; + + build() { + Column() { + Button('刷新UI') + .width('200vp') + .onClick(() => { + this.controller.loadUrl('file://' + filesDir + '/test.pdf') + }) + .margin({ bottom: '20vp' }) + Web({ src: $rawfile('test.html'), controller: this.controller }) + .domStorageAccess(true) + .onPageBegin((event)=>{ + request.agent.create(this.getUIContext().getHostContext(), config).then((task: request.agent.Task) => { + task.on('progress', createOnCallback); + console.info(`Succeeded in creating a download task. result: ${task.config}`); + task.start(); + }).catch((err: Error) => { + console.error(`Failed to create a download task, message: ${err.message}`); + }); + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/FullscreenPlayerSupport.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/FullscreenPlayerSupport.ets new file mode 100644 index 0000000000000000000000000000000000000000..92b8ffe74bdb793b0b34baecedb6a7db746c6c2f --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/FullscreenPlayerSupport.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何适配网页内播放器全屏 +*/ + +// DocsCode 1 +import { mediaquery, window } from '@kit.ArkUI'; +import { common } from '@kit.AbilityKit'; +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebPlayerFullScreen { + @State color: string = '#DB7093'; + @State text: string = 'Portrait'; + @State portraitFunc: mediaquery.MediaQueryResult | void | null = null; + handler: FullScreenExitHandler | null = null; + // 当设备横屏时条件成立 + listener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)'); + controller: webview.WebviewController = new webview.WebviewController(); + + onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) { + // 若设备为横屏状态,更改相应的页面布局 + if (mediaQueryResult.matches as boolean) { + this.color = '#FFD700'; + this.text = 'Landscape'; + } else { + this.color = '#DB7093'; + this.text = 'Portrait'; + } + } + + aboutToAppear() { + // 绑定当前应用实例 + // 绑定回调函数 + this.listener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => { + this.onPortrait(mediaQueryResult); + }); + } + + // 改变设备横竖屏状态函数 + private changeOrientation(isLandscape: boolean) { + // 获取UIAbility实例的上下文信息 + let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; + // 调用该接口手动改变设备横竖屏状态 + window.getLastWindow(context).then((lastWindow) => { + lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT); + }); + } + + build() { + Column() { + Web({ src: 'https://developer.huawei.com/consumer/cn/design/', controller: this.controller }) + .javaScriptAccess(true) + .domStorageAccess(true) + .onFullScreenEnter((event) => { + this.handler = event.handler; + this.changeOrientation(true); + }) + .onFullScreenExit(() => { + if (this.handler) { + this.handler.exitFullScreen(); + this.changeOrientation(false); + } + }) + } + .width('100%') + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/H5PageATagUsage.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/H5PageATagUsage.ets new file mode 100644 index 0000000000000000000000000000000000000000..8434e5800797536d643cc511e07f00df1c85fed0 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/H5PageATagUsage.ets @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在Web组件的H5页面中,如何使用a标签实现打开各种页面 +*/ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; +import { router } from '@kit.ArkUI'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + build() { + Column() { + Column() { + Web({ src: $rawfile('hello.html'), controller: this.controller }) + .onLoadIntercept((event) => { + if(event){ + let url = event.data.getRequestUrl(); + console.log(url); + if(url.indexOf('native://') === 0){ + router.pushUrl({ url : url.substring(9)}) + return true; + } + } + return false; + }) + .width('100%') + .height('100%') + } + .layoutWeight(1) + } + } +} +// DocsCode 1 + +// DocsCode 2 +@Entry +@Component +struct Second { + build() { + Column() { + Text('这是本应用的第二个页面') + } + } +} +// DocsCode 2 + +// DocsCode 3 + + + + + + + Document + + + + + +// DocsCode 3 + +// DocsCode 4 + + + + + + + Document + + + + + +// DocsCode 4 + +// DocsCode 5 + + + + + + + Document + + +
+ hello world +
+
+我是本应用的第二个H5页面 +
+ + +// DocsCode 5 + +// DocsCode 6 + import { webview } from '@kit.ArkWeb' +import { common } from '@kit.AbilityKit'; +import { Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +function startSettingsInfo(context: Context,uri : string): void { + let want: Want = { + bundleName: 'com.huawei.hmos.settings', + abilityName: 'com.huawei.hmos.settings.MainAbility', + uri: uri + }; + context.startAbility(want) + .then(() => { + // ... + }) + .catch((err: BusinessError) => { + console.error(`Failed to startAbility. Code: ${err.code}, message: ${err.message}`); + }); +} +@Entry +@Component +struct WebComponent { + context: Context | undefined = this.getUIContext().getHostContext(); + controller: webview.WebviewController = new webview.WebviewController(); + build() { + Column() { + Column() { + Web({ src: $rawfile('hello.html'), controller: this.controller }) + .onLoadIntercept((event) => { + if(event){ + let url = event.data.getRequestUrl(); + console.log(url); + if(url.indexOf('hmos://') === 0){ + startSettingsInfo(this.context!,url.substring(7)) + return true; + } + } + return false; + }) + .width('100%') + .height('100%') + } + .layoutWeight(1) + } + } +} +// DocsCode 6 + +// DocsCode 7 + + + + + + + Document + + + + + + +// DocsCode 7 + +// DocsCode 8 + import { webview } from '@kit.ArkWeb' +import { common } from '@kit.AbilityKit'; +import { Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + private context = this.getUIContext().getHostContext() as common.UIAbilityContext; + build() { + Column() { + Column() { + Web({ src: $rawfile('hello.html'), controller: this.controller }) + .onLoadIntercept((event) => { + let want: Want = { + deviceId: '', // deviceId为空表示本设备 + bundleName: '***', // 想要跳转的三方应用的bundleName + moduleName: 'entry', // moduleName非必选 + abilityName: 'EntryAbility', + parameters: { + // 自定义参数传递页面信息 + router: 'index' + } + } + this.context.startAbility(want).then(() => { + console.log('success') + }).catch((err: BusinessError) => { + console.log('error:' + JSON.stringify(err)) + }); + return false; + }) + } + .layoutWeight(1) + } + + } +} +// DocsCode 8 + +// DocsCode 9 + + + + + + + Document + + + 跳转至三方应用 + + +// DocsCode 9 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/Index.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/UseAlertInWebview.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/UseAlertInWebview.ets new file mode 100644 index 0000000000000000000000000000000000000000..1f9f767cb8f8ebba43b16fb26c2b0057dc533e47 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/UseAlertInWebview.ets @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在webview中使用H5中的alert + */ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebviewAlert { + controller: webview.WebviewController = new webview.WebviewController(); + + build() { + Column() { + Web({ src: $rawfile('WebviewAlert.html'), controller: this.controller }) + .onAlert((event) => { + if (event) { + console.log('event.url:' + event.url); + console.log('event.message:' + event.message); + this.getUIContext().showAlertDialog({ + title: 'onAlert', + message: 'text', + primaryButton: { + value: 'cancel', + action: () => { + event.result.handleCancel(); + } + }, + secondaryButton: { + value: 'ok', + action: () => { + event.result.handleConfirm(); + } + }, + cancel: () => { + event.result.handleCancel(); + } + }) + } + return true; + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/UseLabelAOpenPages.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/UseLabelAOpenPages.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e10b20af999ebd2d64640aa5faa08903586b011 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/UseLabelAOpenPages.ets @@ -0,0 +1,242 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在Web组件的H5页面中,如何使用a标签实现打开各种页面 +*/ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + build() { + Column() { + Column() { + Web({ src: $rawfile('hello.html'), controller: this.controller }) + .onLoadIntercept((event) => { + if(event){ + let url = event.data.getRequestUrl(); + console.log(url); + if(url.indexOf('native://') === 0){ + this.getUIContext().getRouter().pushUrl({ url : url.substring(9)}) + return true; + } + } + return false; + }) + .width('100%') + .height('100%') + } + .layoutWeight(1) + } + } +} +// DocsCode 1 + +// DocsCode 2 +@Entry +@Component +struct Second { + build() { + Column() { + Text('这是本应用的第二个页面') + } + } +} +// DocsCode 2 + +// DocsCode 3 + + + + + + + Document + + + + + +// DocsCode 3 + +// DocsCode 4 + + + + + + + Document + + + + + +// DocsCode 4 + +// DocsCode 5 + + + + + + + Document + + +
+ hello world +
+
+ 我是本应用的第二个H5页面 +
+ + +// DocsCode 5 + +// DocsCode 6 +import { webview } from '@kit.ArkWeb' +import { common } from '@kit.AbilityKit'; +import { Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +function startSettingsInfo(context: common.UIAbilityContext,uri : string): void { + let want: Want = { + bundleName: 'com.huawei.hmos.settings', + abilityName: 'com.huawei.hmos.settings.MainAbility', + uri: uri + }; + context.startAbility(want) + .then(() => { + // ... + }) + .catch((err: BusinessError) => { + console.error(`Failed to startAbility. Code: ${err.code}, message: ${err.message}`); + }); +} +@Entry +@Component +struct WebComponent { + context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; + controller: webview.WebviewController = new webview.WebviewController(); + build() { + Column() { + Column() { + Web({ src: $rawfile('hello.html'), controller: this.controller }) + .onLoadIntercept((event) => { + if(event){ + let url = event.data.getRequestUrl(); + console.log(url); + if(url.indexOf('hmos://') === 0){ + startSettingsInfo(this.context,url.substring(7)) + return true; + } + } + return false; + }) + .width('100%') + .height('100%') + } + .layoutWeight(1) + } + } +} +// DocsCode 6 + +// DocsCode 7 + + + + + + + Document + + + + + + +// DocsCode 7 + +// DocsCode 8 +import { webview } from '@kit.ArkWeb' +import { common } from '@kit.AbilityKit'; +import { Want } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + build() { + Column() { + Column() { + Web({ src: $rawfile('hello.html'), controller: this.controller }) + .onLoadIntercept((event) => { + let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContext + let want: Want = { + deviceId: '', // deviceId为空表示本设备 + bundleName: '***', // 想要跳转的三方应用的bundleName + moduleName: 'entry', // moduleName非必选 + abilityName: 'EntryAbility', + parameters: { + // 自定义参数传递页面信息 + router: 'index' + } + } + context.startAbility(want).then(() => { + console.log('success') + }).catch((err: BusinessError) => { + console.log('error:' + JSON.stringify(err)) + }); + return false; + }) + } + .layoutWeight(1) + } + + } +} +// DocsCode 8 + +// DocsCode 9 + + + + + + + Document + + +跳转至三方应用 + + +// DocsCode 9 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/UseWebDownloadPdf.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/UseWebDownloadPdf.ets new file mode 100644 index 0000000000000000000000000000000000000000..4fcadec290becda36cb85dca5b6ec3d805e2fb4b --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/UseWebDownloadPdf.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用Web组件下载pdf文件并展示给用户 + */ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; +import { common } from '@kit.AbilityKit'; +import { request } from '@kit.BasicServicesKit'; + +let context = getContext(this) as common.UIAbilityContext; +let filesDir = context.filesDir; +let config: request.agent.Config = { + action: request.agent.Action.DOWNLOAD, + url: 'https://www-file.huawei.com/minisite/media/annual_report/annual_report_2023_cn.pdf', + title: 'createTest', + description: 'Sample code for create task', + mode: request.agent.Mode.FOREGROUND, + overwrite: true, + method: 'get', + saveas: filesDir + '/test.pdf', + network: request.agent.Network.WIFI, + metered: false, + roaming: true, + retry: true, + redirect: true, + index: 0, + begins: 0, + ends: -1, + gauge: false, + precise: false, + token: 'it is a secret' +}; +let createOnCallback = (progress: request.agent.Progress) => { + console.info('download task completed.'); + this.getUIContext().getPromptAction().showToast({ + message: '下载完成', + duration: 2000 + }); +}; + +@Entry +@Component +struct Index { + controller: webview.WebviewController = new webview.WebviewController(); + @State uri: string = ''; + @State isChange: boolean = false; + + build() { + Column() { + Button('刷新UI') + .width('200vp') + .onClick(() => { + this.controller.loadUrl('file://' + filesDir + '/test.pdf'); + }) + .margin({ bottom: '20vp' }) + Web({ src: $rawfile('WebDownloadPDF.html'), controller: this.controller }) + .fileAccess(true) + .domStorageAccess(true) + .onPageBegin((event) => { + request.agent.create(getContext(), config).then((task: request.agent.Task) => { + task.on('completed', createOnCallback); + console.info(`Succeeded in creating a download task. result: ${task.config}`); + task.start(); + }).catch((err: Error) => { + console.error(`Failed to create a download task, message: ${err.message}`); + }); + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/ets/pages/WebPdfViewerHandler.ets b/FAQ/ArkWebKit/entry/src/main/ets/pages/WebPdfViewerHandler.ets new file mode 100644 index 0000000000000000000000000000000000000000..d4486ce6beeafb4b0bcedfde383901a7e24c6fc9 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/ets/pages/WebPdfViewerHandler.ets @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用Web组件下载pdf文件并展示给用户 +*/ + +// DocsCode 1 +import { webview } from '@kit.ArkWeb'; +import { request } from '@kit.BasicServicesKit'; +import { promptAction } from '@kit.ArkUI'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +let filesDir = context.getHostContext()!.filesDir; +let config: request.agent.Config = { + action: request.agent.Action.DOWNLOAD, + url: 'https://www-file.huawei.com/minisite/media/annual_report/annual_report_2023_cn.pdf', + title: 'createTest', + description: 'Sample code for create task', + mode: request.agent.Mode.FOREGROUND, + overwrite: true, + method: 'get', + saveas: filesDir + '/test.pdf', + network: request.agent.Network.WIFI, + metered: false, + roaming: true, + retry: true, + redirect: true, + index: 0, + begins: 0, + ends: -1, + gauge: false, + precise: false, + token: 'it is a secret' +}; +let createOnCallback = (progress: request.agent.Progress) => { + console.info('download task completed.'); + promptAction.showToast({ + message: '下载完成', + duration: 2000 + }); +}; + +@Entry +@Component +struct Index { + controller: webview.WebviewController = new webview.WebviewController(); + @State uri: string = ''; + @State isChange: boolean = false; + + build() { + Column() { + Button('刷新UI') + .width('200vp') + .onClick(() => { + this.controller.loadUrl('file://' + filesDir + '/test.pdf'); + }) + .margin({ bottom: '20vp' }) + Web({ src: $rawfile('WebDownloadPDF.html'), controller: this.controller }) + .fileAccess(true) + .domStorageAccess(true) + .onPageBegin((event) => { + request.agent.create(this.getUIContext().getHostContext(), config).then((task: request.agent.Task) => { + task.on('completed', createOnCallback); + console.info(`Succeeded in creating a download task. result: ${task.config}`); + task.start(); + }).catch((err: Error) => { + console.error(`Failed to create a download task, message: ${err.message}`); + }); + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/module.json5 b/FAQ/ArkWebKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/element/color.json b/FAQ/ArkWebKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/element/float.json b/FAQ/ArkWebKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/element/string.json b/FAQ/ArkWebKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/media/background.png b/FAQ/ArkWebKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ArkWebKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/media/foreground.png b/FAQ/ArkWebKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ArkWebKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/ArkWebKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/ArkWebKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/ArkWebKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/ArkWebKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/ArkWebKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/FAQ/ArkWebKit/entry/src/main/resources/dark/element/color.json b/FAQ/ArkWebKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/mock/mock-config.json5 b/FAQ/ArkWebKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/ArkWebKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/ArkWebKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/ohosTest/module.json5 b/FAQ/ArkWebKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/ArkWebKit/entry/src/test/List.test.ets b/FAQ/ArkWebKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/entry/src/test/LocalUnit.test.ets b/FAQ/ArkWebKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/ArkWebKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/hvigor/hvigor-config.json5 b/FAQ/ArkWebKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/ArkWebKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/ArkWebKit/hvigorfile.ts b/FAQ/ArkWebKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/ArkWebKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ArkWebKit/oh-package-lock.json5 b/FAQ/ArkWebKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/ArkWebKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/ArkWebKit/oh-package.json5 b/FAQ/ArkWebKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/ArkWebKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/CameraKit/.gitignore b/FAQ/CameraKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/CameraKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/CameraKit/AppScope/app.json5 b/FAQ/CameraKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..796eb89dd9bd3856124883c87edbdf407448ffaf --- /dev/null +++ b/FAQ/CameraKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.camerakit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/CameraKit/AppScope/resources/base/element/string.json b/FAQ/CameraKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9fcc7c8d0cce973575acfa9bbceba758d92d33a4 --- /dev/null +++ b/FAQ/CameraKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "CameraKit" + } + ] +} diff --git a/FAQ/CameraKit/AppScope/resources/base/media/background.png b/FAQ/CameraKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CameraKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/CameraKit/AppScope/resources/base/media/foreground.png b/FAQ/CameraKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CameraKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/CameraKit/AppScope/resources/base/media/layered_image.json b/FAQ/CameraKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CameraKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/build-profile.json5 b/FAQ/CameraKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/CameraKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/code-linter.json5 b/FAQ/CameraKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/CameraKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/.gitignore b/FAQ/CameraKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/CameraKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/CameraKit/entry/build-profile.json5 b/FAQ/CameraKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/CameraKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/hvigorfile.ts b/FAQ/CameraKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/CameraKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CameraKit/entry/obfuscation-rules.txt b/FAQ/CameraKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/CameraKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/CameraKit/entry/oh-package.json5 b/FAQ/CameraKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/CameraKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/CameraKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/CameraKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/CameraKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/pages/GetCameraStatus.ets b/FAQ/CameraKit/entry/src/main/ets/pages/GetCameraStatus.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3f03d6ecccc0375954970038946e2ab673bc2cd --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/pages/GetCameraStatus.ets @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何检测当前相机服务的状态 +*/ + +// DocsCode 1 +import { camera } from '@kit.CameraKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +let cameraManager = camera.getCameraManager(UIContext.getHostContext()!); +cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { + console.log(`camera : ${cameraStatusInfo.camera.cameraId}`); + console.log(`status: ${cameraStatusInfo.status}`); +}); +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/pages/GetFrontCameraImage.ets b/FAQ/CameraKit/entry/src/main/ets/pages/GetFrontCameraImage.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a689ccd1781960b26d3c75176db2182756ba9ef --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/pages/GetFrontCameraImage.ets @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取前置摄像头的预览图像 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { camera } from '@kit.CameraKit'; +import { common } from '@kit.AbilityKit'; + +const context = UIContext.getHostContext()! as common.UIAbilityContext; + +@Entry +@Component +struct GetFrontCameraImage { + private xComponentController: XComponentController = new XComponentController(); + + async getCameraImage() { + // 1、使用系统相机框架camera模块获取物理摄像头信息。 + let cameraManager = camera.getCameraManager(context); + let camerasInfo: Array = cameraManager.getSupportedCameras(); + let cameraDevice: camera.CameraDevice = camerasInfo[0]; + // 检测相机状态 + cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { + console.log(`camera : ${cameraStatusInfo.camera.cameraId}`); + console.log(`status : : ${cameraStatusInfo.status}`); + }); + // 2、创建并启动物理摄像头输入流通道 + // 设置为前置摄像头 camera.CameraPosition.CAMERA_POSITION_FRONT + let cameraInput = cameraManager.createCameraInput(camera.CameraPosition.CAMERA_POSITION_FRONT, + camera.CameraType.CAMERA_TYPE_DEFAULT); + await cameraInput.open(); + // 3、拿到物理摄像头信息查询摄像头支持预览流支持的输出格式,结合XComponent提供的surfaceId创建预览输出通道 + let outputCapability = cameraManager.getSupportedOutputCapability(cameraDevice, camera.SceneMode.NORMAL_PHOTO); + let previewProfile = outputCapability.previewProfiles[0]; + let surfaceId = this.xComponentController.getXComponentSurfaceId(); + let previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId); + // 4、创建相机会话,在会话中添加摄像头输入流和预览输出流,然后启动会话,预览画面就会在XComponent组件上送显。 + let captureSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO); + captureSession.beginConfig(); + captureSession.addInput(cameraInput); + captureSession.addOutput(previewOutput); + captureSession.commitConfig() + captureSession.start(); + } + + build() { + Row() { + Column({ space: 20 }) { + XComponent({ id: 'xComponentId1', type: 'surface', controller: this.xComponentController }) + .height(300) + Button('打开摄像头') + .onClick(() => { + // 在调用前确保已经获得相机权限 + this.getCameraImage(); + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/pages/Index.ets b/FAQ/CameraKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/pages/RealizePhotoPreview.ets b/FAQ/CameraKit/entry/src/main/ets/pages/RealizePhotoPreview.ets new file mode 100644 index 0000000000000000000000000000000000000000..334627d1d1ebf617dc09b0bb0f5e5e21befb2c5d --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/pages/RealizePhotoPreview.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现拍照预览onPreviewFrame回调 +*/ + +// DocsCode 1 +this.previewOutput = this.cameraManager!.createPreviewOutput(previewProfilesArray[5], surfaceId); +let size: image.Size = { + width: 640, + height: 480 +} +let receiver: image.ImageReceiver = image.createImageReceiver(size, image.ImageFormat.JPEG, 8); +receiver.on('imageArrival', () => { + receiver.readNextImage((err: BusinessError, nextImage: image.Image) => { + if (err || nextImage === undefined) { + console.error('readNextImage failed'); + return; + } + nextImage.getComponent(image.ComponentType.JPEG, (err: BusinessError, imgComponent: image.Component) => { + if (err || imgComponent === undefined) { + console.error('getComponent failed'); + } + if (imgComponent && imgComponent.byteBuffer as ArrayBuffer && this.count<3) { + this.count = this.count + 1 + let path: string = this.getUIContext().getHostContext()!.filesDir + "/image.yuv"; + let file = fileIo.openSync(path, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + let opt: WriteOptions = { + // 多出2048字节数据 + length: imgComponent.byteBuffer.byteLength - 2048 + } + fileIo.write(file.fd, imgComponent.byteBuffer, opt).then((writeLen) => { + console.info("write data to file succeed and size is:" + writeLen); + fileIo.closeSync(file); + }).catch((err: BusinessError) => { + console.info("write data to file failed with error message: " + err.message + ", error code: " + err.code); + }); + } + nextImage.release(); + }) + }) +}) +let ImageReceiverSurfaceId: string = await receiver.getReceivingSurfaceId(); +this.previewOutput2 = this.cameraManager!.createPreviewOutput(previewProfilesArray[5], ImageReceiverSurfaceId); +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/pages/ResolvePreviewStreamBlackScreenIssue.ets b/FAQ/CameraKit/entry/src/main/ets/pages/ResolvePreviewStreamBlackScreenIssue.ets new file mode 100644 index 0000000000000000000000000000000000000000..65402137ae20d56950fa0793840f7b99d5c0ac7d --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/pages/ResolvePreviewStreamBlackScreenIssue.ets @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:预览流黑屏但无报错信息该怎么解决 +*/ + +// DocsCode 1 +"requestPermissions": [ +{ + "name": + "ohos.permission.CAMERA", "usedScene": + { + "abilities": [ + "FormAbility" ], + "when": + "always" + } + , + "reason": + "$string:Camera_Permission_Request" +} +, +{ + "name": + "ohos.permission.MICROPHONE", "usedScene": + { + "abilities": [ + "FormAbility" ], + "when": + "always" + } + , + "reason": + "$string:Camera_Permission_Request" +} +, +{ + "name": + "ohos.permission.WRITE_MEDIA", "usedScene": + { + "abilities": [ + "FormAbility" ], + "when": + "always" + } + , + "reason": + "$string:Camera_Permission_Request" +} +, +{ + "name": + "ohos.permission.READ_MEDIA", "usedScene": + { + "abilities": [ + "FormAbility" ], + "when": + "always" + } + , + "reason": + "$string:Camera_Permission_Request" +} +] +, +// DocsCode 1 + +// DocsCode 2 +onWindowStageCreate(windowStage: window.WindowStage): void { + let atManager = abilityAccessCtrl.createAtManager(); + atManager.requestPermissionsFromUser(this.context, + [ + 'ohos.permission.CAMERA', + 'ohos.permission.MICROPHONE', + 'ohos.permission.MEDIA_LOCATION', + 'ohos.permission.WRITE_MEDIA' + ] + ).then((data) => { + console.info('data:' + JSON.stringify(data)); + console.info('data permissions:' + data.permissions); + console.info('data authResults:' + data.authResults); + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/CameraPreviewFlow', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; +} +hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); +}); +}).catch((err: BusinessError) => { + console.info('data:' + JSON.stringify(err)); +}); +} +// DocsCode 2 + +// DocsCode 3 +async +onPageShow() { + let baseContext = this.getUIContext().getHostContext()! as common.BaseContext; + await this.initCamera(baseContext, this.surfaceId); +} + +async +onPageHide() { + await this.releaseCamera(); +} +// DocsCode 3 + +// DocsCode 4 +// 获取相机设备支持的输出流能力 +let cameraOutputCap: camera.CameraOutputCapability = + cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_PHOTO); +if (!cameraOutputCap) { + console.error(TAG, "cameraManager.getSupportedOutputCapability error"); + return; +} +console.info(TAG, "outputCapability: " + +JSON.stringify(cameraOutputCap)); //预览流与录像输出流的分辨率的宽高比要保持一致 +let previewProfilesArray: Array = cameraOutputCap.previewProfiles; +let position: number = 0; +if (previewProfilesArray != null) { + previewProfilesArray.forEach((value: camera.Profile, + index: number) => { // 查看支持的预览尺寸 + console.info(TAG, + `支持的预览尺寸: [${value.size.width},${value.size.height},${value.size.width / value.size.height}]`); + if (value.size.width === 2592 && value.size.height === 1200) { + position = index; + } + }) +} else { + console.error(TAG, "createOutput photoProfilesArray == null || undefined"); +} +// DocsCode 4 \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/ets/pages/SetVideoPreviewResolution.ets b/FAQ/CameraKit/entry/src/main/ets/pages/SetVideoPreviewResolution.ets new file mode 100644 index 0000000000000000000000000000000000000000..47b1b68c5530edaa56c2291dc71922ad29b00e6c --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/ets/pages/SetVideoPreviewResolution.ets @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:视频预览分辨率设置 +*/ + +// DocsCode 1 +XComponent({ + id: 'componentId', + type: 'surface', + controller: this.mXComponentController, +}).onLoad(async () => { + this.surfaceId = this.mXComponentController.getXComponentSurfaceId(); + let baseContext = this.getUIContext().getHostContext()! as common.BaseContext; + await this.initCamera(baseContext, this.surfaceId) +}).width('100%') + .height('100%') +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/module.json5 b/FAQ/CameraKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/base/element/color.json b/FAQ/CameraKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/base/element/float.json b/FAQ/CameraKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/base/element/string.json b/FAQ/CameraKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/base/media/background.png b/FAQ/CameraKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CameraKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/CameraKit/entry/src/main/resources/base/media/foreground.png b/FAQ/CameraKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CameraKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/CameraKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/CameraKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/CameraKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/CameraKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/CameraKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/CameraKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/CameraKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..9749d1aeb5942d2d195cfb3fde0059a9659722ca --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,10 @@ +{ + "src": [ + "pages/Index", + "pages/GetFrontCameraImage", + "pages/GetCameraStatus", + "pages/ResolvePreviewStreamBlackScreenIssue", + "pages/SetVideoPreviewResolution", + "pages/RealizePhotoPreview" + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/main/resources/dark/element/color.json b/FAQ/CameraKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/CameraKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/mock/mock-config.json5 b/FAQ/CameraKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/CameraKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/CameraKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/CameraKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/CameraKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/CameraKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/ohosTest/module.json5 b/FAQ/CameraKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/CameraKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/CameraKit/entry/src/test/List.test.ets b/FAQ/CameraKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/CameraKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/CameraKit/entry/src/test/LocalUnit.test.ets b/FAQ/CameraKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/CameraKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/CameraKit/hvigor/hvigor-config.json5 b/FAQ/CameraKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/CameraKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/CameraKit/hvigorfile.ts b/FAQ/CameraKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/CameraKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CameraKit/oh-package-lock.json5 b/FAQ/CameraKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/CameraKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/CameraKit/oh-package.json5 b/FAQ/CameraKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/CameraKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/CompilingAndBuilding/.gitignore b/FAQ/CompilingAndBuilding/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/CompilingAndBuilding/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/AppScope/app.json5 b/FAQ/CompilingAndBuilding/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..43c3768f298019e9432b325e024b0710839963e5 --- /dev/null +++ b/FAQ/CompilingAndBuilding/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.compilingandbuilding", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/CompilingAndBuilding/AppScope/resources/base/element/string.json b/FAQ/CompilingAndBuilding/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..6f823777756b3194c1d0e95d5ecc7be5dff5a3e9 --- /dev/null +++ b/FAQ/CompilingAndBuilding/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "CompilingAndBuilding" + } + ] +} diff --git a/FAQ/CompilingAndBuilding/AppScope/resources/base/media/background.png b/FAQ/CompilingAndBuilding/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CompilingAndBuilding/AppScope/resources/base/media/background.png differ diff --git a/FAQ/CompilingAndBuilding/AppScope/resources/base/media/foreground.png b/FAQ/CompilingAndBuilding/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CompilingAndBuilding/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/CompilingAndBuilding/AppScope/resources/base/media/layered_image.json b/FAQ/CompilingAndBuilding/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CompilingAndBuilding/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/build-profile.json5 b/FAQ/CompilingAndBuilding/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/CompilingAndBuilding/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/code-linter.json5 b/FAQ/CompilingAndBuilding/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/CompilingAndBuilding/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/.gitignore b/FAQ/CompilingAndBuilding/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/build-profile.json5 b/FAQ/CompilingAndBuilding/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/hvigorfile.ts b/FAQ/CompilingAndBuilding/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CompilingAndBuilding/entry/obfuscation-rules.txt b/FAQ/CompilingAndBuilding/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/oh-package.json5 b/FAQ/CompilingAndBuilding/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/CompilingAndBuilding/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/CompilingAndBuilding/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/CompilingAndBuilding/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/ErrorOccurredWhileBuildingHSPModule.ets b/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/ErrorOccurredWhileBuildingHSPModule.ets new file mode 100644 index 0000000000000000000000000000000000000000..d044ff7124031ac8294fb94ed415e62ad448235e --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/ErrorOccurredWhileBuildingHSPModule.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:构建HSP模块时报错“Ohos BundleTool [Error]: hsp has home ability;Ohos BundleTool [Error]: CompressEntrance::main exit, verify failed.” + */ + +// DocsCode 1 +// HSP模块hvigorfile.ts +import { hspTasks,OhosPluginId, Target } from '@ohos/hvigor-ohos-plugin'; +import { hvigor, HvigorNode, HvigorPlugin,FileUtil } from '@ohos/hvigor'; +export function customPlugin():HvigorPlugin { + return { + pluginId: 'customPlugin', + context() { + return { + data: 'customPlugin xxx' + }; + }, + apply(currentNode:HvigorNode): Promise { + hvigor.nodesEvaluated(async () => { + hspTask(currentNode); + }); + } + } +} +function hspTask(currentNode: HvigorNode) { + // 获取hsp模块上下文信息 + const hspContext = currentNode.getContext(OhosPluginId.OHOS_HSP_PLUGIN) as OhosHspContext; + hspContext?.targets((target: Target) => { + const targetName = target.getTargetName(); + const outputPath = target.getBuildTargetOutputPath(); + const task = currentNode.getTaskByName(`${targetName}@GeneratePkgModuleJson`); + currentNode.registerTask({ + // 任务名称 + name: `${targetName}@changeModuleJson`, + // 任务执行逻辑主体函数 + run() { + const moduleJson = FileUtil.readJson5(outputPath+"/../../intermediates/package/"+targetName+"/module.json"); + const abilities = moduleJson['module']['abilities']; + abilities.forEach((ability)=>{ + delete ability['skills']; + }) + console.log('begin to rewrite module.json file.'); + moduleJson['module']['abilities'] = abilities + FileUtil.writeFileSync(outputPath+"/../../intermediates/package/"+targetName+"/module.json",JSON.stringify(moduleJson)); + }, + // 配置前置任务依赖 + dependencies: [`${targetName}@GeneratePkgModuleJson`], + // 配置任务的后置任务依赖 + postDependencies: [`${targetName}@PackageSharedHar`] + }); + }); +} +export default { + system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[customPlugin()] /* Custom plugin to extend the functionality of Hvigor. */ +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/Index.ets b/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/PushPackageDebuggingError.ets b/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/PushPackageDebuggingError.ets new file mode 100644 index 0000000000000000000000000000000000000000..377fff638e668c6ea11151a485d0411bebc16d23 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/ets/pages/PushPackageDebuggingError.ets @@ -0,0 +1,160 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:推包调试报错“Error message:cannot find record '&XXX/src/main/ets/YYY&x.y.z', please check the request path.'ZZZ.abc'.” + */ + +// DocsCode 1 +import {OhosPluginId, Target} from '@ohos/hvigor-ohos-plugin'; +import {hvigor, HvigorNode, HvigorPlugin} from '@ohos/hvigor'; +import path from "path"; +import fs from "fs"; + +function getLoaderJsonPath(target: Target) { + return path.resolve(target.getBuildTargetOutputPath(), `../../intermediates/loader/${target.getTargetName()}/loader.json`); +} + +function getPkgContextInfoPath(target: Target) { + return path.resolve(target.getBuildTargetOutputPath(), `../../intermediates/loader/${target.getTargetName()}/pkgContextInfo.json`); +} + +function deleteLoaderJson(target: Target) { + const loaderJsonPath = getLoaderJsonPath(target); + if (fs.existsSync(loaderJsonPath)) { + fs.rmSync(loaderJsonPath); + } +} + +function deletePkgContextInfo(target: Target) { + const pkgContextInfoPath = getPkgContextInfoPath(target); + if (fs.existsSync(pkgContextInfoPath)) { + fs.rmSync(pkgContextInfoPath); + } +} + +function deleteRollupCache(target: Target, buildMode: string) { + const arkTSCompileCachePath = path.resolve(target.getBuildTargetOutputPath(), + `../../cache/${target.getTargetName()}/${target.getTargetName()}@HarCompileArkTS/esmodule/${buildMode}/compiler.cache`); + if (fs.existsSync(arkTSCompileCachePath)) { + fs.rmSync(arkTSCompileCachePath, { recursive: true }); + } +} + +function updateHapHspAbcVersion(subNode: HvigorNode, target: Target) { + const task = subNode.getTaskByName(`${target.getTargetName()}@GenerateLoaderJson`); + if (!task) { + console.log('GenerateLoaderJson not found.'); + return; + } + deleteLoaderJson(target); + deletePkgContextInfo(target); + task.afterRun(() => { + const pkgContextInfoPath = getPkgContextInfoPath(target); + if (!fs.existsSync(pkgContextInfoPath)) { + console.log('pkgContextInfo not found.'); + return; + } + const pkgContextInfoObj = JSON.parse(fs.readFileSync(pkgContextInfoPath).toString()); + if (!pkgContextInfoObj) { + console.log('pkgContextInfo parse failed.'); + return; + } + const loaderJsonPath = getLoaderJsonPath(target); + if (!fs.existsSync(loaderJsonPath)) { + console.log('loaderJson not found.'); + return; + } + const loaderJsonObj = JSON.parse(fs.readFileSync(loaderJsonPath).toString()); + if (!loaderJsonObj) { + console.log('loaderJson parse failed.'); + return; + } + for (const [key, value] of Object.entries(pkgContextInfoObj)) { + if (!value?.version) { + continue; + } + if (!loaderJsonObj.updateVersionInfo[key]) { + loaderJsonObj.updateVersionInfo[key] = {}; + } + loaderJsonObj.updateVersionInfo[key][key] = value.version; + } + fs.writeFileSync(loaderJsonPath, JSON.stringify(loaderJsonObj)); + }); +} + +function updateHarAbcVersion(target: Target) { + deleteLoaderJson(target); + deleteRollupCache(target, 'debug'); + deleteRollupCache(target, 'release'); +} + +// 字节码har的使用方使用此插件,在集成字节码har时,可以正确修改abc中ohmurl的版本号,保证运行时不闪退 +export function updateAbcVersionPlugin(): HvigorPlugin { + return { + pluginId: 'updateAbcVersionPlugin', + apply(node: HvigorNode) { + hvigor.nodesEvaluated(() => { + hvigor.getRootNode().subNodes(subNode => { + let context = subNode.getContext(OhosPluginId.OHOS_HAP_PLUGIN); + if (!context) { + context = subNode.getContext(OhosPluginId.OHOS_HSP_PLUGIN); + } + if (!context) { + return; + } + context.targets(target => { + updateHapHspAbcVersion(subNode, target); + }); + }); + }); + } + }; +} + +// 字节码har的生成方使用此插件,在修改版本号之后可以增量构建出ohmurl正确的字节码har +export function updateHarAbcVersionPlugin(): HvigorPlugin { + return { + pluginId: 'updateHarAbcVersionPlugin', + apply(node: HvigorNode) { + hvigor.nodesEvaluated(() => { + hvigor.getRootNode().subNodes(subNode => { + const context = subNode.getContext(OhosPluginId.OHOS_HAR_PLUGIN); + if (!context) { + return; + } + context.targets(target => { + updateHarAbcVersion(target); + }); + }); + }); + } + }; +} +// DocsCode 1 + +// DocsCode 2 +import { appTasks } from '@ohos/hvigor-ohos-plugin'; +import { updateAbcVersionPlugin, updateHarAbcVersionPlugin } from './plugin.ts'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[updateAbcVersionPlugin(), updateHarAbcVersionPlugin()] /* Custom plugin to extend the functionality of Hvigor. */ +} +// DocsCode 2 + +// DocsCode 3 +hvigorw --stop-daemon +// DocsCode 3 \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/module.json5 b/FAQ/CompilingAndBuilding/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/color.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/float.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/string.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/background.png b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/foreground.png b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/layered_image.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/startIcon.png b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/profile/backup_config.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/base/profile/main_pages.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..2e45e7c7694ac43d507de8d2f851dfe1c15a082a --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,7 @@ +{ + "src": [ + "pages/Index", + "pages/PushPackageDebuggingError", + "pages/ErrorOccurredWhileBuildingHSPModule" + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/main/resources/dark/element/color.json b/FAQ/CompilingAndBuilding/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/mock/mock-config.json5 b/FAQ/CompilingAndBuilding/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/CompilingAndBuilding/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/CompilingAndBuilding/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/ohosTest/module.json5 b/FAQ/CompilingAndBuilding/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/CompilingAndBuilding/entry/src/test/List.test.ets b/FAQ/CompilingAndBuilding/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/entry/src/test/LocalUnit.test.ets b/FAQ/CompilingAndBuilding/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/CompilingAndBuilding/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/hvigor/hvigor-config.json5 b/FAQ/CompilingAndBuilding/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/CompilingAndBuilding/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/CompilingAndBuilding/hvigorfile.ts b/FAQ/CompilingAndBuilding/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/CompilingAndBuilding/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CompilingAndBuilding/oh-package-lock.json5 b/FAQ/CompilingAndBuilding/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/CompilingAndBuilding/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/CompilingAndBuilding/oh-package.json5 b/FAQ/CompilingAndBuilding/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/CompilingAndBuilding/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/CoreFileKit/.gitignore b/FAQ/CoreFileKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/CoreFileKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/CoreFileKit/AppScope/app.json5 b/FAQ/CoreFileKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..82a9586484a54636236415a786742a7168ebeff2 --- /dev/null +++ b/FAQ/CoreFileKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.corefilekit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/CoreFileKit/AppScope/resources/base/element/string.json b/FAQ/CoreFileKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..62fcc31f4405e696575142c0ea566d1a62fc97ec --- /dev/null +++ b/FAQ/CoreFileKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "CoreFileKit" + } + ] +} diff --git a/FAQ/CoreFileKit/AppScope/resources/base/media/background.png b/FAQ/CoreFileKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CoreFileKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/CoreFileKit/AppScope/resources/base/media/foreground.png b/FAQ/CoreFileKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CoreFileKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/CoreFileKit/AppScope/resources/base/media/layered_image.json b/FAQ/CoreFileKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CoreFileKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/build-profile.json5 b/FAQ/CoreFileKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/CoreFileKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/code-linter.json5 b/FAQ/CoreFileKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/CoreFileKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/.gitignore b/FAQ/CoreFileKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/CoreFileKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/build-profile.json5 b/FAQ/CoreFileKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/CoreFileKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/hvigorfile.ts b/FAQ/CoreFileKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/CoreFileKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CoreFileKit/entry/obfuscation-rules.txt b/FAQ/CoreFileKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/CoreFileKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/oh-package.json5 b/FAQ/CoreFileKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/CoreFileKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/CoreFileKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/CoreFileKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/CoreFileKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/CacheSizeAndCleanupAPI.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/CacheSizeAndCleanupAPI.ets new file mode 100644 index 0000000000000000000000000000000000000000..c845ac46ef5c4bc46bdf30b358ad1e4f2c327a3c --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/CacheSizeAndCleanupAPI.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:怎么获取应用已使用的缓存大小,如何使用API清理缓存 +*/ + +// DocsCode 1 +import { fileIo, storageStatistics } from '@kit.CoreFileKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct ClearCache { + // 在缓存中创建一个文件 + writeFile() { + let filePath = this.getUIContext().getHostContext()!.cacheDir + '/test.txt'; + let fileStream = fileIo.createStreamSync(filePath, 'w+'); + fileStream.writeSync('1145141919810'); + fileStream.close(); + } + + // 获取应用数据空间大小 + getCache() { + storageStatistics.getCurrentBundleStats((error: BusinessError, bundleStats: storageStatistics.BundleStats) => { + if (error) { + console.error('getCurrentBundleStats failed with error:' + JSON.stringify(error)); + } else { + console.info('getCurrentBundleStats successfully:' + JSON.stringify(bundleStats)); + console.info('appsize :' + bundleStats.appSize); + console.info('cacheSize :' + bundleStats.cacheSize); + console.info('dataSize :' + bundleStats.dataSize); + } + }); + } + + // 清理缓存 + clearCache() { + let cacheDir = this.getUIContext().getHostContext()!.cacheDir; + console.info(cacheDir); + + fileIo.listFile(cacheDir).then((filenames) => { + for (let i = 0; i < filenames.length; i++) { + let dirPath = cacheDir + '/' + filenames[i]; + console.log(dirPath); + // 判断是否为文件夹 + let isDirectory: boolean = false; + try { + isDirectory = fileIo.statSync(dirPath).isDirectory(); + } catch (e) { + console.error(JSON.stringify(e)); + } + + if (isDirectory) { + fileIo.rmdirSync(dirPath); + } else { + fileIo.unlink(dirPath).then(() => { + console.info('remove file succeed'); + }).catch((err: Error) => { + console.error('remove file failed with error message: ' + err.message); + }); + } + } + + }) + } + + build() { + Column() { + Button('向缓存写入数据') + .onClick(() => { + this.writeFile(); + }) + Button('获取系统缓存大小') + .onClick(() => { + this.getCache(); + }) + Button('点击清理缓存') + .onClick(() => { + this.clearCache(); + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/CheckStorageSpace.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/CheckStorageSpace.ets new file mode 100644 index 0000000000000000000000000000000000000000..e8ddc26c20e6d9bcbf3fec56c131cc24f87c3dd5 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/CheckStorageSpace.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:获取指定文件系统的剩余空间大小 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { statfs } from '@kit.CoreFileKit'; + +@Entry +@Component +struct GetFileSpace { + build() { + Column() { + Button('获取系统空间大小') + .onClick(() => { + let context = this.getUIContext().getHostContext(); + let path = context!.filesDir; + + //获取指定文件系统总字节数 + statfs.getTotalSize(path).then((number: number) => { + console.info('getTotalSize succeed, Size: ' + number); + }).catch((err: BusinessError) => { + console.error('getTotalSize failed with error message: ' + err.message + ', error code: ' + err.code); + }); + + //获取指定文件系统空闲字节数 + statfs.getFreeSize(path).then((number: number) => { + console.info('getFreeSize succeed, Size: ' + number); + }).catch((err: BusinessError) => { + console.error('getFreeSize failed with error message: ' + err.message + ', error code: ' + err.code); + }); + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/CreateTempFile.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/CreateTempFile.ets new file mode 100644 index 0000000000000000000000000000000000000000..f1f0522e6b00e2c19849c3f1ceb40e2b5433ee75 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/CreateTempFile.ets @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何创建临时文件 +*/ + +// DocsCode 1 +import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit'; +import { common } from '@kit.AbilityKit'; +import { buffer } from '@kit.ArkTS'; + +@Entry +@Component +struct CreateFileDemo { + @State message: string = 'Hello World'; + @State writeStr: string = 'write content'; + @State readStr: string = 'read content'; + + build() { + Column() { + Text(this.message) + Button(this.writeStr) + .margin({ top: 15, bottom: 15 }) + .onClick(() => { + let context = this.getUIContext().getHostContext(); + let filesDir = context!.tempDir; + let file = fs.openSync(filesDir + 'test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // 写入一段内容至文件 + fs.writeSync(file.fd, 'Try to write str.'); + console.info('str has been written'); + // 关闭文件 + fs.closeSync(file); + }) + Button(this.readStr) + .onClick(() => { + let context = this.getUIContext().getHostContext(); + let filesDir = context!.tempDir; + let file = fs.openSync(filesDir + 'test.txt', fs.OpenMode.READ_WRITE); + // 从文件读取一段内容 + let arrayBuffer = new ArrayBuffer(1024); + let readOptions: ReadOptions = { + offset: 0, + length: arrayBuffer.byteLength + }; + let readLen = fs.readSync(file.fd, arrayBuffer, readOptions); + let buf = buffer.from(arrayBuffer, 0, readLen); + this.message = buf.toString(); + // 关闭文件 + fs.closeSync(file); + }) + } + .height('100%') + .width('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/FileContentParser.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/FileContentParser.ets new file mode 100644 index 0000000000000000000000000000000000000000..47c11a810659b5c3a33859002ae2ef675bf0a730 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/FileContentParser.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何读取指定文件内容,并转为具体对象 +*/ + +// DocsCode 1 +import { Context } from '@kit.AbilityKit'; +import { buffer } from '@kit.ArkTS'; + +@Entry +@Component +struct Index { + private context: Context | undefined = this.getUIContext().getHostContext(); + private str: string = ''; + + getRawFile(): ESObject { + //调用getRawFileContent接口获取json文件内容,并读为string + this.getUIContext().getHostContext()!.resourceManager.getRawFileContent('test.json', (err, data) => { + try { + this.str = buffer.from(data.buffer).toString(); + console.info(JSON.stringify(this.str)); + } catch (e) { + console.info(JSON.stringify(e)); + } + }) + //也可以调用getRawFileContentSync接口获取json文件内容,并读为string + try { + let data: Uint8Array = this.context!.resourceManager.getRawFileContentSync('test.json'); + this.str = buffer.from(data.buffer).toString(); + } catch (e) { + console.info(JSON.stringify(e)); + } + // string转为ESObject + let obj: ESObject = JSON.parse(this.str); + console.info('ESObject', JSON.stringify(obj)); + return obj; + } + + build() { + Column() { + Button('get') + .onClick(() => { + this.getRawFile(); + }) + }.width('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/GetRawfile.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/GetRawfile.ets new file mode 100644 index 0000000000000000000000000000000000000000..c826f0497653ad082599a784adbe068cf154c242 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/GetRawfile.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取到 resources下rawfile 的文件 +*/ + +// DocsCode 1 +import { fileIo } from '@kit.CoreFileKit'; + +@Component +export struct GetRawfile { + @State message: string = 'Hello World'; + + aboutToAppear(): void { + getContext(this).resourceManager.getRawFileContent('test.txt', (_err, value) => { + let myBuffer: ArrayBufferLike = value.buffer; + let context = this.getUIContext().getHostContext(); //沙箱路径 + let filePath = context!.filesDir + '/test.txt'; + console.info('testTag-filePath:' + filePath); + let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + let writeLen = fileIo.writeSync(file.fd, myBuffer); + console.info('testTag-write data to file succeed and size is:' + writeLen); + fileIo.closeSync(file); + }); + } + + build() { + RelativeContainer() { + Text(this.message) + .id('RawfileHelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + } + .height('100%') + .width('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/HandleFileEncodingProblem.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/HandleFileEncodingProblem.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a09f947d6bc73b2ecfa607ad7f8ee37ed0c3350 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/HandleFileEncodingProblem.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决文件的中文乱码问题 +*/ + +// DocsCode 1 +import { util } from '@kit.ArkTS'; +import { fileIo } from '@kit.CoreFileKit'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +// 创建一个文件写入中文字符 +let filePath = context.getHostContext()!.filesDir + "/test0.txt"; +let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); +// 写入一段内容至文件 +let writeLen = fileIo.writeSync(file.fd, "你好,世界"); +fileIo.closeSync(file); +console.info(`GarbledCnCharacters The length of str is: ${writeLen}`); +let stream = fileIo.createStreamSync(filePath, "r+"); +let buffer = new ArrayBuffer(4096); +stream.readSync(buffer); +// 设置编码格式为“utf-8” +let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true }); +// 解码输后获取对应文本 +let readString = textDecoder.decodeToString(new Uint8Array(buffer), { stream: false }); +console.info(`GarbledCnCharacters read content is:${readString}`); +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/Index.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/StreamDataToFile.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/StreamDataToFile.ets new file mode 100644 index 0000000000000000000000000000000000000000..1ffa41627cb483cbf4da10adace49da67b6224de --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/StreamDataToFile.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将数据持续写入文件内 +*/ + +// DocsCode 1 +import { fileIo, WriteOptions } from '@kit.CoreFileKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Component +export struct ContinuousWrite { + @State message: string = 'Hello World'; + + aboutToAppear(): void { + let context = this.getUIContext().getHostContext(); // 沙箱路径 + let filePath = context!.filesDir + '/test.txt'; + let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE); + let arrayBuffer = new ArrayBuffer(4096); + fileIo.read(file.fd, arrayBuffer).then((readLen: number) => { + console.info(readLen.toString()); + let str: string = 'hello, world'; + let options: WriteOptions = { offset: readLen }; + let writeLen = fileIo.writeSync(file.fd, str, options); + console.info('write data to file succeed and size is:' + writeLen); + }).catch((err: BusinessError) => { + console.error('read file data failed with error message: ' + err.message + ', error code: ' + err.code); + }).finally(() => { + fileIo.closeSync(file); + }); + } + + build() { + RelativeContainer() { + Text(this.message) + .id('WriteHelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + } + .height('100%') + .width('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/ets/pages/UpdateSandboxJson.ets b/FAQ/CoreFileKit/entry/src/main/ets/pages/UpdateSandboxJson.ets new file mode 100644 index 0000000000000000000000000000000000000000..b4b4207ef7bbc72191954fda40764a52af3f8ece --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/ets/pages/UpdateSandboxJson.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何修改沙箱路径下json文件的指定内容 +*/ + +// DocsCode 1 +import { fileIo } from '@kit.CoreFileKit'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +let filePath = context.getHostContext()!.filesDir + '/people.json'; + +class Student { + name: string = 'zhangsan'; + age: number = 10; +} + +let student = new Student(); +// 1 创建文件,并且写入内容 +let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); +fileIo.writeSync(file.fd, JSON.stringify(student)) +fileIo.close(file); +// 2 通过fileIo.readSync读取json文件内容。 +let data = fileIo.readTextSync(filePath); +let obj: Student = JSON.parse(data); +// 3 修改指定内容name为lisi +obj.name = 'lisi'; +// 4 重新写入json文件 +let fileModify = fileIo.openSync(filePath, fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.TRUNC); +fileIo.writeSync(fileModify.fd, JSON.stringify(obj)); +fileIo.close(fileModify); +// 5 读取最新内容 +let content = fileIo.readTextSync(filePath); +console.info(`ModifySanFileContent content is :${content}`); +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/module.json5 b/FAQ/CoreFileKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/element/color.json b/FAQ/CoreFileKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/element/float.json b/FAQ/CoreFileKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/element/string.json b/FAQ/CoreFileKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/media/background.png b/FAQ/CoreFileKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CoreFileKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/media/foreground.png b/FAQ/CoreFileKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CoreFileKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/CoreFileKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/CoreFileKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/CoreFileKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/CoreFileKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/CoreFileKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/FAQ/CoreFileKit/entry/src/main/resources/dark/element/color.json b/FAQ/CoreFileKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/mock/mock-config.json5 b/FAQ/CoreFileKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/CoreFileKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/CoreFileKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/ohosTest/module.json5 b/FAQ/CoreFileKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/CoreFileKit/entry/src/test/List.test.ets b/FAQ/CoreFileKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/entry/src/test/LocalUnit.test.ets b/FAQ/CoreFileKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/CoreFileKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/hvigor/hvigor-config.json5 b/FAQ/CoreFileKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/CoreFileKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/CoreFileKit/hvigorfile.ts b/FAQ/CoreFileKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/CoreFileKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CoreFileKit/oh-package-lock.json5 b/FAQ/CoreFileKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c6f99f5c73b06c5fdef7ec6f491b74b7befebe2e --- /dev/null +++ b/FAQ/CoreFileKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/CoreFileKit/oh-package.json5 b/FAQ/CoreFileKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/CoreFileKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/CryptoArchitectureKit/.gitignore b/FAQ/CryptoArchitectureKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/CryptoArchitectureKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/AppScope/app.json5 b/FAQ/CryptoArchitectureKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..87d45c975cd911b9f24b12c4a9f0979869e3a61f --- /dev/null +++ b/FAQ/CryptoArchitectureKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.cryptoarchitecturekit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/CryptoArchitectureKit/AppScope/resources/base/element/string.json b/FAQ/CryptoArchitectureKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..8dc255af16832fe03be404301ea35e90ee5d35f6 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "CryptoArchitectureKit" + } + ] +} diff --git a/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/background.png b/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/foreground.png b/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/layered_image.json b/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CryptoArchitectureKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/build-profile.json5 b/FAQ/CryptoArchitectureKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/code-linter.json5 b/FAQ/CryptoArchitectureKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/.gitignore b/FAQ/CryptoArchitectureKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/build-profile.json5 b/FAQ/CryptoArchitectureKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/hvigorfile.ts b/FAQ/CryptoArchitectureKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CryptoArchitectureKit/entry/obfuscation-rules.txt b/FAQ/CryptoArchitectureKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/oh-package.json5 b/FAQ/CryptoArchitectureKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/CryptoArchitectureKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/CryptoArchitectureKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/ets/pages/Index.ets b/FAQ/CryptoArchitectureKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/ets/pages/ObtainCertificateHashValue.ets b/FAQ/CryptoArchitectureKit/entry/src/main/ets/pages/ObtainCertificateHashValue.ets new file mode 100644 index 0000000000000000000000000000000000000000..a10df29cfe06e5de09dd4b68bc5e2ea360424f90 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/ets/pages/ObtainCertificateHashValue.ets @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取应用签名证书的hash值 +*/ + +// DocsCode 1 +import { bundleManager } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO; +try { + bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => { + hilog.info(0x0000, 'testTag', 'getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data)); + //data里可以获取到signatureInfo,即应用的签名证书信息 + }).catch((err: BusinessError) => { + hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message); + }); +} catch (err) { + let message = (err as BusinessError).message; + hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed: %{public}s', message); +} +// DocsCode 1 + +// DocsCode 2 +import { common } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { hash }from '@kit.CoreFileKit'; + +let context = UIContext.getHostContext()! as common.UIAbilityContext; +let pathDir = context.filesDir; + +let filePath = pathDir + "/test.txt"; +hash.hash(filePath, "sha256").then((str: string) => { + console.info("calculate file hash succeed:" + str); +}).catch((err: BusinessError) => { + console.error("calculate file hash failed with error message: " + err.message + ", error code: " + err.code); +}); +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/module.json5 b/FAQ/CryptoArchitectureKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/color.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/float.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/string.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/background.png b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/foreground.png b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..52582fb0e8493bf4abb8a35ce0d024caef056595 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,6 @@ +{ + "src": [ + "pages/Index", + "pages/ObtainCertificateHashValue" + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/main/resources/dark/element/color.json b/FAQ/CryptoArchitectureKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/mock/mock-config.json5 b/FAQ/CryptoArchitectureKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/CryptoArchitectureKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/CryptoArchitectureKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/ohosTest/module.json5 b/FAQ/CryptoArchitectureKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/CryptoArchitectureKit/entry/src/test/List.test.ets b/FAQ/CryptoArchitectureKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/entry/src/test/LocalUnit.test.ets b/FAQ/CryptoArchitectureKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/CryptoArchitectureKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/hvigor/hvigor-config.json5 b/FAQ/CryptoArchitectureKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/CryptoArchitectureKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/CryptoArchitectureKit/hvigorfile.ts b/FAQ/CryptoArchitectureKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/CryptoArchitectureKit/oh-package-lock.json5 b/FAQ/CryptoArchitectureKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/CryptoArchitectureKit/oh-package.json5 b/FAQ/CryptoArchitectureKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/CryptoArchitectureKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/ImageKit/.gitignore b/FAQ/ImageKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/ImageKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/ImageKit/AppScope/app.json5 b/FAQ/ImageKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..011f7775a219ab9718cd92f567806bc9304d62cf --- /dev/null +++ b/FAQ/ImageKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.imagekit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/ImageKit/AppScope/resources/base/element/string.json b/FAQ/ImageKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..234d8a0af60826869deb035bfe30047a3d63bffe --- /dev/null +++ b/FAQ/ImageKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "ImageKit" + } + ] +} diff --git a/FAQ/ImageKit/AppScope/resources/base/media/background.png b/FAQ/ImageKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ImageKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/ImageKit/AppScope/resources/base/media/foreground.png b/FAQ/ImageKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ImageKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/ImageKit/AppScope/resources/base/media/layered_image.json b/FAQ/ImageKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ImageKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/build-profile.json5 b/FAQ/ImageKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/ImageKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/code-linter.json5 b/FAQ/ImageKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/ImageKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/.gitignore b/FAQ/ImageKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/ImageKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/ImageKit/entry/build-profile.json5 b/FAQ/ImageKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/ImageKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/hvigorfile.ts b/FAQ/ImageKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/ImageKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ImageKit/entry/obfuscation-rules.txt b/FAQ/ImageKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/ImageKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/ImageKit/entry/oh-package.json5 b/FAQ/ImageKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/ImageKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/ImageKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/ImageKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/ImageKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/ConvertPixelMapToCvMatFormat.ets b/FAQ/ImageKit/entry/src/main/ets/pages/ConvertPixelMapToCvMatFormat.ets new file mode 100644 index 0000000000000000000000000000000000000000..a4b0b4b6803b9a7a747167d84b0bc3e169450d5d --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/ConvertPixelMapToCvMatFormat.ets @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将C++侧接收的PixelMap转换成cv::mat格式 + */ + +// DocsCode 1 +import cPixelMapToMat from 'libcpixelmaptomat.so'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { image } from '@kit.ImageKit'; + +@Entry +@Component +struct Index { + @State pixelMap: image.PixelMap | undefined = undefined + + async arrayBufferToMat() { + if (this.pixelMap == undefined || this.pixelMap){ + let resourceManager = this.getUIContext().getHostContext()!.resourceManager + let imageArray = await resourceManager.getMediaContent($r('app.media.sample10')); + let pixelBuffer = new Uint8Array(imageArray).buffer as Object as ArrayBuffer + console.info("pixelBuffer length: " + pixelBuffer.byteLength); + let imageResource = image.createImageSource(pixelBuffer); + let opts: image.DecodingOptions = { + editable: true, + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + } + this.pixelMap = await imageResource.createPixelMap(opts); + } + + const readBuffer: ArrayBuffer = new ArrayBuffer(this.pixelMap.getPixelBytesNumber()); // 获取pixelmap的arraybuffer + console.info("readBuffer length: " + readBuffer.byteLength); + this.pixelMap.readPixelsToBuffer(readBuffer).then(() => { + console.info("No Error!") + }).catch((err: BusinessError) => { + console.error("Error! " + err.message) + }) + const dir = this.getUIContext().getHostContext()!.filesDir; + console.info('save path: ' + dir); + cPixelMapToMat.arrayBufferToMat(this.pixelMap, readBuffer, dir); + } + + async accessToMat(){ + if (this.pixelMap == undefined || this.pixelMap) { + let resourceManager = this.getUIContext().getHostContext()!.resourceManager + let imageArray = await resourceManager.getMediaContent($r('app.media.sample14')); + let pixelBuffer = new Uint8Array(imageArray).buffer as Object as ArrayBuffer + console.info("pixelBuffer length: " + pixelBuffer.byteLength); + let imageResource = image.createImageSource(pixelBuffer); + let opts: image.DecodingOptions = { + editable: true, + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + } + this.pixelMap = await imageResource.createPixelMap(opts); + } + + const dir = this.getUIContext().getHostContext()!.filesDir; + console.info('save path: ' + dir); + cPixelMapToMat.accessToMat(this.pixelMap, dir); + } + + build() { + Row() { + Column() { + Image(this.pixelMap) + .width(200) + .height(200) + Button('ArrayBufferToMat') + .onClick(() => { + this.arrayBufferToMat(); + }) + + Button('AccessToMat') + .onClick(() => { + this.accessToMat(); + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 + +// DocsCode 2 +#include "napi/native_api.h" +#include +#include +#include +#include +#include "hilog/log.h" +#include +#include + + static napi_value ArrayBufferToMat(napi_env env, napi_callback_info info) { + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_value error; + napi_create_int32(env, -1, &error); + // 初始化PixelMap对象数据 + NativePixelMap *native = OH_PixelMap_InitNativePixelMap(env, args[0]); + if (native == nullptr) { + return error; + } + // 获取图片信息 + struct OhosPixelMapInfos pixelMapInfos; + if (OH_PixelMap_GetImageInfo(native, &pixelMapInfos) != IMAGE_RESULT_SUCCESS) { + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Test", "Pure : -1"); + return error; + } +// 获取buffer +napi_value buffer = args[1]; +napi_valuetype valueType; +napi_typeof(env, buffer, &valueType); +if (valueType == napi_object) { + bool isArrayBuffer = false; + napi_is_arraybuffer(env, buffer, &isArrayBuffer); + if (!isArrayBuffer) { + napi_throw_error(env, "EINVAL", "Error"); + } +} +void *data = nullptr; +size_t byteLength = 0; +napi_get_arraybuffer_info(env, buffer, &data, &byteLength); +int32_t *saveBuffer = (int32_t *)(data); +// 转换成Mat +cv::Mat originMat(pixelMapInfos.height, pixelMapInfos.width, CV_8UC4, saveBuffer); +if (!originMat.data) { + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Read Image", "Pure : -1"); + return error; +} +// opencv默认bgra或bgr,若pixelmap创建时未指定为这两种格式,需要进行格式转换 +cv::Mat saveMat; +cv::cvtColor(originMat, saveMat, cv::COLOR_BGRA2RGBA); +char pathArray[1024]; +size_t length; +napi_get_value_string_utf8(env, args[2], pathArray, 1024, &length); +std::string path(pathArray); +path += "/buffer.jpg"; +if (!cv::imwrite(path, saveMat)) { + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Write Image", "Pure : -1"); + return error; +} +napi_value res; +napi_create_int32(env, 1, &res); +return res; +} +// DocsCode 2 + +// DocsCode 3 +static napi_value AccessToMat(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + napi_value error; + napi_create_int32(env, -1, &error); + NativePixelMap *native = OH_PixelMap_InitNativePixelMap(env, args[0]); + if (native == nullptr) { + return error; + } + struct OhosPixelMapInfos pixelMapInfos; + if (OH_PixelMap_GetImageInfo(native, &pixelMapInfos) != IMAGE_RESULT_SUCCESS) { + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Test", "Pure : -1"); + return error; + } +void *pixel; +// 获取NativePixelMap对象的内存地址并锁定内存 +OH_PixelMap_AccessPixels(native, &pixel); +// 转换成Mat,注意对齐,所以要传入rowSize +cv::Mat originMat(pixelMapInfos.height, pixelMapInfos.width, CV_8UC4, pixel, pixelMapInfos.rowSize); +if (!originMat.data) { + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Read Image", "Pure : -1"); + return error; +} +// opencv默认bgra或bgr,若pixelmap创建时未指定为这两种格式,需要进行格式转换 +cv::Mat saveMat; +cv::cvtColor(originMat, saveMat, cv::COLOR_BGRA2RGBA); +char pathArray[1024]; +size_t length; +napi_get_value_string_utf8(env, args[1], pathArray, 1024, &length); +std::string path(pathArray); +path += "/access.jpg"; +if (!cv::imwrite(path, saveMat)) { + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Write Image", "Pure : -1"); + return error; +} +napi_value res; +napi_create_int32(env, 1, &res); +return res; +} +// DocsCode 3 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/Index.ets b/FAQ/ImageKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/NetworkImageSaveToAlbum.ets b/FAQ/ImageKit/entry/src/main/ets/pages/NetworkImageSaveToAlbum.ets new file mode 100644 index 0000000000000000000000000000000000000000..b5f28b41a186e5c59d3672ac751f7132a634e1cf --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/NetworkImageSaveToAlbum.ets @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何保存网络图片到相册 + */ + +// DocsCode 1 +import { http } from '@kit.NetworkKit'; +import { image } from '@kit.ImageKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { fileIo as fs } from '@kit.CoreFileKit'; + +@Entry +@Component +struct SaveImage { + @State pixelMap: PixelMap | undefined = undefined; + + loadImageWithUrl(url: string) { + let responseCode = http.ResponseCode; + let OutData: http.HttpResponse; + let imagePackerApi = image.createImagePacker(); + let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 }; + // 确保网络正常 + http.createHttp().request(url, { + method: http.RequestMethod.GET, + connectTimeout: 60000, + readTimeout: 60000 + }, + async (error: BusinessError, data: http.HttpResponse) => { + if (error) { + console.error(`http request failed with. Code: ${error.code}, message: ${error.message}`); + } else { + OutData = data; + let code: http.ResponseCode | number = OutData.responseCode; + if (responseCode.OK === code) { + let imageData: ArrayBuffer = OutData.result as ArrayBuffer; + let imageSource: image.ImageSource = image.createImageSource(imageData); + + class tmp { + height: number = 100 + width: number = 100 + }; + + let options: Record = { + 'alphaType': 0, // 透明度 + 'editable': false, // 是否可编辑 + 'pixelFormat': 3, // 像素格式 + 'scaleMode': 1, // 缩略值 + 'size': { height: 100, width: 100 } + }; // 创建图片大小 + imageSource.createPixelMap(options).then((pixelMap: PixelMap) => { + this.pixelMap = pixelMap; + this.pixelMap.getImageInfo().then((info: image.ImageInfo) => { + console.info('info.width = ' + info.size.width); + }).catch((err: BusinessError) => { + console.error('Failed ' + err); + }) + imagePackerApi.packing(pixelMap, packOpts).then(async (buffer: ArrayBuffer) => { + try { + const context = this.getUIContext().getHostContext()!; + let helper = photoAccessHelper.getPhotoAccessHelper(context); + let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png'); + let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // 写入文件 + await fs.write(file.fd, buffer); + this.getUIContext().getPromptAction().showToast({ message: '已保存至相册!' }); + // 关闭文件 + await fs.close(file.fd); + } catch (error) { + console.error('error is ' + JSON.stringify(error)); + } + }).catch((error: BusinessError) => { + console.error('Failed to pack the image. And the error is: ' + error); + }) + pixelMap.release(); + }) + } + } + } + ) + } + + build() { + Row() { + Column({ space: 10 }) { + Image('https://agc-storage-drcn.platform.dbankcloud.cn/v0/test-rqcjj/test.png') + .width('80%') + + SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { + if (result === SaveButtonOnClickResult.SUCCESS) { + this.loadImageWithUrl('https://agc-storage-drcn.platform.dbankcloud.cn/v0/test-rqcjj/test.png'); + } else { + this.getUIContext().getPromptAction().showToast({ message: '设置权限失败!' }); + } + }) + } + .width('100%') + } + .height('100%') + .backgroundColor(0xF1F3F5) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/PixelMapAndBase64ConverToEachOther.ets b/FAQ/ImageKit/entry/src/main/ets/pages/PixelMapAndBase64ConverToEachOther.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c31aa2c9776b1fd2fa131a62c39bc7f80224194 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/PixelMapAndBase64ConverToEachOther.ets @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现PixelMap和base64的相互转换 +*/ + +// DocsCode 1 +import { image } from '@kit.ImageKit'; +import { buffer } from '@kit.ArkTS'; + +@Entry +@Component +struct Index { + @State message: string = 'PixelMapToBase64'; + @State base64: string = ''; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(async () => { + let resourceManager = this.getUIContext().getHostContext()!.resourceManager + let imageArray = await resourceManager.getMediaContent($r('app.media.sample7')); + let pixelBuffer = new Uint8Array(imageArray).buffer as Object as ArrayBuffer; + let imageResource = image.createImageSource(pixelBuffer); + let opts: image.DecodingOptions = { editable: true } + let pixelMap = await imageResource.createPixelMap(opts); + + // 转换成base64 + const imagePackerApi: image.ImagePacker = image.createImagePacker(); + let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 100 }; + imagePackerApi.packToData(pixelMap, packOpts).then((data: ArrayBuffer) => { + let buf: buffer.Buffer = buffer.from(data); + this.base64 = 'data:image/jpeg;base64,' + buf.toString('base64', 0, buf.length); + console.info('base64: ' + this.base64); + }) + }) + Image(this.base64) + .width(200).height(200).margin(15) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 + +// DocsCode 2 +import CommonConstants from '../common/constants/CommonContants'; +import { util } from '@kit.ArkTS'; +import { image } from '@kit.ImageKit'; + +@Entry +@Component +struct Index { + @State message: string = 'Base64ToPixelMap'; + private base64: string = CommonConstants.Image_Base64_String; // 该变量为图片的base64格式字符串 + @State private pixelMap: PixelMap | null = null; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(async () => { + let helper = new util.Base64Helper(); + let buffer: ArrayBuffer = helper.decodeSync(this.base64, util.Type.MIME).buffer as ArrayBuffer; + let imageSource = image.createImageSource(buffer); + let opts: image.DecodingOptions = { editable: true }; + this.pixelMap = await imageSource.createPixelMap(opts); + }) + Image(this.pixelMap) + .width(200).height(200).margin(15) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/PixelMapSaveToAlbum.ets b/FAQ/ImageKit/entry/src/main/ets/pages/PixelMapSaveToAlbum.ets new file mode 100644 index 0000000000000000000000000000000000000000..752fe240f343462543d09c578e49725dcd5974d7 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/PixelMapSaveToAlbum.ets @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将PixelMap保存到相册 + */ + +// DocsCode 1 +import { resourceManager } from '@kit.LocalizationKit'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { image } from '@kit.ImageKit'; +import { fileIo } from '@kit.CoreFileKit'; + +@Entry +@Component +struct SavePixelMapToAlbum { + @State saveButtonOptions: SaveButtonOptions = { + icon: SaveIconStyle.FULL_FILLED, + text: SaveDescription.SAVE, + buttonType: ButtonType.Capsule + }; + @State pixel: image.PixelMap | undefined = undefined; + @State albumPath: string = ''; + @State photoSize: number = 0; + private context: Context = this.getUIContext().getHostContext()!; + + async aboutToAppear() { + const resourceMgr: resourceManager.ResourceManager = this.context.resourceManager; + // beer.jpeg为rawfile文件下的图片名,可根据自身需求修改使用。 + const fileData: Uint8Array = await resourceMgr.getRawFileContent('beer.jpeg'); + let buffer = new Uint8Array(fileData).buffer as object as ArrayBuffer; + let imageResource = image.createImageSource(buffer); + let opts: image.DecodingOptions = { editable: true }; + this.pixel = await imageResource.createPixelMap(opts); + } + + async savePixelMapToAlbum() { + // 获取相册的保存路径 + let helper = photoAccessHelper.getPhotoAccessHelper(this.context); + let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpeg'); + let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + let imagePackerApi = image.createImagePacker(); + let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 }; + + imagePackerApi.packToFile(this.pixel, file.fd, packOpts, (err: BusinessError) => { + if (err) { + console.error(`Failed to pack the image to file.code ${err.code},message is ${err.message}`); + } else { + console.info('Succeeded in packing the image to file.'); + imagePackerApi.release((err: BusinessError) => { + if (err) { + console.error(`Failed to release the image source instance.code ${err.code},message is ${err.message}`); + } else { + console.info('Succeeded in releasing the image source instance.'); + fileIo.close(file.fd); + } + }) + this.getUIContext().getPromptAction().showToast({ message: '已保存至相册!' }); + } + }) + } + + build() { + Row() { + Column() { + Image(this.pixel) + .objectFit(ImageFit.None) + .height('30%') + + SaveButton(this.saveButtonOptions) + .onClick(async (event, result: SaveButtonOnClickResult) => { + if (result === SaveButtonOnClickResult.SUCCESS) { + this.savePixelMapToAlbum(); + } + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/ResolveCreatePixelMapError.ets b/FAQ/ImageKit/entry/src/main/ets/pages/ResolveCreatePixelMapError.ets new file mode 100644 index 0000000000000000000000000000000000000000..75af7653d40dd3734da2b3f81d1576307ee88df2 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/ResolveCreatePixelMapError.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:调用imageSource.createPixelMap()报错"Create PixelMap error" + */ + +// DocsCode 1 +const file = fs.openSync(uri, fs.OpenMode.READ_ONLY); +const imageSource = image.createImageSource(file.fd); +const pixelMap = await imageSource.createPixelMap({sampleSize: 2, rotate: 0}); +// DocsCode 1 + +// DocsCode 2 +import { BusinessError } from '@kit.BasicServicesKit'; +import { image } from '@kit.ImageKit'; + +let decodingOptions: image.DecodingOptions = { + editable: true, + desiredPixelFormat: 3, + desiredSize: { width: 4, height: 6 } +} +const context: Context = this.getUIContext().getHostContext()!; +const filePath: string = context.cacheDir + '/test.jpg'; +const imageSource: image.ImageSource = image.createImageSource(filePath); +// 创建pixelMap并进行简单的旋转和缩放 +imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { + console.log("Succeeded in creating PixelMap") +}).catch((err: BusinessError) => { + console.error("Failed to create PixelMap") +}); +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/ResolveErrorCode62980096.ets b/FAQ/ImageKit/entry/src/main/ets/pages/ResolveErrorCode62980096.ets new file mode 100644 index 0000000000000000000000000000000000000000..ece1b7db0e119e3acdf89dcfc67cd540758aa48e --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/ResolveErrorCode62980096.ets @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:错误码62980096怎么处理 + */ + +// DocsCode 1 +import { image } from '@kit.ImageKit'; + +@Entry +@Component +struct Index { + @State message: string = 'NV21AndNV12ToPixelMap'; + @State private pixelMap: PixelMap | null = null; + @State private pixelMap2: PixelMap | null = null; + + build() { + Row() { + Column() { + Image(this.pixelMap) + .width(200).height(200).margin(15) + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(async () => { + let resourceManager = this.getUIContext().getHostContext()!.resourceManager + let imageArray = await resourceManager.getMediaContent($r("app.media.sample14_NV21_fromJPG_510X510")); + let pixelBuffer = new Uint8Array(imageArray).buffer as Object as ArrayBuffer; + // 其中sourcePixelFormat参数的值8对应NV21格式,9对应NV12格式;sourceSize参数需要设置宽高(原始yuv图片的宽高数据),且width值不能为奇数。 + let sourceOptions: image.SourceOptions = + { sourceDensity: 120, sourcePixelFormat: 8, sourceSize: { width: 510, height: 510 } }; + let imageResource = image.createImageSource(pixelBuffer, sourceOptions); + let opts: image.DecodingOptions = { editable: true } + this.pixelMap = await imageResource.createPixelMap(opts); + + let imageArray2 = await resourceManager.getMediaContent($r('app.media.sample10_NV12_fromJPG_510X510')); + let pixelBuffer2 = new Uint8Array(imageArray2).buffer as Object as ArrayBuffer; + // 其中sourcePixelFormat参数的值8对应NV21格式,9对应NV12格式;sourceSize参数需要设置宽高(原始yuv图片的宽高数据),且width值不能为奇数。 + let sourceOptions2: image.SourceOptions = + { sourceDensity: 120, sourcePixelFormat: 9, sourceSize: { width: 510, height: 510 } }; + let imageResource2 = image.createImageSource(pixelBuffer2, sourceOptions2); + let opts2: image.DecodingOptions = { editable: true } + this.pixelMap2 = await imageResource2.createPixelMap(opts2); + }) + Image(this.pixelMap2) + .width(200).height(200).margin(15) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/SaveVideoFrameDataLocally.ets b/FAQ/ImageKit/entry/src/main/ets/pages/SaveVideoFrameDataLocally.ets new file mode 100644 index 0000000000000000000000000000000000000000..a4f8c8edc473db19aff9e21942f308f997d709dc --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/SaveVideoFrameDataLocally.ets @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何把ImageReceiver收到的视频帧数据保存到本地 + */ + +// DocsCode 1 +let size: image.Size = { + width: 640, + height: 480 +} +let receiver: image.ImageReceiver = image.createImageReceiver(size, image.ImageFormat.JPEG, 8); +receiver.on('imageArrival', () => { + console.info("imageArrival callback"); + receiver.readNextImage((err: BusinessError, nextImage: image.Image) => { + if (err || nextImage === undefined) { + console.error("receiveImage -error:" + err + " nextImage:" + nextImage); + return; + } + nextImage.getComponent(image.ComponentType.JPEG, (err: BusinessError, imgComponent: image.Component) => { + if (err || imgComponent === undefined) { + console.error("receiveImage--getComponent -error:" + err + " imgComponent:" + imgComponent); + return; + } + + if (imgComponent.byteBuffer as ArrayBuffer) { + let sourceOptions: image.SourceOptions = { + sourceDensity: 120, + sourcePixelFormat: 8, + sourceSize: { + height: 1080, + width: 1920 + }, + } + let imageResource = image.createImageSource(imgComponent.byteBuffer, sourceOptions); + let imagePackerApi = image.createImagePacker(); + let packOpts: image.PackingOption = { format: "image/jpeg", quality: 90 }; + const filePath: string = this.getUIContext().getHostContext()!.cacheDir + "/image.jpg"; + let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); + imagePackerApi.packToFile(imageResource, file.fd, packOpts).then(() => { + console.error('pack success: ' + filePath); + }).catch((error: BusinessError) => { + console.error('Failed to pack the image. And the error is: ' + error); + }) + imageResource.createPixelMap({}).then((res) => { + this.imgUrl = res; + }); + } else { + return; + } + nextImage.release(); + }); + }); +}); +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets b/FAQ/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets new file mode 100644 index 0000000000000000000000000000000000000000..448ac95614a16df3ed66e3fae7581494228f01b2 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/SaveWebPictureToAlbum.ets @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何保存网络图片到相册 +*/ + +// DocsCode 1 +import { http } from '@kit.NetworkKit'; +import { image } from '@kit.ImageKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { promptAction } from '@kit.ArkUI'; +import { fileIo as fs } from '@kit.CoreFileKit'; + +@Entry +@Component +struct SaveImage { + @State pixelMap: PixelMap | undefined = undefined; + + loadImageWithUrl(url: string) { + let responseCode = http.ResponseCode; + let OutData: http.HttpResponse; + let imagePackerApi = image.createImagePacker(); + let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 }; + // 确保网络正常 + http.createHttp().request(url, { + method: http.RequestMethod.GET, + connectTimeout: 60000, + readTimeout: 60000 + }, + async (error: BusinessError, data: http.HttpResponse) => { + if (error) { + console.error(`http request failed with. Code: ${error.code}, message: ${error.message}`); + } else { + OutData = data; + let code: http.ResponseCode | number = OutData.responseCode; + if (responseCode.OK === code) { + let imageData: ArrayBuffer = OutData.result as ArrayBuffer; + let imageSource: image.ImageSource = image.createImageSource(imageData); + + class tmp { + height: number = 100 + width: number = 100 + }; + + let options: Record = { + 'alphaType': 0, // 透明度 + 'editable': false, // 是否可编辑 + 'pixelFormat': 3, // 像素格式 + 'scaleMode': 1, // 缩略值 + 'size': { height: 100, width: 100 } + }; // 创建图片大小 + imageSource.createPixelMap(options).then((pixelMap: PixelMap) => { + this.pixelMap = pixelMap; + this.pixelMap.getImageInfo().then((info: image.ImageInfo) => { + console.info('info.width = ' + info.size.width); + }).catch((err: BusinessError) => { + console.error('Failed ' + err); + }) + imagePackerApi.packToData(pixelMap, packOpts).then(async (buffer: ArrayBuffer) => { + try { + const context = this.getUIContext().getHostContext()!; + let helper = photoAccessHelper.getPhotoAccessHelper(context); + let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png'); + let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + // 写入文件 + await fs.write(file.fd, buffer); + promptAction.showToast({ message: '已保存至相册!' }); + // 关闭文件 + await fs.close(file.fd); + } catch (error) { + console.error('error is ' + JSON.stringify(error)); + } + }).catch((error: BusinessError) => { + console.error('Failed to pack the image. And the error is: ' + error); + }) + pixelMap.release(); + }) + } + } + } + ) + } + + build() { + Row() { + Column({ space: 10 }) { + Image('https://agc-storage-drcn.platform.dbankcloud.cn/v0/test-rqcjj/test.png') + .width('80%') + + SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { + if (result === SaveButtonOnClickResult.SUCCESS) { + this.loadImageWithUrl('https://agc-storage-drcn.platform.dbankcloud.cn/v0/test-rqcjj/test.png'); + } else { + promptAction.showToast({ message: '设置权限失败!' }); + } + }) + } + .width('100%') + } + .height('100%') + .backgroundColor(0xF1F3F5) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/ets/pages/SelectedAlbumPictureGeneratePixelMap.ets b/FAQ/ImageKit/entry/src/main/ets/pages/SelectedAlbumPictureGeneratePixelMap.ets new file mode 100644 index 0000000000000000000000000000000000000000..d963559a697acfc7fb8bd34ab5c1ab47a684b954 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/ets/pages/SelectedAlbumPictureGeneratePixelMap.ets @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将相册选择的图片生成PixelMap +*/ + +// DocsCode 1 +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { dataSharePredicates } from '@kit.ArkData'; +import { common } from '@kit.AbilityKit'; + +const context = UIContext.getHostContext() as common.UIAbilityContext; +@Entry +@Component +struct WebComponent { + build() { + Column() { + Button('选择图片').onClick(() => { + try { + let uris: Array = []; + let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; + PhotoSelectOptions.maxSelectNumber = 1; + let photoPicker = new photoAccessHelper.PhotoViewPicker(); + photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => { + console.info('photoPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult)); + uris = PhotoSelectResult.photoUris; + let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context); + let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); + // 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询 + predicates.equalTo('uri', uris[0]); + let fetchOptions: photoAccessHelper.FetchOptions = { + fetchColumns: [], + predicates: predicates + }; + phAccessHelper.getAssets(fetchOptions, async (err, fetchResult) => { + if (fetchResult !== undefined) { + console.info('fetchResult success'); + let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject(); + if (photoAsset !== undefined) { + // 获取缩略图 + photoAsset.getThumbnail((err, pixelMap) => { + if (err == undefined) { + console.info('getThumbnail successful ' + JSON.stringify(pixelMap)); + } else { + console.error('getThumbnail fail', err); + } + }); + console.info('photoAsset.displayName : ' + photoAsset.displayName); + } + } else { + console.error(`fetchResult fail with error: ${err.code}, ${err.message}`); + } + }); + }).catch((err: BusinessError) => { + console.error('photoPicker.select failed with err: ' + JSON.stringify(err)); + }); + } catch (error) { + let err: BusinessError = error as BusinessError; + console.error('photoPicker failed with err: ' + JSON.stringify(err)); + } + }) + } + } +} +// DocsCode 1 + +// DocsCode 2 +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { image } from '@kit.ImageKit'; +import { fileIo } from '@kit.CoreFileKit'; + +@Entry +@Component +struct WebComponent { + build() { + Column() { + Button('选择图片').onClick(() => { + try { + let uris: Array = []; + let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; + PhotoSelectOptions.maxSelectNumber = 1; + let photoPicker = new photoAccessHelper.PhotoViewPicker(); + photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => { + uris = PhotoSelectResult.photoUris; + let file = fileIo.openSync(uris[0], fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let buffer = new ArrayBuffer(4096); + let readLen = fileIo.readSync(file.fd, buffer); + console.info('readSync data to file succeed and buffer size is:' + readLen); + const imageSource: image.ImageSource = image.createImageSource(file.fd); + let decodingOptions: image.DecodingOptions = { + editable: true, + desiredPixelFormat: 3, + } + imageSource.createPixelMap(decodingOptions, (err: BusinessError, pixelMap: image.PixelMap) => { + if (err !== undefined) { + console.error(`Failed to create pixelMap.code is ${err.code},message is ${err.message}`); + } else { + console.info('Succeeded in creating pixelMap object.'); + } + }) + }).catch((err: BusinessError) => { + console.error(`Invoke photoPicker.select failed, code is ${err.code}, message is ${err.message}`); + }) + } catch (error) { + let err: BusinessError = error as BusinessError; + console.error('photoPicker failed with err: ' + JSON.stringify(err)); + } + }) + } + } +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/module.json5 b/FAQ/ImageKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/base/element/color.json b/FAQ/ImageKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/base/element/float.json b/FAQ/ImageKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/base/element/string.json b/FAQ/ImageKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/base/media/background.png b/FAQ/ImageKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/ImageKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/ImageKit/entry/src/main/resources/base/media/foreground.png b/FAQ/ImageKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/ImageKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/ImageKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/ImageKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/ImageKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/ImageKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/ImageKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/ImageKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/ImageKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..bf3989d6e57eeeb1cb5f8a619ba2f96183c3984f --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,12 @@ +{ + "src": [ + "pages/Index", + "pages/PixelMapAndBase64ConverToEachOther", + "pages/SaveWebPictureToAlbum", + "pages/SelectedAlbumPictureGeneratePixelMap", + "pages/ResolveCreatePixelMapError", + "pages/SaveVideoFrameDataLocally", + "pages/ResolveErrorCode62980096", + "pages/ConvertPixelMapToCvMatFormat" + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/main/resources/dark/element/color.json b/FAQ/ImageKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/ImageKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/mock/mock-config.json5 b/FAQ/ImageKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/ImageKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/ImageKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/ImageKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/ImageKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/ImageKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/ohosTest/module.json5 b/FAQ/ImageKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/ImageKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/ImageKit/entry/src/test/List.test.ets b/FAQ/ImageKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/ImageKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/ImageKit/entry/src/test/LocalUnit.test.ets b/FAQ/ImageKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/ImageKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/ImageKit/hvigor/hvigor-config.json5 b/FAQ/ImageKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/ImageKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/ImageKit/hvigorfile.ts b/FAQ/ImageKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/ImageKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/ImageKit/oh-package-lock.json5 b/FAQ/ImageKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/ImageKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/ImageKit/oh-package.json5 b/FAQ/ImageKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/ImageKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/InterfacePreviewKit/.gitignore b/FAQ/InterfacePreviewKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/InterfacePreviewKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/AppScope/app.json5 b/FAQ/InterfacePreviewKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bff7b7cdf416846e862f706a029efc9df7aa8ce1 --- /dev/null +++ b/FAQ/InterfacePreviewKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.interfacepreviewkit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/InterfacePreviewKit/AppScope/resources/base/element/string.json b/FAQ/InterfacePreviewKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..c0ce6ae156d14bf1778ca9a6dc1201928d44c6a0 --- /dev/null +++ b/FAQ/InterfacePreviewKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "InterfacePreviewKit" + } + ] +} diff --git a/FAQ/InterfacePreviewKit/AppScope/resources/base/media/background.png b/FAQ/InterfacePreviewKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/InterfacePreviewKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/InterfacePreviewKit/AppScope/resources/base/media/foreground.png b/FAQ/InterfacePreviewKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/InterfacePreviewKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/InterfacePreviewKit/AppScope/resources/base/media/layered_image.json b/FAQ/InterfacePreviewKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/InterfacePreviewKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/build-profile.json5 b/FAQ/InterfacePreviewKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/InterfacePreviewKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/code-linter.json5 b/FAQ/InterfacePreviewKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/InterfacePreviewKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/.gitignore b/FAQ/InterfacePreviewKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/build-profile.json5 b/FAQ/InterfacePreviewKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/hvigorfile.ts b/FAQ/InterfacePreviewKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/InterfacePreviewKit/entry/obfuscation-rules.txt b/FAQ/InterfacePreviewKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/oh-package.json5 b/FAQ/InterfacePreviewKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/InterfacePreviewKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/InterfacePreviewKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/InterfacePreviewKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/ets/pages/Index.ets b/FAQ/InterfacePreviewKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/ets/pages/InterfacePreviewNotInitialized.ets b/FAQ/InterfacePreviewKit/entry/src/main/ets/pages/InterfacePreviewNotInitialized.ets new file mode 100644 index 0000000000000000000000000000000000000000..25b6d7e5f9f6115c6dc8de17f550275be16fcdfd --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/ets/pages/InterfacePreviewNotInitialized.ets @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:预览告警“There are properties not initialized” +*/ + +// DocsCode 1 +"dependencies": { + // 版本号需根据hvigor及SDK的配套关系进行修改 + "@ohos/hamock": "1.0.0" +} +// DocsCode 1 + +// DocsCode 2 +import { MockSetup } from '@ohos/hamock'; +// DocsCode 2 + +// DocsCode 3 +@MockSetup +mock(){ + this.fruit = new Fruit("apple"); +} +// DocsCode 3 + +// DocsCode 4 +import { MockSetup } from '@ohos/hamock'; + +export default class Fruit{ + public name: string; + + getName(): string{ + return this.name; + } + + constructor(name: string) { + this.name = name; + } + +} +@Entry +@Component +struct GlobalData { + @State fruit:Fruit = AppStorage.get("fruit") as Fruit; + + @MockSetup + mock(){ + this.fruit = new Fruit("apple"); + } + + build() { + Row() { + Column() { + Text(this.fruit.name) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 4 + +// DocsCode 5 +@Entry +@Component +struct Page { + @State params: object = this.getUIContext().getRouter().getParams(); + + @MockSetup + mock(){ + this.params = []; + this.params["path"] = "path"; + } + + build() { + Row() { + Column() { + Text(this.params['path']) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 5 \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/module.json5 b/FAQ/InterfacePreviewKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/color.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/float.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/string.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/background.png b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/foreground.png b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/FAQ/InterfacePreviewKit/entry/src/main/resources/dark/element/color.json b/FAQ/InterfacePreviewKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/mock/mock-config.json5 b/FAQ/InterfacePreviewKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/InterfacePreviewKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/InterfacePreviewKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/ohosTest/module.json5 b/FAQ/InterfacePreviewKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/InterfacePreviewKit/entry/src/test/List.test.ets b/FAQ/InterfacePreviewKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/entry/src/test/LocalUnit.test.ets b/FAQ/InterfacePreviewKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/InterfacePreviewKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/hvigor/hvigor-config.json5 b/FAQ/InterfacePreviewKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/InterfacePreviewKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/InterfacePreviewKit/hvigorfile.ts b/FAQ/InterfacePreviewKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/InterfacePreviewKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/InterfacePreviewKit/oh-package-lock.json5 b/FAQ/InterfacePreviewKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/InterfacePreviewKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/InterfacePreviewKit/oh-package.json5 b/FAQ/InterfacePreviewKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/InterfacePreviewKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/LocalizationKit/.gitignore b/FAQ/LocalizationKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/LocalizationKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/LocalizationKit/AppScope/app.json5 b/FAQ/LocalizationKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3c3af19c34f7c9fc2cb4aea907e3a74c58f3dc8b --- /dev/null +++ b/FAQ/LocalizationKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.localizationkit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/LocalizationKit/AppScope/resources/base/element/string.json b/FAQ/LocalizationKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..285cce59ff555c36150ae79665743ffe38aaaa3a --- /dev/null +++ b/FAQ/LocalizationKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "LocalizationKit" + } + ] +} diff --git a/FAQ/LocalizationKit/AppScope/resources/base/media/background.png b/FAQ/LocalizationKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/LocalizationKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/LocalizationKit/AppScope/resources/base/media/foreground.png b/FAQ/LocalizationKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/LocalizationKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/LocalizationKit/AppScope/resources/base/media/layered_image.json b/FAQ/LocalizationKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/LocalizationKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/build-profile.json5 b/FAQ/LocalizationKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/LocalizationKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/code-linter.json5 b/FAQ/LocalizationKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/LocalizationKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/.gitignore b/FAQ/LocalizationKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/LocalizationKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/build-profile.json5 b/FAQ/LocalizationKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/LocalizationKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/hvigorfile.ts b/FAQ/LocalizationKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/LocalizationKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/LocalizationKit/entry/obfuscation-rules.txt b/FAQ/LocalizationKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/LocalizationKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/oh-package.json5 b/FAQ/LocalizationKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/LocalizationKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/LocalizationKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/LocalizationKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/LocalizationKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/ets/pages/ConvertAppIconToPixelMap.ets b/FAQ/LocalizationKit/entry/src/main/ets/pages/ConvertAppIconToPixelMap.ets new file mode 100644 index 0000000000000000000000000000000000000000..d2fb46528db2b488335abbef13684ddba08fd403 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/ets/pages/ConvertAppIconToPixelMap.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将app.media.app_icon,转换为PixelMap +*/ + +// DocsCode 1 +import { image } from '@kit.ImageKit'; + +@Entry +@Component +struct Index { + @State text: string = ''; + + convert() { + try { + // 媒体文件字节数组 + this.getUIContext().getHostContext()!.resourceManager.getMediaContent($r('app.media.startIcon').id, (error, value: ArrayBuffer) => { + let opts: image.InitializationOptions = { + editable: true, + pixelFormat: 3, + size: { height: 4, width: 6 } + }; + let uint8Array: Uint8Array = new Uint8Array(value); + let buffer: ArrayBuffer = uint8Array.buffer.slice(0); + + // 创建PixelMap + image.createPixelMap(buffer, opts).then((pixelMap) => { + // ... + this.text = JSON.stringify(pixelMap); + }) + }); + } catch (error) { + console.error(`callback getMediaContent failed, error code: ${error.code}, message: ${error.message}.`) + } + } + + build() { + Column() { + Button('点击转换') + .onClick(() => { + this.convert(); + }) + .margin({ bottom: 16 }) + TextArea({ text: this.text }) + } + .padding(16) + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/ets/pages/Index.ets b/FAQ/LocalizationKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/ets/pages/RawXmlFileToStringParser.ets b/FAQ/LocalizationKit/entry/src/main/ets/pages/RawXmlFileToStringParser.ets new file mode 100644 index 0000000000000000000000000000000000000000..9402569b28898b449d12b159eb2e5297f2e1ceff --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/ets/pages/RawXmlFileToStringParser.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何读取rawfile中的xml文件并转化为String类型 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { util } from '@kit.ArkTS'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; + +try { + context.getHostContext()!.resourceManager.getRawFileContent('test.xml', (error, value) => { + if (error != null) { + console.log('error is ' + error); + } else { + let rawFile = value; + let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true }); + let rawFileString = textDecoder.decodeToString( rawFile , {stream: false}); + } + }); +} catch (error) { + let code = (error as BusinessError).code; + let message = (error as BusinessError).message; + console.error(`callback getRawFileContent failed, error code: ${code}, message: ${message}.`); +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/module.json5 b/FAQ/LocalizationKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/element/color.json b/FAQ/LocalizationKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/element/float.json b/FAQ/LocalizationKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/element/string.json b/FAQ/LocalizationKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/media/background.png b/FAQ/LocalizationKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/LocalizationKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/media/foreground.png b/FAQ/LocalizationKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/LocalizationKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/LocalizationKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/LocalizationKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/LocalizationKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/LocalizationKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/LocalizationKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/FAQ/LocalizationKit/entry/src/main/resources/dark/element/color.json b/FAQ/LocalizationKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/mock/mock-config.json5 b/FAQ/LocalizationKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/LocalizationKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/LocalizationKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/ohosTest/module.json5 b/FAQ/LocalizationKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/LocalizationKit/entry/src/test/List.test.ets b/FAQ/LocalizationKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/entry/src/test/LocalUnit.test.ets b/FAQ/LocalizationKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/LocalizationKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/hvigor/hvigor-config.json5 b/FAQ/LocalizationKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/LocalizationKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/LocalizationKit/hvigorfile.ts b/FAQ/LocalizationKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/LocalizationKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/LocalizationKit/oh-package-lock.json5 b/FAQ/LocalizationKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c6f99f5c73b06c5fdef7ec6f491b74b7befebe2e --- /dev/null +++ b/FAQ/LocalizationKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/LocalizationKit/oh-package.json5 b/FAQ/LocalizationKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/LocalizationKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/LocationKit/.gitignore b/FAQ/LocationKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/LocationKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/LocationKit/AppScope/app.json5 b/FAQ/LocationKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e7dd0caefbe0660bf0472d2deec0885689e8b2c7 --- /dev/null +++ b/FAQ/LocationKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.locationkit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/LocationKit/AppScope/resources/base/element/string.json b/FAQ/LocationKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..d4ab77e7666f2066b3bd1604978e147538f64780 --- /dev/null +++ b/FAQ/LocationKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "LocationKit" + } + ] +} diff --git a/FAQ/LocationKit/AppScope/resources/base/media/background.png b/FAQ/LocationKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/LocationKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/LocationKit/AppScope/resources/base/media/foreground.png b/FAQ/LocationKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/LocationKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/LocationKit/AppScope/resources/base/media/layered_image.json b/FAQ/LocationKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/LocationKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/build-profile.json5 b/FAQ/LocationKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/LocationKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/code-linter.json5 b/FAQ/LocationKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/LocationKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/.gitignore b/FAQ/LocationKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/LocationKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/LocationKit/entry/build-profile.json5 b/FAQ/LocationKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/LocationKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/hvigorfile.ts b/FAQ/LocationKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/LocationKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/LocationKit/entry/obfuscation-rules.txt b/FAQ/LocationKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/LocationKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/LocationKit/entry/oh-package.json5 b/FAQ/LocationKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/LocationKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/LocationKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/LocationKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/LocationKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/ets/pages/ApplyPrecisePositioning.ets b/FAQ/LocationKit/entry/src/main/ets/pages/ApplyPrecisePositioning.ets new file mode 100644 index 0000000000000000000000000000000000000000..4b91243305a0b3001a991a28760baa462d910bbd --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/ets/pages/ApplyPrecisePositioning.ets @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何申请精确定位 + */ + +// DocsCode 1 +import { abilityAccessCtrl, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Component +export struct ApplyPrecisePositioning { + permissions: Array = ['ohos.permission.APPROXIMATELY_LOCATION', 'ohos.permission.LOCATION']; + + aboutToAppear(): void { + this.reqPermissionsFromUser(this.permissions); + } + + reqPermissionsFromUser(permissions: Array): void { + let context: Context = getContext(this) as common.UIAbilityContext; + let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); + // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 + atManager.requestPermissionsFromUser(context, permissions).then((data: PermissionRequestResult) => { + let grantStatus: Array = data.authResults; + let length: number = grantStatus.length; + for (let i = 0; i < length; i++) { + if (grantStatus[i] === 0) { + // 用户授权,可以继续访问目标操作 + } else { + // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限 + this.getUIContext().getPromptAction().showToast({ message: '用户拒绝授权' }); + return; + } + } + // 授权成功 + }).catch((err: BusinessError) => { + console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); + }) + } + + build() { + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/ets/pages/Index.ets b/FAQ/LocationKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/module.json5 b/FAQ/LocationKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/base/element/color.json b/FAQ/LocationKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/base/element/float.json b/FAQ/LocationKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/base/element/string.json b/FAQ/LocationKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/base/media/background.png b/FAQ/LocationKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/LocationKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/LocationKit/entry/src/main/resources/base/media/foreground.png b/FAQ/LocationKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/LocationKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/LocationKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/LocationKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/LocationKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/LocationKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/LocationKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/LocationKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/LocationKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..55c3f007f87b7ce5206d325f968cc56f2f79441f --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/main/resources/dark/element/color.json b/FAQ/LocationKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/LocationKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/mock/mock-config.json5 b/FAQ/LocationKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/LocationKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/LocationKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/LocationKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/LocationKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/LocationKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/ohosTest/module.json5 b/FAQ/LocationKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/LocationKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/LocationKit/entry/src/test/List.test.ets b/FAQ/LocationKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/LocationKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/LocationKit/entry/src/test/LocalUnit.test.ets b/FAQ/LocationKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/LocationKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/LocationKit/hvigor/hvigor-config.json5 b/FAQ/LocationKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/LocationKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/LocationKit/hvigorfile.ts b/FAQ/LocationKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/LocationKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/LocationKit/oh-package-lock.json5 b/FAQ/LocationKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/LocationKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/LocationKit/oh-package.json5 b/FAQ/LocationKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/LocationKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/MediaLibraryKit/.gitignore b/FAQ/MediaLibraryKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/MediaLibraryKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/AppScope/app.json5 b/FAQ/MediaLibraryKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b9f2503416e682c335fefc5ef3f1101429cdbd1f --- /dev/null +++ b/FAQ/MediaLibraryKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.medialibrarykit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/MediaLibraryKit/AppScope/resources/base/element/string.json b/FAQ/MediaLibraryKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..fdb684dff01a0586162b2cb747a5ad5f21c08021 --- /dev/null +++ b/FAQ/MediaLibraryKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "MediaLibraryKit" + } + ] +} diff --git a/FAQ/MediaLibraryKit/AppScope/resources/base/media/background.png b/FAQ/MediaLibraryKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/MediaLibraryKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/MediaLibraryKit/AppScope/resources/base/media/foreground.png b/FAQ/MediaLibraryKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/MediaLibraryKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/MediaLibraryKit/AppScope/resources/base/media/layered_image.json b/FAQ/MediaLibraryKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/MediaLibraryKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/build-profile.json5 b/FAQ/MediaLibraryKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/MediaLibraryKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/code-linter.json5 b/FAQ/MediaLibraryKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/MediaLibraryKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/.gitignore b/FAQ/MediaLibraryKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/build-profile.json5 b/FAQ/MediaLibraryKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/hvigorfile.ts b/FAQ/MediaLibraryKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/MediaLibraryKit/entry/obfuscation-rules.txt b/FAQ/MediaLibraryKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/oh-package.json5 b/FAQ/MediaLibraryKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/pages/Base64ImageConverter.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/Base64ImageConverter.ets new file mode 100644 index 0000000000000000000000000000000000000000..4baaa6bba847d27aace422e077ff9b62e205142c --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/Base64ImageConverter.ets @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:base64字符串如何转为图片并保存 +*/ + +// DocsCode 1 +import { buffer } from '@kit.ArkTS'; +import { fileIo } from '@kit.CoreFileKit'; +import { common } from '@kit.AbilityKit'; +import { fileUri } from "@kit.CoreFileKit"; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +let filesDir = context.getHostContext()!.filesDir; + +// data为需要转换的base64字符串,返回沙箱路径uri +export async function writeFile(data: string): Promise { + let uri = '' + try { + let filePath = filesDir + "/1.png"; + uri = fileUri.getUriFromPath(filePath); + let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + console.info("file fd: " + file.fd); + const reg = new RegExp("data:image/\\w+;base64,") + const base64 = data.replace(reg, ""); + console.log("base64flag", base64) + const dataBuffer = buffer.from(base64, 'base64') + let writeLen = fileIo.writeSync(file.fd, dataBuffer.buffer); + hilog.info(0xA0c0d0,'uri',uri) + fileIo.closeSync(file); + } + catch (Error) { + hilog.error(0xA0c0d0,'Error',Error.code) + } + return uri; +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/pages/ImageImportIssues.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/ImageImportIssues.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a8e1279b9b33c33e6728120b27ae0ce17cd43a6 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/ImageImportIssues.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:关于导入图片的使用权限和问题 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { fileIo } from '@kit.CoreFileKit'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; + +// 工具类中:在EntryAbility中获取Context后保存至AppStorage,然后在工具类中使用AppStorage获取 +let context = AppStorage.get("context") as UIContext; +let filesDir = context.getHostContext()!.filesDir; +function SavePictureToContext(){ + const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE + photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目 + let uris: Array = []; + const photoViewPicker = new photoAccessHelper.PhotoViewPicker(); + photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => { + uris = photoSelectResult.photoUris; + console.info('photoViewPicker.select to file succeed and uris are:' + uris); + }).catch((err: BusinessError) => { + console.error('Invoke photoViewPicker.select failed, code is'+ err.code+', message is '+err.message); + }) + let uri: string = uris[0]; + let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let fd =file.fd; + fileIo.copyFileSync(fd, filesDir + '/test2.jpg') + let file2 = fileIo.openSync(filesDir + '/test2.jpg', fileIo.OpenMode.READ_ONLY ); + let file3 = fileIo.openSync(filesDir + '/test3.jpg', fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + // 将fd传入后,C端即可进行调用 + // ReadFile(file2.fd,file3.fd) +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/pages/ImportedImagesPermissionsAndIssues.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/ImportedImagesPermissionsAndIssues.ets new file mode 100644 index 0000000000000000000000000000000000000000..75ebf704d93c1590d26b8231cfcf1b451ac7cabe --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/ImportedImagesPermissionsAndIssues.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:关于导入图片的使用权限和问题 +*/ + +// DocsCode 1 +import { BusinessError } from '@kit.BasicServicesKit'; +import { fileIo } from '@kit.CoreFileKit'; +import { common } from '@kit.AbilityKit'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; + +let context = getContext(this) as common.UIAbilityContext; +let filesDir = context.filesDir; +function SavePictureToContext(){ + const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE + photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目 + let uris: Array = []; + const photoViewPicker = new photoAccessHelper.PhotoViewPicker(); + photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => { + uris = photoSelectResult.photoUris; + console.info('photoViewPicker.select to file succeed and uris are:' + uris); + }).catch((err: BusinessError) => { + console.error('Invoke photoViewPicker.select failed, code is'+ err.code+', message is '+err.message); + }) + let uri: string = uris[0]; + let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let fd =file.fd; + fileIo.copyFileSync(fd, filesDir + '/test2.jpg') + let file2 = fileIo.openSync(filesDir + '/test2.jpg', fileIo.OpenMode.READ_ONLY ); + let file3 = fileIo.openSync(filesDir + '/test3.jpg', fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + // 将fd传入后,C端即可进行调用 + // ReadFile(file2.fd,file3.fd) +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/pages/Index.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/ets/pages/SelectFileSavePath.ets b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/SelectFileSavePath.ets new file mode 100644 index 0000000000000000000000000000000000000000..255a7546c1f32f2f228b9c4766d483c4d815fc73 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/ets/pages/SelectFileSavePath.ets @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何选择文件保存路径 + */ + +// DocsCode 1 +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { fileIo } from '@kit.CoreFileKit'; + +@Entry +@Component +struct WebComponent { + build() { + Row() { + Column() { + Image($r('app.media.startIcon')) + .height(200) + .width(200) + SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { + if (result === SaveButtonOnClickResult.SUCCESS) { + try { + const context = this.getUIContext().getHostContext(); + let helper = photoAccessHelper.getPhotoAccessHelper(context); + // onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回。 + let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); + // 使用uri打开文件,可以持续写入内容,写入过程不受时间限制 + let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + try { + context.resourceManager.getMediaContent($r('app.media.startIcon').id, 0) + .then(async value => { + let media = value.buffer; + // 写到媒体库文件中 + await fileIo.write(file.fd, media); + await fileIo.close(file.fd); + this.getUIContext().showAlertDialog({ message: '已保存至相册!' }); + }); + } catch (err) { + console.error('error is ' + JSON.stringify(err)) + } + } catch (error) { + console.error('error is ' + JSON.stringify(error)); + } + } else { + this.getUIContext().showAlertDialog({ message: '设置权限失败' }) + } + }) + } + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/module.json5 b/FAQ/MediaLibraryKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/color.json b/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/float.json b/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/string.json b/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/background.png b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/foreground.png b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/MediaLibraryKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/MediaLibraryKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/MediaLibraryKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..d798da48122b66adbec51d80c0220172e0c6b27b --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,6 @@ +{ + "src": [ + "pages/Index", + "pages/ImportedImagesPermissionsAndIssues" + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/main/resources/dark/element/color.json b/FAQ/MediaLibraryKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/mock/mock-config.json5 b/FAQ/MediaLibraryKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/MediaLibraryKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/MediaLibraryKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/ohosTest/module.json5 b/FAQ/MediaLibraryKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/MediaLibraryKit/entry/src/test/List.test.ets b/FAQ/MediaLibraryKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/entry/src/test/LocalUnit.test.ets b/FAQ/MediaLibraryKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/MediaLibraryKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/hvigor/hvigor-config.json5 b/FAQ/MediaLibraryKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/MediaLibraryKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/MediaLibraryKit/hvigorfile.ts b/FAQ/MediaLibraryKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/MediaLibraryKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/MediaLibraryKit/oh-package-lock.json5 b/FAQ/MediaLibraryKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/MediaLibraryKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/MediaLibraryKit/oh-package.json5 b/FAQ/MediaLibraryKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/MediaLibraryKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/NdkDevelopment/.gitignore b/FAQ/NdkDevelopment/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/NdkDevelopment/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/NdkDevelopment/AppScope/app.json5 b/FAQ/NdkDevelopment/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9ff755fb5c90085d615f1175a502bd066cc023b7 --- /dev/null +++ b/FAQ/NdkDevelopment/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.ndkdevelopment", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/NdkDevelopment/AppScope/resources/base/element/string.json b/FAQ/NdkDevelopment/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1a57d87c7d352e41ace1d91dd8321fbe9926612b --- /dev/null +++ b/FAQ/NdkDevelopment/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "NdkDevelopment" + } + ] +} diff --git a/FAQ/NdkDevelopment/AppScope/resources/base/media/background.png b/FAQ/NdkDevelopment/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/NdkDevelopment/AppScope/resources/base/media/background.png differ diff --git a/FAQ/NdkDevelopment/AppScope/resources/base/media/foreground.png b/FAQ/NdkDevelopment/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/NdkDevelopment/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/NdkDevelopment/AppScope/resources/base/media/layered_image.json b/FAQ/NdkDevelopment/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/NdkDevelopment/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/build-profile.json5 b/FAQ/NdkDevelopment/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/NdkDevelopment/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/code-linter.json5 b/FAQ/NdkDevelopment/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/NdkDevelopment/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/.gitignore b/FAQ/NdkDevelopment/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/build-profile.json5 b/FAQ/NdkDevelopment/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/hvigorfile.ts b/FAQ/NdkDevelopment/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/NdkDevelopment/entry/obfuscation-rules.txt b/FAQ/NdkDevelopment/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/NdkDevelopment/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/oh-package.json5 b/FAQ/NdkDevelopment/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/NdkDevelopment/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/NdkDevelopment/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/NdkDevelopment/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/NdkDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/ets/pages/AsyncMethodForArkTSFromNative.ets b/FAQ/NdkDevelopment/entry/src/main/ets/pages/AsyncMethodForArkTSFromNative.ets new file mode 100644 index 0000000000000000000000000000000000000000..7e14d659de0de8d981ffc18280ced754b51f28b6 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/ets/pages/AsyncMethodForArkTSFromNative.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Native侧如何访问ArkTS侧系统定义的异步方法 + */ + +// DocsCode 3 +import testNapi from 'libcallsystemasyncwork.so'; + +@Entry +@Component +struct Index { + build() { + Row() { + Column() { + Text('c++异步调用ts') + .fontSize(40) + .fontWeight(FontWeight.Bold) + .onClick(() => { + testNapi.getDisplayWidthAsync().then((res: number) =>{ + console.info(`display width = ${res.toString()}`); + this.getUIContext().getPromptAction().showToast({ + message: "屏幕宽度:" + res.toString() + }) + }); + }) + .margin('30') + } + .width('100%') + .justifyContent(FlexAlign.SpaceBetween) + } + .height('100%') + } +} +// DocsCode 3 \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/ets/pages/CSideOpenFile.ets b/FAQ/NdkDevelopment/entry/src/main/ets/pages/CSideOpenFile.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d9791448e9fa2773a5222a1ee2ff7e680e51e76 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/ets/pages/CSideOpenFile.ets @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:C侧如何打开文件 +*/ + +// DocsCode 1 +import { fileIo, picker } from '@kit.CoreFileKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import testNapi from 'libentry.so'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; + +@Entry +@Component +struct Index { + @State message: string = '打开文件'; + + async open() { + const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE + photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目 + let uris: Array = []; + const photoViewPicker = new photoAccessHelper.PhotoViewPicker(); + await photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => { + uris = photoSelectResult.photoUris; + console.info('photoViewPicker.select to file succeed and uris are:' + uris); + }).catch((err: BusinessError) => { + console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`); + }) + let uri: string = uris[0]; + let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let fd = file.fd + let filesDir = getContext(this).filesDir; + fileIo.copyFileSync(fd, filesDir + '/test2.jpg') + let file2 = fileIo.openSync(filesDir + '/test2.jpg', fileIo.OpenMode.READ_ONLY); + let file3 = fileIo.openSync(filesDir + '/test3.jpg', fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); + testNapi.ReadFile(file2.fd, file3.fd) + } + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .onClick(() => { + this.open(); + }) + .width('100%') + } + .height('100%') + } +} +// DocsCode 1 + +// DocsCode 2 +static napi_value OpenFile(unsigned int fd, unsigned int fd2) { + OH_LOG_INFO(LOG_APP, "OpenFile"); + + if (fd != -1) { + char buffer[4096]; + ssize_t bytesRead; + // 读取文件内容到缓冲区中 + bytesRead = read(fd, buffer, sizeof(buffer)); + if (bytesRead == -1) { + OH_LOG_INFO(LOG_APP, "读取文件失败"); + close(fd); // 关闭文件描述符 + return nullptr; + } + while (bytesRead != 0) { + OH_LOG_INFO(LOG_APP, "读取文件大小 %{public}lu", bytesRead); + OH_LOG_INFO(LOG_APP, "读取文件cg"); + char *pData1 = buffer; + OH_LOG_INFO(LOG_APP, "文件内容: \n%{public}s", pData1); + ssize_t bytesWrite; + bytesWrite = write(fd2, pData1, bytesRead); + if (bytesWrite == -1) { + OH_LOG_INFO(LOG_APP, "写文件失败"); + close(fd2); // 关闭文件描述符 + return nullptr; + } + bytesRead = read(fd, buffer, sizeof(buffer)); + } + // 关闭文件描述符 + close(fd); + close(fd2); // 关闭文件描述符 + } + return nullptr; +} +static napi_value ReadFile(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + unsigned int fd = -1; + napi_get_value_uint32(env, args[0], &fd); + unsigned int fd2 = -1; + napi_get_value_uint32(env, args[1], &fd2); + OpenFile(fd, fd2); + return nullptr; +} +// DocsCode 2 \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/ets/pages/GetObjectForArkTSFromNative.ets b/FAQ/NdkDevelopment/entry/src/main/ets/pages/GetObjectForArkTSFromNative.ets new file mode 100644 index 0000000000000000000000000000000000000000..26bf0ef2d6578924906ca795872a47a3d66f78cb --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/ets/pages/GetObjectForArkTSFromNative.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Native侧如何获取ArkTS侧Object对象及其成员变量 + */ + +// DocsCode 1 +// index.ets +import testNapi from 'libentry.so'; + +class A { + name:string ='username' + onCall() { + this.getUIContext().getPromptAction().showToast({ + message:'Message Info', + duration:2000 + }); + console.log("testTag user onCall"); + } +} +build() { + ... + .onClick(() => { + testNapi.callFunction(new A()); + }) +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/ets/pages/Index.ets b/FAQ/NdkDevelopment/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/module.json5 b/FAQ/NdkDevelopment/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/element/color.json b/FAQ/NdkDevelopment/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/element/float.json b/FAQ/NdkDevelopment/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/element/string.json b/FAQ/NdkDevelopment/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/media/background.png b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/media/foreground.png b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/media/layered_image.json b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/media/startIcon.png b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/NdkDevelopment/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/profile/backup_config.json b/FAQ/NdkDevelopment/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/base/profile/main_pages.json b/FAQ/NdkDevelopment/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..09ab5f84a5d6aa6153214fa2a404752f172a10f3 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,6 @@ +{ + "src": [ + "pages/Index", + "pages/CSideOpenFile" + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/main/resources/dark/element/color.json b/FAQ/NdkDevelopment/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/mock/mock-config.json5 b/FAQ/NdkDevelopment/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/NdkDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/NdkDevelopment/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/ohosTest/module.json5 b/FAQ/NdkDevelopment/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/NdkDevelopment/entry/src/test/List.test.ets b/FAQ/NdkDevelopment/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/entry/src/test/LocalUnit.test.ets b/FAQ/NdkDevelopment/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/NdkDevelopment/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/hvigor/hvigor-config.json5 b/FAQ/NdkDevelopment/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/NdkDevelopment/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/NdkDevelopment/hvigorfile.ts b/FAQ/NdkDevelopment/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/NdkDevelopment/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/NdkDevelopment/oh-package-lock.json5 b/FAQ/NdkDevelopment/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/NdkDevelopment/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/NdkDevelopment/oh-package.json5 b/FAQ/NdkDevelopment/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/NdkDevelopment/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/FAQ/PackageStructureKit/.gitignore b/FAQ/PackageStructureKit/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/FAQ/PackageStructureKit/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/FAQ/PackageStructureKit/AppScope/app.json5 b/FAQ/PackageStructureKit/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2c14f23c4da55fb768138172ca684b047de475b6 --- /dev/null +++ b/FAQ/PackageStructureKit/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.packagestructurekit", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/FAQ/PackageStructureKit/AppScope/resources/base/element/string.json b/FAQ/PackageStructureKit/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..e305dae8d3cde6ef95aa4121325ba593446c3879 --- /dev/null +++ b/FAQ/PackageStructureKit/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "PackageStructureKit" + } + ] +} diff --git a/FAQ/PackageStructureKit/AppScope/resources/base/media/background.png b/FAQ/PackageStructureKit/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/PackageStructureKit/AppScope/resources/base/media/background.png differ diff --git a/FAQ/PackageStructureKit/AppScope/resources/base/media/foreground.png b/FAQ/PackageStructureKit/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/PackageStructureKit/AppScope/resources/base/media/foreground.png differ diff --git a/FAQ/PackageStructureKit/AppScope/resources/base/media/layered_image.json b/FAQ/PackageStructureKit/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/PackageStructureKit/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/build-profile.json5 b/FAQ/PackageStructureKit/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..03ac3a3ae9dd397844173066e5d5ee21b49455a1 --- /dev/null +++ b/FAQ/PackageStructureKit/build-profile.json5 @@ -0,0 +1,41 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/code-linter.json5 b/FAQ/PackageStructureKit/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/FAQ/PackageStructureKit/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/.gitignore b/FAQ/PackageStructureKit/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/build-profile.json5 b/FAQ/PackageStructureKit/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/hvigorfile.ts b/FAQ/PackageStructureKit/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/PackageStructureKit/entry/obfuscation-rules.txt b/FAQ/PackageStructureKit/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/FAQ/PackageStructureKit/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/oh-package.json5 b/FAQ/PackageStructureKit/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/FAQ/PackageStructureKit/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/FAQ/PackageStructureKit/entry/src/main/ets/entryability/EntryAbility.ets b/FAQ/PackageStructureKit/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/FAQ/PackageStructureKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/ets/pages/CrossModulePageJump.ets b/FAQ/PackageStructureKit/entry/src/main/ets/pages/CrossModulePageJump.ets new file mode 100644 index 0000000000000000000000000000000000000000..81fa65b6df74e4d37cdb9793c55a3a3c036e9d14 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/ets/pages/CrossModulePageJump.ets @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现跨模块的页面跳转功能 +*/ + +// DocsCode 1 +@Component +export struct LoginPage { + @Consume('pathStack') pathStack: NavPathStack; + @State message: string = 'Login Page'; + + build() { + NavDestination() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + .height('100%') + } + .onBackPressed(() => { + this.pathStack.pop(); + return true; + }) + } +} +// DocsCode 1 + +// DocsCode 2 +{ + // ... + "dependencies": { + "@ohos/login": "file:../login" + } +} +// DocsCode 2 + +// DocsCode 3 +// 导入Login模块自定义组件 +import { LoginPage } from '@ohos/login'; + +@Entry +@Component +struct NavigationPage { + @Provide('pathStack') pathStack: NavPathStack = new NavPathStack(); + + @Builder + pageMap(name: string) { + if (name === 'loginPage') { + LoginPage() + } + } + + build() { + Navigation(this.pathStack) { + Button('jump to login page') + .onClick(() => { + // NavPathInfo第二个参数为自定义参数,可用于信息传递 + let pathInfo: NavPathInfo = new NavPathInfo('loginPage', new Object()); + this.pathStack.pushDestination(pathInfo, true); + }) + } + .navDestination(this.pageMap) + } +} +// DocsCode 3 \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/ets/pages/ErrorInObtainingHSPFile.ets b/FAQ/PackageStructureKit/entry/src/main/ets/pages/ErrorInObtainingHSPFile.ets new file mode 100644 index 0000000000000000000000000000000000000000..214bf8cae0085558d8a4baf36f07b7ace49711d9 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/ets/pages/ErrorInObtainingHSPFile.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:通过resourceManager.getStringResource接口获取HSP资源文件报“Resource id invalid”错误 + */ + +// DocsCode 1 +import { common, application } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { JSON } from '@kit.ArkTS'; + +@Entry +@Component +struct Index { + private context = UIContext.getHostContext() as common.UIAbilityContext; + + build() { + Column() { + Button() + .onClick(() => { + // 根据模块名创建上下文Context + let moduleName: string = 'library'; + application.createModuleContext(this.context, moduleName) + .then((data: common.Context) => { + console.info(`CreateModuleContext success, data: ${JSON.stringify(data)}`); + if (data !== null) { + this.getUIContext().getPromptAction().showToast({ + message: ('成功获取Context') + }); + } + + // 然后通过getStringByNameSync获取指定资源名称对应的字符串 + try { + let str = data.resourceManager.getStringByNameSync('shared_desc'); + console.info(`getStringByNameSync, data: ${JSON.stringify(str)}`); + } catch (error) { + let code = (error as BusinessError).code; + let message = (error as BusinessError).message; + console.error(`getStringByNameSync failed, error code: ${code}, message: ${message}.`); + } + }) + .catch((err: BusinessError) => { + console.error(`CreateModuleContext failed, err code:${err.code}, err msg: ${err.message}`); + }); + }) + } + } +} +// DocsCode 1 \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/ets/pages/Index.ets b/FAQ/PackageStructureKit/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/module.json5 b/FAQ/PackageStructureKit/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/element/color.json b/FAQ/PackageStructureKit/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/element/float.json b/FAQ/PackageStructureKit/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/element/string.json b/FAQ/PackageStructureKit/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/media/background.png b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/background.png differ diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/media/foreground.png b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/foreground.png differ diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/media/layered_image.json b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/media/startIcon.png b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/FAQ/PackageStructureKit/entry/src/main/resources/base/media/startIcon.png differ diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/profile/backup_config.json b/FAQ/PackageStructureKit/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/base/profile/main_pages.json b/FAQ/PackageStructureKit/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/FAQ/PackageStructureKit/entry/src/main/resources/dark/element/color.json b/FAQ/PackageStructureKit/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/mock/mock-config.json5 b/FAQ/PackageStructureKit/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/ohosTest/ets/test/Ability.test.ets b/FAQ/PackageStructureKit/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/ohosTest/ets/test/List.test.ets b/FAQ/PackageStructureKit/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/ohosTest/module.json5 b/FAQ/PackageStructureKit/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/FAQ/PackageStructureKit/entry/src/test/List.test.ets b/FAQ/PackageStructureKit/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/entry/src/test/LocalUnit.test.ets b/FAQ/PackageStructureKit/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/FAQ/PackageStructureKit/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/hvigor/hvigor-config.json5 b/FAQ/PackageStructureKit/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a63d34ae5ce5833b3874807e2b8d472687c6c5bf --- /dev/null +++ b/FAQ/PackageStructureKit/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.4", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/FAQ/PackageStructureKit/hvigorfile.ts b/FAQ/PackageStructureKit/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/FAQ/PackageStructureKit/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/FAQ/PackageStructureKit/oh-package-lock.json5 b/FAQ/PackageStructureKit/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/FAQ/PackageStructureKit/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/FAQ/PackageStructureKit/oh-package.json5 b/FAQ/PackageStructureKit/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..75e4e229db0f608fc3d9471c8819d0e52fb403c5 --- /dev/null +++ b/FAQ/PackageStructureKit/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.4", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +}