From 0138a35996b311c93b1c506c5be12692c7723582 Mon Sep 17 00:00:00 2001
From: dingchengjie
Date: Sat, 12 Sep 2026 13:54:31 +0800
Subject: [PATCH] feat:Ohos adaptation, adding jest and examples, and modifying
other configurations.pre-release:0.0.5-beta.1
Signed-off-by: dingchengjie
---
.buckconfig | 6 -
.eslintignore | 1 +
.flowconfig | 75 -
.gitignore | 80 +-
CHANGELOG.md | 5 +
OAT.xml | 89 +
README.md | 368 +-
README_en.md | 372 +
example/.eslintrc.json | 20 +
{examples => example}/.gitignore | 131 +-
example/App.tsx | 480 +
example/app.json | 4 +
example/babel.config.js | 3 +
example/harmony/.gitignore | 13 +
example/harmony/AppScope/app.json5 | 10 +
.../resources/base/element/string.json | 8 +
.../resources/base/media/background.png | Bin 0 -> 91942 bytes
.../resources/base/media/foreground.png | Bin 0 -> 15325 bytes
.../resources/base/media/layered_image.json | 7 +
example/harmony/build-profile.json5 | 35 +
example/harmony/code-linter.json5 | 32 +
example/harmony/entry/.gitignore | 6 +
example/harmony/entry/build-profile.json5 | 19 +
example/harmony/entry/hvigorfile.ts | 6 +
example/harmony/entry/obfuscation-rules.txt | 23 +
example/harmony/entry/oh-package.json5 | 16 +
.../harmony/entry/src/main/cpp/CMakeLists.txt | 30 +
.../entry/src/main/cpp/PackageProvider.cpp | 26 +
.../entry/src/main/cpp/RNOHPackagesFactory.h | 14 +
.../entry/src/main/ets/RNPackagesFactory.ets | 20 +
.../main/ets/entryability/EntryAbility.ets | 12 +
.../entrybackupability/EntryBackupAbility.ets | 16 +
.../entry/src/main/ets/pages/Index.ets | 94 +
example/harmony/entry/src/main/module.json5 | 62 +
.../main/resources/base/element/color.json | 8 +
.../main/resources/base/element/float.json | 8 +
.../main/resources/base/element/string.json | 16 +
.../main/resources/base/media/background.png | Bin 0 -> 91942 bytes
.../main/resources/base/media/foreground.png | Bin 0 -> 8805 bytes
.../resources/base/media/layered_image.json | 7 +
.../main/resources/base/media/startIcon.png | Bin 0 -> 20093 bytes
.../resources/base/profile/backup_config.json | 3 +
.../resources/base/profile/main_pages.json | 5 +
.../main/resources/dark/element/color.json | 8 +
.../entry/src/ohosTest/ets/test/List.test.ets | 5 +
.../ohosTest/ets/test/ui/ModuleTest.test.ets | 109 +
.../ohosTest/ets/testability/TestAbility.ets | 44 +
.../ohosTest/ets/testability/pages/Index.ets | 15 +
.../ets/testrunner/OpenHarmonyTestRunner.ts | 43 +
.../harmony/entry/src/ohosTest/module.json5 | 29 +
.../resources/base/element/color.json | 8 +
.../resources/base/element/string.json | 16 +
.../resources/base/media/startIcon.png | Bin 0 -> 20093 bytes
.../resources/base/profile/test_pages.json | 5 +
example/harmony/hvigor/hvigor-config.json5 | 26 +
example/harmony/hvigorfile.ts | 13 +
example/harmony/oh-package.json5 | 12 +
example/index.js | 9 +
example/metro.config.js | 39 +
example/package.json | 42 +
example/tsconfig.json | 8 +
examples/.buckconfig | 6 -
examples/.eslintrc.js | 4 -
examples/.flowconfig | 75 -
examples/.gitattributes | 1 -
examples/.prettierrc.js | 6 -
examples/.watchmanconfig | 1 -
examples/App.js | 135 -
examples/README.md | 25 -
examples/android/.project | 17 -
.../org.eclipse.buildship.core.prefs | 2 -
examples/android/app/_BUCK | 55 -
examples/android/app/build.gradle | 201 -
examples/android/app/build_defs.bzl | 19 -
examples/android/app/debug.keystore | Bin 2257 -> 0 bytes
examples/android/app/proguard-rules.pro | 10 -
.../android/app/src/debug/AndroidManifest.xml | 8 -
.../android/app/src/main/AndroidManifest.xml | 47 -
.../examples/headless/MainActivity.java | 15 -
.../examples/headless/MainApplication.java | 75 -
.../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3056 -> 0 bytes
.../res/mipmap-hdpi/ic_launcher_round.png | Bin 5024 -> 0 bytes
.../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2096 -> 0 bytes
.../res/mipmap-mdpi/ic_launcher_round.png | Bin 2858 -> 0 bytes
.../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4569 -> 0 bytes
.../res/mipmap-xhdpi/ic_launcher_round.png | Bin 7098 -> 0 bytes
.../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 6464 -> 0 bytes
.../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10676 -> 0 bytes
.../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 9250 -> 0 bytes
.../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15523 -> 0 bytes
.../app/src/main/res/values/strings.xml | 3 -
.../app/src/main/res/values/styles.xml | 9 -
examples/android/build.gradle | 38 -
examples/android/gradle.properties | 21 -
.../android/gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 0 bytes
.../gradle/wrapper/gradle-wrapper.properties | 5 -
examples/android/gradlew | 188 -
examples/android/gradlew.bat | 100 -
examples/android/settings.gradle | 3 -
examples/app.json | 4 -
examples/babel.config.js | 3 -
examples/index.js | 24 -
examples/metro.config.js | 17 -
examples/package-lock.json | 8476 -----------------
examples/package.json | 39 -
examples/package.json.git | 36 -
examples/package.json.local | 0
examples/run.sh | 1 -
examples/src/event-handler.js | 6 -
examples/src/store.js | 27 -
examples/update_run.sh | 3 -
examples/yarn.lock | 6570 -------------
harmony/headless.har | Bin 0 -> 10803 bytes
harmony/headless/NOTICE | 33 +
harmony/headless/OAT.xml | 38 +
harmony/headless/build-profile.json5 | 16 +
harmony/headless/hvigorfile.ts | 2 +
harmony/headless/index.ets | 1 +
harmony/headless/oh-package.json5 | 12 +
harmony/headless/src/main/cpp/CMakeLists.txt | 20 +
.../headless/src/main/cpp/HeadlessPackage.h | 15 +
.../src/main/cpp/generated/HeadlessModule.cpp | 25 +
.../src/main/cpp/generated/HeadlessModule.h | 21 +
.../main/cpp/generated/RNOHGeneratedPackage.h | 76 +
.../headless/src/main/ets/HeadlessModule.ets | 329 +
.../main/ets/HeadlessTurboModulesFactory.ets | 26 +
.../src/main/ets/generated/components/ts.ts | 5 +
.../headless/src/main/ets/generated/index.ets | 8 +
harmony/headless/src/main/ets/generated/ts.ts | 9 +
.../generated/turboModules/HeadlessModule.ts | 27 +
.../src/main/ets/generated/turboModules/ts.ts | 8 +
harmony/headless/src/main/module.json5 | 16 +
.../main/resources/base/element/string.json | 8 +
.../main/resources/en_US/element/string.json | 8 +
.../main/resources/zh_CN/element/string.json | 8 +
index.js | 10 +-
jest/__tests__/Headless-test.js | 81 +
jest/__tests__/NativeHeadlessModule-test.js | 46 +
jest/__tests__/index-test.js | 60 +
jest/jest.config.js | 72 +
jest/react-native.js | 46 +
jest/setup.js | 27 +
metro.config.js | 17 -
package.json | 96 +-
react-native.config.js | 11 +
src/Headless.js | 37 +-
src/index.js | 4 +
src/specs/NativeHeadlessModule.ts | 45 +
tsconfig.json | 35 +
149 files changed, 3573 insertions(+), 16561 deletions(-)
delete mode 100644 .buckconfig
create mode 100644 .eslintignore
delete mode 100644 .flowconfig
create mode 100644 CHANGELOG.md
create mode 100644 OAT.xml
create mode 100644 README_en.md
create mode 100644 example/.eslintrc.json
rename {examples => example}/.gitignore (58%)
create mode 100644 example/App.tsx
create mode 100644 example/app.json
create mode 100644 example/babel.config.js
create mode 100644 example/harmony/.gitignore
create mode 100644 example/harmony/AppScope/app.json5
create mode 100644 example/harmony/AppScope/resources/base/element/string.json
create mode 100644 example/harmony/AppScope/resources/base/media/background.png
create mode 100644 example/harmony/AppScope/resources/base/media/foreground.png
create mode 100644 example/harmony/AppScope/resources/base/media/layered_image.json
create mode 100644 example/harmony/build-profile.json5
create mode 100644 example/harmony/code-linter.json5
create mode 100644 example/harmony/entry/.gitignore
create mode 100644 example/harmony/entry/build-profile.json5
create mode 100644 example/harmony/entry/hvigorfile.ts
create mode 100644 example/harmony/entry/obfuscation-rules.txt
create mode 100644 example/harmony/entry/oh-package.json5
create mode 100644 example/harmony/entry/src/main/cpp/CMakeLists.txt
create mode 100644 example/harmony/entry/src/main/cpp/PackageProvider.cpp
create mode 100644 example/harmony/entry/src/main/cpp/RNOHPackagesFactory.h
create mode 100644 example/harmony/entry/src/main/ets/RNPackagesFactory.ets
create mode 100644 example/harmony/entry/src/main/ets/entryability/EntryAbility.ets
create mode 100644 example/harmony/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
create mode 100644 example/harmony/entry/src/main/ets/pages/Index.ets
create mode 100644 example/harmony/entry/src/main/module.json5
create mode 100644 example/harmony/entry/src/main/resources/base/element/color.json
create mode 100644 example/harmony/entry/src/main/resources/base/element/float.json
create mode 100644 example/harmony/entry/src/main/resources/base/element/string.json
create mode 100644 example/harmony/entry/src/main/resources/base/media/background.png
create mode 100644 example/harmony/entry/src/main/resources/base/media/foreground.png
create mode 100644 example/harmony/entry/src/main/resources/base/media/layered_image.json
create mode 100644 example/harmony/entry/src/main/resources/base/media/startIcon.png
create mode 100644 example/harmony/entry/src/main/resources/base/profile/backup_config.json
create mode 100644 example/harmony/entry/src/main/resources/base/profile/main_pages.json
create mode 100644 example/harmony/entry/src/main/resources/dark/element/color.json
create mode 100644 example/harmony/entry/src/ohosTest/ets/test/List.test.ets
create mode 100644 example/harmony/entry/src/ohosTest/ets/test/ui/ModuleTest.test.ets
create mode 100644 example/harmony/entry/src/ohosTest/ets/testability/TestAbility.ets
create mode 100644 example/harmony/entry/src/ohosTest/ets/testability/pages/Index.ets
create mode 100644 example/harmony/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
create mode 100644 example/harmony/entry/src/ohosTest/module.json5
create mode 100644 example/harmony/entry/src/ohosTest/resources/base/element/color.json
create mode 100644 example/harmony/entry/src/ohosTest/resources/base/element/string.json
create mode 100644 example/harmony/entry/src/ohosTest/resources/base/media/startIcon.png
create mode 100644 example/harmony/entry/src/ohosTest/resources/base/profile/test_pages.json
create mode 100644 example/harmony/hvigor/hvigor-config.json5
create mode 100644 example/harmony/hvigorfile.ts
create mode 100644 example/harmony/oh-package.json5
create mode 100644 example/index.js
create mode 100644 example/metro.config.js
create mode 100644 example/package.json
create mode 100644 example/tsconfig.json
delete mode 100644 examples/.buckconfig
delete mode 100644 examples/.eslintrc.js
delete mode 100644 examples/.flowconfig
delete mode 100644 examples/.gitattributes
delete mode 100644 examples/.prettierrc.js
delete mode 100644 examples/.watchmanconfig
delete mode 100644 examples/App.js
delete mode 100644 examples/README.md
delete mode 100644 examples/android/.project
delete mode 100644 examples/android/.settings/org.eclipse.buildship.core.prefs
delete mode 100644 examples/android/app/_BUCK
delete mode 100644 examples/android/app/build.gradle
delete mode 100644 examples/android/app/build_defs.bzl
delete mode 100644 examples/android/app/debug.keystore
delete mode 100644 examples/android/app/proguard-rules.pro
delete mode 100644 examples/android/app/src/debug/AndroidManifest.xml
delete mode 100644 examples/android/app/src/main/AndroidManifest.xml
delete mode 100644 examples/android/app/src/main/java/one/telefon/examples/headless/MainActivity.java
delete mode 100644 examples/android/app/src/main/java/one/telefon/examples/headless/MainApplication.java
delete mode 100644 examples/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
delete mode 100644 examples/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
delete mode 100644 examples/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
delete mode 100644 examples/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
delete mode 100644 examples/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
delete mode 100644 examples/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
delete mode 100644 examples/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
delete mode 100644 examples/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
delete mode 100644 examples/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
delete mode 100644 examples/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
delete mode 100644 examples/android/app/src/main/res/values/strings.xml
delete mode 100644 examples/android/app/src/main/res/values/styles.xml
delete mode 100644 examples/android/build.gradle
delete mode 100644 examples/android/gradle.properties
delete mode 100644 examples/android/gradle/wrapper/gradle-wrapper.jar
delete mode 100644 examples/android/gradle/wrapper/gradle-wrapper.properties
delete mode 100755 examples/android/gradlew
delete mode 100644 examples/android/gradlew.bat
delete mode 100644 examples/android/settings.gradle
delete mode 100644 examples/app.json
delete mode 100644 examples/babel.config.js
delete mode 100644 examples/index.js
delete mode 100644 examples/metro.config.js
delete mode 100644 examples/package-lock.json
delete mode 100644 examples/package.json
delete mode 100644 examples/package.json.git
delete mode 100644 examples/package.json.local
delete mode 100755 examples/run.sh
delete mode 100644 examples/src/event-handler.js
delete mode 100644 examples/src/store.js
delete mode 100755 examples/update_run.sh
delete mode 100644 examples/yarn.lock
create mode 100644 harmony/headless.har
create mode 100644 harmony/headless/NOTICE
create mode 100644 harmony/headless/OAT.xml
create mode 100644 harmony/headless/build-profile.json5
create mode 100644 harmony/headless/hvigorfile.ts
create mode 100644 harmony/headless/index.ets
create mode 100644 harmony/headless/oh-package.json5
create mode 100644 harmony/headless/src/main/cpp/CMakeLists.txt
create mode 100644 harmony/headless/src/main/cpp/HeadlessPackage.h
create mode 100644 harmony/headless/src/main/cpp/generated/HeadlessModule.cpp
create mode 100644 harmony/headless/src/main/cpp/generated/HeadlessModule.h
create mode 100644 harmony/headless/src/main/cpp/generated/RNOHGeneratedPackage.h
create mode 100644 harmony/headless/src/main/ets/HeadlessModule.ets
create mode 100644 harmony/headless/src/main/ets/HeadlessTurboModulesFactory.ets
create mode 100644 harmony/headless/src/main/ets/generated/components/ts.ts
create mode 100644 harmony/headless/src/main/ets/generated/index.ets
create mode 100644 harmony/headless/src/main/ets/generated/ts.ts
create mode 100644 harmony/headless/src/main/ets/generated/turboModules/HeadlessModule.ts
create mode 100644 harmony/headless/src/main/ets/generated/turboModules/ts.ts
create mode 100644 harmony/headless/src/main/module.json5
create mode 100644 harmony/headless/src/main/resources/base/element/string.json
create mode 100644 harmony/headless/src/main/resources/en_US/element/string.json
create mode 100644 harmony/headless/src/main/resources/zh_CN/element/string.json
create mode 100644 jest/__tests__/Headless-test.js
create mode 100644 jest/__tests__/NativeHeadlessModule-test.js
create mode 100644 jest/__tests__/index-test.js
create mode 100644 jest/jest.config.js
create mode 100644 jest/react-native.js
create mode 100644 jest/setup.js
delete mode 100644 metro.config.js
create mode 100644 react-native.config.js
create mode 100644 src/index.js
create mode 100644 src/specs/NativeHeadlessModule.ts
create mode 100644 tsconfig.json
diff --git a/.buckconfig b/.buckconfig
deleted file mode 100644
index 934256c..0000000
--- a/.buckconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-
-[android]
- target = Google Inc.:Google APIs:23
-
-[maven_repositories]
- central = https://repo1.maven.org/maven2
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+node_modules
diff --git a/.flowconfig b/.flowconfig
deleted file mode 100644
index 4afc766..0000000
--- a/.flowconfig
+++ /dev/null
@@ -1,75 +0,0 @@
-[ignore]
-; We fork some components by platform
-.*/*[.]android.js
-
-; Ignore "BUCK" generated dirs
-/\.buckd/
-
-; Ignore polyfills
-node_modules/react-native/Libraries/polyfills/.*
-
-; These should not be required directly
-; require from fbjs/lib instead: require('fbjs/lib/warning')
-node_modules/warning/.*
-
-; Flow doesn't support platforms
-.*/Libraries/Utilities/LoadingView.js
-
-[untyped]
-.*/node_modules/@react-native-community/cli/.*/.*
-
-[include]
-
-[libs]
-node_modules/react-native/Libraries/react-native/react-native-interface.js
-node_modules/react-native/flow/
-
-[options]
-emoji=true
-
-esproposal.optional_chaining=enable
-esproposal.nullish_coalescing=enable
-
-module.file_ext=.js
-module.file_ext=.json
-module.file_ext=.ios.js
-
-munge_underscores=true
-
-module.name_mapper='^react-native$' -> '/node_modules/react-native/Libraries/react-native/react-native-implementation'
-module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1'
-module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub'
-
-suppress_type=$FlowIssue
-suppress_type=$FlowFixMe
-suppress_type=$FlowFixMeProps
-suppress_type=$FlowFixMeState
-
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
-suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
-suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
-
-[lints]
-sketchy-null-number=warn
-sketchy-null-mixed=warn
-sketchy-number=warn
-untyped-type-import=warn
-nonstrict-import=warn
-deprecated-type=warn
-unsafe-getters-setters=warn
-inexact-spread=warn
-unnecessary-invariant=warn
-signature-verification-failure=warn
-deprecated-utility=error
-
-[strict]
-deprecated-type
-nonstrict-import
-sketchy-null
-unclear-type
-unsafe-getters-setters
-untyped-import
-untyped-type-import
-
-[version]
-^0.105.0
diff --git a/.gitignore b/.gitignore
index 3a819fb..05ebe44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,62 +1,32 @@
-.vscode
-
# OSX
-#
.DS_Store
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# Android/IntelliJ
-#
-build/
-.idea
-.gradle
-local.properties
-*.iml
-
# node.js
-#
node_modules/
-examples/node_modules/
npm-debug.log
yarn-error.log
-
-# BUCK
-buck-out/
-\.buckd/
-*.keystore
-!debug.keystore
-
-# fastlane
-#
-# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
-# screenshots whenever they are needed.
-# For more information about the recommended setup visit:
-# https://docs.fastlane.tools/best-practices/source-control/
-
-*/fastlane/report.xml
-*/fastlane/Preview.html
-*/fastlane/screenshots
-
-# Bundle artifact
-*.jsbundle
-
-# CocoaPods
-/ios/Pods/
+package-lock.json
+
+# Build output
+/dist
+*.tgz
+
+# IDE
+.idea/
+.vscode/
+
+# HarmonyOS build artifacts
+harmony/**/.cxx/
+harmony/**/build/
+harmony/**/.hvigor/
+example/harmony/**/.cxx/
+example/harmony/**/build/
+example/harmony/**/.hvigor/
+example/harmony/**/oh_modules/
+example/node_modules/
+
+# rn.py build hap fingerprints / local build metadata
+.rn-build/
+
+# Jest coverage output
+coverage/
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..0a46f83
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changelog
+
+## v0.0.5-beta.1
+### Added
+- feat:Ohos adaptation, adding jest and examples, and modifying other configurations. [#2](https://github.com/react-native-oh-library/react-native-headless/pull/2)
\ No newline at end of file
diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000..ccd31c9
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,89 @@
+
+
+
+ LICENSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 59b13c1..24f4bdb 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,371 @@
+> 文档模板:v0.4.2
+
+
react-native-headless
+
-# react-native-tele
+本项目基于 [react-native-headless](https://github.com/telefon-one/react-native-headless) 开发。
+版本所属关系如下:
-**UPDATE**: Now is compatible with RN 0.60+ (AndroidX)
+| 三方库名称 | 三方库版本(npm 地址) | 发布信息 | 支持 RN 版本 | Autolink | 编译 API 版本 | 社区基线版本 | 源码地址 |
+| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- |
+| react-native-headless | [~0.0.5](https://www.npmjs.com/package/react-native-headless) | [GitHub Releases](https://github.com/react-native-oh-library/react-native-headless/releases) | 0.84.* | 是 | API12+ | 0.0.4 | [master](https://github.com/react-native-oh-library/react-native-headless/tree/master) |
+## 简介
+本库为 React Native 提供后台任务保活、前后台切换等原生能力封装。
-## Support
-- Currently support for Android.
+## 下载安装
-## To do
+进入到工程目录并输入以下命令:
- - [ ] Add ToDo
+**npm**
-## Examples
+```bash
+npm install @react-native-ohos/react-native-headless
+```
+
+**yarn**
+
+```bash
+yarn add @react-native-ohos/react-native-headless
+```
+
+## Link
+
+| 版本 | 是否支持 Autolink | RN 框架版本 |
+|--------------------------------------|----------------|-----------|
+| ~0.0.5 | 是 | 0.84.* |
+
+使用 AutoLink 的工程需要根据该文档配置,Autolink 框架指导文档:[Autolinking 文档](https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md)
+
+如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过 ManualLink 配置。
+
+
+ ManualLink:此步骤为手动配置原生依赖项的指导
+
+首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。
+
+### 1. Overrides RN SDK
+
+为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 `oh-package.json5` 添加 overrides 字段:
+
+```json
+{
+ "overrides": {
+ "@rnoh/react-native-openharmony": "~0.84.1"
+ }
+}
+```
+
+关于该字段的作用请阅读[官方说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#zh-cn_topic_0000001792256137_overrides)。
+
+### 2. 引入原生端代码
+
+方法一:通过 har 包引入(推荐)
+
+> [!TIP] har 包位于三方库安装路径的 `harmony/headless.har`。
+
+打开 `entry/oh-package.json5`,添加以下依赖:
+
+```json
+"dependencies": {
+ "react-native-headless": "file:../../node_modules/react-native-headless/harmony/headless.har"
+}
+```
+
+点击右上角的 `sync` 按钮,或在终端执行:
+
+```bash
+cd entry
+ohpm install
+```
+
+方法二:直接链接源码
+
+> [!TIP] 如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)。
+
+### 3. 配置 CMakeLists 和引入 HeadlessPackage
+
+打开 `entry/src/main/cpp/CMakeLists.txt`,添加:
+
+```cmake
+set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+
+add_subdirectory("${OH_MODULES}/react-native-headless/src/main/cpp" ./headless)
+
+target_link_libraries(rnoh_app PUBLIC headless)
+```
+
+打开 `entry/src/main/cpp/PackageProvider.cpp`,添加:
+
+```cpp
+#include "HeadlessPackage.h"
+
+std::vector> PackageProvider::getPackages(Package::Context ctx) {
+ return {
+ std::make_shared(ctx),
+ };
+}
+```
+
+### 4. 在 ArkTS 侧引入 HeadlessPackage
+
+打开 `entry/src/main/ets/RNOHPackagesFactory.ets`,添加:
+
+```typescript
+import HeadlessPackage from 'react-native-headless';
+
+export function createRNOHPackages(ctx: RNPackageContext): RNOHPackage[] {
+ return [
+ new HeadlessPackage(ctx),
+ ];
+}
+```
+
+
+
+### 运行
+
+点击右上角的 `sync` 按钮,或在命令行终端执行:
+
+```bash
+cd entry
+ohpm install
+```
+
+然后编译、运行即可。
+
+## 约束与限制
+
+### 兼容性
+
+本文档内容基于以下版本验证通过:
+
+1.RNOH: 0.84.2; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.2.636; ROM: 6.0.0.125;
+
+### 权限要求
+
+在宿主工程 `entry/src/main/module.json5` 中声明:
+
+```json
+"requestPermissions": [
+ {
+ "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
+ }
+],
+"abilities": [
+ {
+ "name": "EntryAbility",
+ "backgroundModes": ["dataTransfer"]
+ }
+]
+```
+
+> [!TIP] `backgroundModes` 须与真实业务匹配。示例使用 `dataTransfer`(DATA_TRANSFER),若超 10 分钟未更新传输进度,系统会取消长时任务。实际业务应改用匹配类型(如 `audioPlayback`、`location` 等)。
+
+JS Bundle 路径:`example/harmony/entry/src/main/resources/rawfile/bundle.harmony.js`(由 `npm run dev` 生成)。
+
+### 编译运行 API 要求
-- [Android]Simple example (https://github.com/telefon-one/react-native-foreground-background/blob/master/examples/)
-- [Google.Play] TODO
+> [!TIP] 当前三方库支持在 `API12+` 工程编译,及 `API12+` ROM 运行。
+> [!TIP] 以下功能依赖特定版本的 API,使用低于指定 API 版本的 ROM 运行可能导致部分功能受限。
-## Installation
+1. `toBackground()` 映射 `UIAbilityContext.moveAbilityToBackground()`,需要 **API 12+**。
+2. `HeadlessTaskCancelled` 事件依赖 `backgroundTaskManager.on('continuousTaskCancel')`,需要 **API 15+**;低版本设备收不到该事件,但不影响 `stopService()` 复位。
-- [Android](https://github.com/telefon-one/react-native-foreground-background/blob/master/docs/installation_android.md)
+## 使用示例
-## Usage
+下面的代码展示了这个库的基本使用场景:
+
+> [!WARNING] 使用时 import 的库名不变。
+
+```javascript
+import Headless from 'react-native-headless';
+import { DeviceEventEmitter } from 'react-native';
+
+// 启动后台长时任务(Harmony:backgroundTaskManager;Android:Foreground Service)
+await Headless.startService();
+
+// 监听周期事件(Harmony 降级替代 registerHeadlessTask('HeadlessHandler'))
+const tickSub = DeviceEventEmitter.addListener('HeadlessTick', (payload) => {
+ console.log(payload.task, payload.tick, payload.timestamp);
+});
+
+// 长时任务被系统/用户取消
+const cancelSub = DeviceEventEmitter.addListener('HeadlessTaskCancelled', (payload) => {
+ console.log('cancelled, reason =', payload.reason);
+});
+
+// 停止
+await Headless.stopService();
+
+// 前后台(见下方使用说明中的平台差异)
+await Headless.toForeground();
+await Headless.toBackground();
+```
+
+## 使用说明
+
+**后台长时任务**
+
+```javascript
+await Headless.startService();
+// 运行期间 Harmony 每 2s 发送 HeadlessTick;Android 通过 HeadlessEventService 触发 HeadlessHandler
+await Headless.stopService(); // 幂等:未运行时静默成功
+```
+
+**Android 无头任务注册(仅 Android)**
```javascript
- import {ForegroundBackground} from 'react-native-foreground-background';
+import { AppRegistry } from 'react-native';
+
+AppRegistry.registerHeadlessTask('HeadlessHandler', () => async (data) => {
+ // 后台 JS 逻辑
+});
+```
+
+> HarmonyOS 无 `HeadlessJsTaskService` 等价物,请改用 `DeviceEventEmitter.addListener('HeadlessTick', ...)`。
+
+**前后台切换**
+
+```javascript
+// 退到后台(Harmony 真实能力;Android 上游为空实现)
+await Headless.toBackground();
+
+// 尝试拉到前台
+await Headless.toForeground();
+// ⚠️ Harmony:应用在后台时,普通三方应用无法主动 startAbility 拉起自身
+// (需 ohos.permission.START_ABILITIES_FROM_BACKGROUND,仅系统应用可申请)
+// 推荐通过 startService 时长时任务通知 + 用户点击 WantAgent 回前台
+```
+
+**锁屏相关**
+
+```javascript
+await Headless.noLock(); // Android/鸿蒙均为 no-op(与 Android 源码空实现对等,不提供锁屏穿透)
+```
+
+## 接口说明
+
+> [!TIP] 「Platform」列表示该属性/接口在原三方库上支持的平台。
- let tForegroundBackground = new ForegroundBackground();
+> [!TIP] 「HarmonyOS 平台支持」列为 yes 表示 HarmonyOS 平台完整支持;no 表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 Android 上游实现或官方允许的等价能力。
- ForegroundBackground.toBackground();
- ForegroundBackground.toForeground();
-
+### 模块导出
+
+| 名称 | 类型 | 必填 | Platform | HarmonyOS 平台支持 | 描述 |
+|------|------|------|----------|-------------------|------|
+| Headless | `NativeModule` / `TurboModule` | 是 | Android, HarmonyOS | yes | 默认导出,模块名 `HeadlessModule` |
+
+### API
+
+| 名称 | 类型 | 参数类型 | 返回值 | 必填 | Platform | HarmonyOS 平台支持 | 描述 |
+|------|------|----------|--------|------|----------|-------------------|------|
+| startService | function | 无 | `Promise` | 否 | Android, HarmonyOS | yes | 启动后台任务。Harmony:申请长时任务 + 系统通知;Android:启动 Foreground Service。成功后 Harmony 每 2s 发送 `HeadlessTick`。重复调用幂等。 |
+| stopService | function | 无 | `Promise` | 否 | Android, HarmonyOS | yes | 停止后台任务,撤销通知与周期事件。未运行时静默成功(与 Android 语义对等)。 |
+| toForeground | function | 无 | `Promise` | 否 | Android, HarmonyOS | partially | 尝试将应用拉到前台。Android:`startActivity(MainActivity)` 可从后台拉起。Harmony:`startAbility` 拉起自身 UIAbility;**应用在后台时普通三方应用会被系统拒绝**([组件启动规则](https://gitcode.com/openharmony/docs/blob/OpenHarmony-6.0-Release/zh-cn/application-dev/application-models/component-startup-rules.md))。 |
+| toBackground | function | 无 | `Promise` | 否 | Android, HarmonyOS | yes | 将应用退到后台。Harmony:`moveAbilityToBackground()`(API 12+,真实能力)。Android 上游为空实现。 |
+| noLock | function | 无 | `Promise` | 否 | Android, HarmonyOS | yes | 占位 API,立即 resolve,**不做任何操作**。对标 Android 源码空实现(`FLAG_SHOW_WHEN_LOCKED` 代码被注释未生效),不提供锁屏穿透。 |
+
+### 事件
+
+| 名称 | 参数类型 | Platform | HarmonyOS 平台支持 | 描述 |
+|------|----------|----------|-------------------|------|
+| HeadlessTick | [HeadlessTickPayload](#HeadlessTickPayload) | HarmonyOS | yes | 长时任务运行期间每 2s 触发,降级替代 Android `registerHeadlessTask('HeadlessHandler')`。 |
+| HeadlessTaskCancelled | [HeadlessTaskCancelledPayload](#HeadlessTaskCancelledPayload) | HarmonyOS | partially | 长时任务被系统/用户取消时触发(API 15+)。 |
+
+#### HeadlessTickPayload
+
+| 名称 | 参数类型 | 默认值 | 必填 | 描述 |
+|------|----------|--------|------|------|
+| task | string | `"HeadlessHandler"` | 是 | 任务名,对应 Android HeadlessEventService 注册的 taskName |
+| tick | number | — | 是 | 本次长时任务周期内第几个 tick(从 1 开始) |
+| timestamp | number | — | 是 | 事件产生时刻(epoch 毫秒) |
+
+#### HeadlessTaskCancelledPayload
+
+| 名称 | 参数类型 | 默认值 | 必填 | 描述 |
+|------|----------|--------|------|------|
+| task | string | `"HeadlessHandler"` | 是 | 任务名 |
+| reason | number | — | 是 | 取消原因:`1`=用户取消(移除通知),`2`=系统取消,等 |
+
+### 未实现功能
+
+| 能力 | Platform | HarmonyOS 平台支持 | 原因 |
+|------|----------|-------------------|------|
+| 开机自启(BootUpReceiver / BOOT_COMPLETED) | Android | no | HarmonyOS 不向三方应用开放开机广播;`ohos.permission.RECEIVER_STARTUP_COMPLETED` 仅系统应用可申请 |
+| AppRegistry.registerHeadlessTask | Android | no | RNOH 无 HeadlessJsTaskService 等价物,已降级为 `HeadlessTick` 事件 |
+| 锁屏穿透显示 | Android, HarmonyOS | no | Android 源码未实现;Harmony 需 [Live View Kit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/liveview-preparations) |
+
+## 快速验证(运行 Example)
+
+### 前置条件
+
+| 依赖 | 版本要求 |
+|------|----------|
+| Node.js | >= 18 |
+| DevEco Studio | 5.0+ / 6.0+ |
+| HarmonyOS SDK | API 12+ |
+
+### 运行步骤
+
+```bash
+# 1. 根目录安装并构建 JS 产物
+npm install --legacy-peer-deps
+
+# 2. 安装 example 依赖
+cd example
+npm install --legacy-peer-deps
+
+# 3. 生成 Harmony JS Bundle
+npm run dev
+
+# 4. DevEco Studio 打开 example/harmony,Sync 后编译运行
```
+> Example 已预置插件依赖与 Package 注册,无需手动 Link。
+
+## 遗留问题
+
+- `toForeground()` 在 HarmonyOS 后台场景下无法可靠自动拉回前台,需改用长时任务通知 + 用户点击(系统 [组件启动规则](https://gitcode.com/openharmony/docs/blob/OpenHarmony-6.0-Release/zh-cn/application-dev/application-models/component-startup-rules.md) 限制)。
+- `HeadlessTaskCancelled` 依赖 API 15+ 的 `continuousTaskCancel` 事件;API 12–14 设备收不到该事件。
+- 示例使用 `DATA_TRANSFER` 长时任务类型,超 10 分钟未更新进度会被系统取消。
+
+## 其他
+
+- import 包名始终为 `'react-native-headless'`,Harmony 侧通过 RNOH alias 映射到原生 HAR。
+- Android 上游原生代码见 [telefon-one/react-native-headless](https://github.com/telefon-one/react-native-headless);本仓库当前分支以 HarmonyOS 适配为主。
+
+## 目录结构
+
+````
+react-native-headless/ # 项目根目录
+├── harmony/ # 鸿蒙适配代码
+│ ├── headless.har # 预构建 har 包
+│ └── headless/ # 鸿蒙适配核心代码
+│ ├── index.ets # 鸿蒙适配入口(导出 HeadlessPackage)
+│ └── src/main/ets/
+│ ├── HeadlessModule.ets # TurboModule 实现
+│ └── HeadlessTurboModulesFactory.ets # Package 注册
+├── src/ # RN JS 源码
+│ ├── index.js # 入口(导出 Headless)
+│ ├── Headless.js # 跨平台模块获取
+│ └── specs/NativeHeadlessModule.ts # TurboModule Spec
+├── dist/ # bob 构建产物(npm 发布入口)
+├── example/ # HarmonyOS 示例工程
+│ ├── App.tsx
+│ └── harmony/ # DevEco 工程
+├── jest/ # 单元测试
+├── README.md # 中文文档
+└── README_en.md # 英文文档
+````
+
+## 贡献代码
+
+使用过程中发现任何问题都可以提交 [Issue](https://github.com/telefon-one/react-native-headless/issues),也非常欢迎提交 [PR](https://github.com/telefon-one/react-native-headless/pulls)。
+
+## 开源协议
+
+本项目基于 [ISC License](https://github.com/telefon-one/react-native-headless/blob/master/LICENSE)(原始库协议)。
diff --git a/README_en.md b/README_en.md
new file mode 100644
index 0000000..c8dc659
--- /dev/null
+++ b/README_en.md
@@ -0,0 +1,372 @@
+> Document Template: v0.4.2
+
+
+
react-native-headless
+
+
+This project is based on [react-native-headless](https://github.com/telefon-one/react-native-headless).
+
+The version correspondence details are as follows:
+
+| Name | Version (Npm Address) | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | Source Code Address |
+| --------------| -------------- | ------------------------------ | ------------- | ------------- |------------------------ | ------------ | ------------- |
+| react-native-headless | [~0.0.5](https://www.npmjs.com/package/react-native-headless) | [GitHub Releases](https://github.com/react-native-oh-library/react-native-headless/releases) | 0.84.* | Yes | API12+ | 0.0.4 | [master](https://github.com/react-native-oh-library/react-native-headless/tree/master) |
+
+## Introduction
+
+This library provides native capabilities encapsulation for React Native, such as background task maintenance and front-end/back-end switching.
+
+## Installation
+
+Go to the project directory and execute the following instruction:
+
+**npm**
+
+```bash
+npm install @react-native-ohos/react-native-headless
+```
+
+**yarn**
+
+```bash
+yarn add @react-native-ohos/react-native-headless
+```
+
+## Link
+
+| Version | Supported Autolink | Supported RN Version |
+|--------------------------------------|--------------------|----------------------|
+| ~0.0.5 | Yes | 0.84.* |
+
+Projects using AutoLink need to be configured according to this document. AutoLink framework guide: [Autolinking documentation](https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md)
+
+If the version you are using supports Autolink and the project has integrated Autolink, you can skip the ManualLink configuration.
+
+
+ ManualLink: This step provides guidance for manually configuring native dependencies.
+
+Open the `harmony` directory of the OpenHarmony project in DevEco Studio.
+
+### 1. Overrides RN SDK
+
+To ensure the project relies on the same version of the RN SDK, add an `overrides` field in the project's root `oh-package.json5` file:
+
+```json
+{
+ "overrides": {
+ "@rnoh/react-native-openharmony": "~0.84.1"
+ }
+}
+```
+
+For more information about the purpose of this field, please refer to the [official documentation](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#en-us_topic_0000001792256137_overrides).
+
+### 2. Introducing Native Code
+
+Method 1 (recommended): Use the HAR file.
+
+> [!TIP] The HAR file is stored at `harmony/headless.har` in the installation path of the third-party library.
+
+Open `entry/oh-package.json5` and add the following dependencies:
+
+```json
+"dependencies": {
+ "react-native-headless": "file:../../node_modules/react-native-headless/harmony/headless.har"
+}
+```
+
+Click the `sync` button in the upper right corner, or run:
+
+```bash
+cd entry
+ohpm install
+```
+
+Method 2: Directly link to the source code.
+
+> [!TIP] For details, see [Directly Linking Source Code](https://gitcode.com/CPF-RN/usage-docs/blob/master/en/link-source-code.md).
+
+### 3. Configuring CMakeLists and Introducing HeadlessPackage
+
+Open `entry/src/main/cpp/CMakeLists.txt` and add:
+
+```cmake
+set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
+
+add_subdirectory("${OH_MODULES}/react-native-headless/src/main/cpp" ./headless)
+
+target_link_libraries(rnoh_app PUBLIC headless)
+```
+
+Open `entry/src/main/cpp/PackageProvider.cpp` and add:
+
+```cpp
+#include "HeadlessPackage.h"
+
+std::vector> PackageProvider::getPackages(Package::Context ctx) {
+ return {
+ std::make_shared(ctx),
+ };
+}
+```
+
+### 4. Introducing HeadlessPackage to ArkTS
+
+Open `entry/src/main/ets/RNOHPackagesFactory.ets` and add:
+
+```typescript
+import HeadlessPackage from 'react-native-headless';
+
+export function createRNOHPackages(ctx: RNPackageContext): RNOHPackage[] {
+ return [
+ new HeadlessPackage(ctx),
+ ];
+}
+```
+
+
+
+## Running
+
+Click the `sync` button in the upper right corner, or run:
+
+```bash
+cd entry
+ohpm install
+```
+
+Then build and run the code.
+
+## Constraints
+
+### Compatibility
+
+This document is verified based on the following versions:
+
+1.RNOH: 0.84.2; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.2.636; ROM: 6.0.0.125;
+
+### Permission Requirements
+
+Declare in the host app's `entry/src/main/module.json5`:
+
+```json
+"requestPermissions": [
+ {
+ "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
+ }
+],
+"abilities": [
+ {
+ "name": "EntryAbility",
+ "backgroundModes": ["dataTransfer"]
+ }
+]
+```
+
+> [!TIP] `backgroundModes` must match your actual business scenario. The example uses `dataTransfer` (DATA_TRANSFER). If progress is not updated for more than 10 minutes, the system cancels the continuous task. Use a matching type in production (e.g. `audioPlayback`, `location`).
+
+JS Bundle path: `example/harmony/entry/src/main/resources/rawfile/bundle.harmony.js` (generated by `npm run dev`).
+
+### API Requirements
+
+> [!TIP] The current third-party library supports compilation in `API12+` projects and execution on `API12+` ROMs.
+
+> [!TIP] The following features depend on specific API versions. Running on a ROM below the specified API version may result in limited functionality.
+
+1. `toBackground()` maps to `UIAbilityContext.moveAbilityToBackground()`, requiring **API 12+**.
+2. The `HeadlessTaskCancelled` event depends on `backgroundTaskManager.on('continuousTaskCancel')`, requiring **API 15+**. Devices below API 15 will not receive this event, but `stopService()` still resets state correctly.
+
+## Example
+
+The following code shows the basic use scenario of the repository:
+
+> [!WARNING] The name of the imported repository remains unchanged.
+
+```javascript
+import Headless from 'react-native-headless';
+import { DeviceEventEmitter } from 'react-native';
+
+// Start background continuous task (Harmony: backgroundTaskManager; Android: Foreground Service)
+await Headless.startService();
+
+// Listen for periodic events (Harmony degraded alternative to registerHeadlessTask('HeadlessHandler'))
+const tickSub = DeviceEventEmitter.addListener('HeadlessTick', (payload) => {
+ console.log(payload.task, payload.tick, payload.timestamp);
+});
+
+// Continuous task cancelled by system or user
+const cancelSub = DeviceEventEmitter.addListener('HeadlessTaskCancelled', (payload) => {
+ console.log('cancelled, reason =', payload.reason);
+});
+
+// Stop
+await Headless.stopService();
+
+// Foreground/background (see platform differences in How to Use)
+await Headless.toForeground();
+await Headless.toBackground();
+```
+
+## How to Use
+
+**Background continuous task**
+
+```javascript
+await Headless.startService();
+// While running: Harmony emits HeadlessTick every 2s; Android triggers HeadlessHandler via HeadlessEventService
+await Headless.stopService(); // Idempotent: silently succeeds when not running
+```
+
+**Android headless task registration (Android only)**
+
+```javascript
+import { AppRegistry } from 'react-native';
+
+AppRegistry.registerHeadlessTask('HeadlessHandler', () => async (data) => {
+ // Background JS logic
+});
+```
+
+> HarmonyOS has no `HeadlessJsTaskService` equivalent. Use `DeviceEventEmitter.addListener('HeadlessTick', ...)` instead.
+
+**Foreground/background switching**
+
+```javascript
+// Move to background (real capability on Harmony; upstream Android is a no-op)
+await Headless.toBackground();
+
+// Attempt to bring to foreground
+await Headless.toForeground();
+// ⚠️ Harmony: when the app is in background, third-party apps cannot reliably startAbility to bring themselves to foreground
+// (requires ohos.permission.START_ABILITIES_FROM_BACKGROUND, system apps only)
+// Recommended: use the continuous task notification from startService() + user tap on WantAgent
+```
+
+**Lock screen**
+
+```javascript
+await Headless.noLock(); // No-op on both Android and Harmony (parity with upstream Android empty implementation; no lock-screen bypass)
+```
+
+## Available APIs
+
+> [!TIP] The **Platform** column indicates the platform where the properties are supported in the original third-party library.
+
+> [!TIP] If the value of **HarmonyOS Support** is **yes**, it means that the HarmonyOS platform supports this property; **no** means the opposite; **partially** means some capabilities are supported. The usage method is the same on different platforms and the effect is aligned with the upstream Android behavior or officially allowed equivalent capabilities.
+
+### Module Export
+
+| Name | Type | Required | Platform | HarmonyOS Support | Description |
+|------|------|----------|----------|-------------------|-------------|
+| Headless | `NativeModule` / `TurboModule` | Yes | Android, HarmonyOS | yes | Default export. Module name: `HeadlessModule`. |
+
+### API
+
+| Name | Type | Parameter Type | Return Value | Required | Platform | HarmonyOS Support | Description |
+|------|------|----------------|--------------|----------|----------|-------------------|-------------|
+| startService | function | None | `Promise` | No | Android, HarmonyOS | yes | Start background task. Harmony: request continuous task + system notification; Android: start Foreground Service. After success, Harmony emits `HeadlessTick` every 2s. Repeated calls are idempotent. |
+| stopService | function | None | `Promise` | No | Android, HarmonyOS | yes | Stop background task, dismiss notification and periodic events. Silently succeeds when not running (parity with Android). |
+| toForeground | function | None | `Promise` | No | Android, HarmonyOS | partially | Attempt to bring the app to foreground. Android: `startActivity(MainActivity)` can launch from background. Harmony: `startAbility` to self UIAbility; **rejected when app is in background for third-party apps** ([Component Startup Rules](https://gitcode.com/openharmony/docs/blob/OpenHarmony-6.0-Release/en/application-dev/application-models/component-startup-rules.md)). |
+| toBackground | function | None | `Promise` | No | Android, HarmonyOS | yes | Move app to background. Harmony: `moveAbilityToBackground()` (API 12+, real capability). Upstream Android is a no-op. |
+| noLock | function | None | `Promise` | No | Android, HarmonyOS | yes | Placeholder API, resolves immediately, **does nothing**. Parity with upstream Android empty implementation (`FLAG_SHOW_WHEN_LOCKED` code commented out). Does not provide lock-screen bypass. |
+
+### Events
+
+| Name | Parameter Type | Platform | HarmonyOS Support | Description |
+|------|----------------|----------|-------------------|-------------|
+| HeadlessTick | [HeadlessTickPayload](#HeadlessTickPayload) | HarmonyOS | yes | Emitted every 2s while continuous task runs. Degraded alternative to Android `registerHeadlessTask('HeadlessHandler')`. |
+| HeadlessTaskCancelled | [HeadlessTaskCancelledPayload](#HeadlessTaskCancelledPayload) | HarmonyOS | partially | Emitted when continuous task is cancelled by system or user (API 15+). |
+
+#### HeadlessTickPayload
+
+| Name | Parameter Type | Default Value | Required | Description |
+|------|----------------|---------------|----------|-------------|
+| task | string | `"HeadlessHandler"` | Yes | Task name, matching Android HeadlessEventService taskName |
+| tick | number | — | Yes | Tick count within current continuous task period (starts at 1) |
+| timestamp | number | — | Yes | Event timestamp (epoch milliseconds) |
+
+#### HeadlessTaskCancelledPayload
+
+| Name | Parameter Type | Default Value | Required | Description |
+|------|----------------|---------------|----------|-------------|
+| task | string | `"HeadlessHandler"` | Yes | Task name |
+| reason | number | — | Yes | Cancel reason: `1`=user cancelled (notification removed), `2`=system cancelled, etc. |
+
+### Unsupported Features
+
+| Capability | Platform | HarmonyOS Support | Reason |
+|------------|----------|-------------------|--------|
+| Boot auto-start (BootUpReceiver / BOOT_COMPLETED) | Android | no | HarmonyOS does not expose boot broadcast to third-party apps; `ohos.permission.RECEIVER_STARTUP_COMPLETED` is system-only |
+| AppRegistry.registerHeadlessTask | Android | no | RNOH has no HeadlessJsTaskService equivalent; degraded to `HeadlessTick` events |
+| Lock-screen bypass display | Android, HarmonyOS | no | Not implemented in upstream Android source; Harmony requires [Live View Kit](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/liveview-preparations) |
+
+## Quick Verification (Run Example)
+
+### Prerequisites
+
+| Dependency | Version Requirement |
+|------------|---------------------|
+| Node.js | >= 18 |
+| DevEco Studio | 5.0+ / 6.0+ |
+| HarmonyOS SDK | API 12+ |
+
+### Steps
+
+```bash
+# 1. Install and build JS artifacts at repo root
+npm install --legacy-peer-deps
+
+# 2. Install example dependencies
+cd example
+npm install --legacy-peer-deps
+
+# 3. Generate Harmony JS Bundle
+npm run dev
+
+# 4. Open example/harmony in DevEco Studio, Sync, build and run
+```
+
+> The example already includes plugin dependencies and Package registration; no manual Link required.
+
+## Known Issues
+
+- `toForeground()` cannot reliably auto-bring the app to foreground from background on HarmonyOS. Use continuous task notification + user tap instead ([Component Startup Rules](https://gitcode.com/openharmony/docs/blob/OpenHarmony-6.0-Release/en/application-dev/application-models/component-startup-rules.md)).
+- `HeadlessTaskCancelled` depends on API 15+ `continuousTaskCancel` event; API 12–14 devices will not receive it.
+- The example uses `DATA_TRANSFER` continuous task type; the system cancels it if progress is not updated for more than 10 minutes.
+
+## Other
+
+- Always import as `'react-native-headless'`. Harmony side maps to the native HAR via RNOH alias.
+- Upstream Android native code is at [telefon-one/react-native-headless](https://github.com/telefon-one/react-native-headless); this branch focuses on HarmonyOS adaptation.
+
+## Directory Structure
+
+````
+react-native-headless/ # Project root
+├── harmony/ # HarmonyOS adaptation code
+│ ├── headless.har # Prebuilt HAR package
+│ └── headless/ # Core HarmonyOS adaptation
+│ ├── index.ets # Entry (exports HeadlessPackage)
+│ └── src/main/ets/
+│ ├── HeadlessModule.ets # TurboModule implementation
+│ └── HeadlessTurboModulesFactory.ets # Package registration
+├── src/ # RN JS source
+│ ├── index.js # Entry (exports Headless)
+│ ├── Headless.js # Cross-platform module accessor
+│ └── specs/NativeHeadlessModule.ts # TurboModule Spec
+├── dist/ # bob build output (npm publish entry)
+├── example/ # HarmonyOS example project
+│ ├── App.tsx
+│ └── harmony/ # DevEco project
+├── jest/ # Unit tests
+├── README.md # Chinese documentation
+└── README_en.md # English documentation
+````
+
+## How to Contribute
+
+If you find any problem when using react-native-headless, submit an [Issue](https://github.com/telefon-one/react-native-headless/issues) or a [PR](https://github.com/telefon-one/react-native-headless/pulls).
+
+## License
+
+This repository is based on the [ISC License](https://github.com/telefon-one/react-native-headless/blob/master/LICENSE) (original library license).
diff --git a/example/.eslintrc.json b/example/.eslintrc.json
new file mode 100644
index 0000000..672abc4
--- /dev/null
+++ b/example/.eslintrc.json
@@ -0,0 +1,20 @@
+{
+ "root": true,
+ "extends": [
+ "@react-native"
+ ],
+ "rules": {
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "warn",
+ "no-console": "off",
+ "@typescript-eslint/no-unused-vars": "off",
+ "prettier/prettier": "off"
+ },
+ "ignorePatterns": [
+ "node_modules/",
+ "harmony/",
+ "__tests__/",
+ "*.js",
+ "*.d.ts"
+ ]
+}
\ No newline at end of file
diff --git a/examples/.gitignore b/example/.gitignore
similarity index 58%
rename from examples/.gitignore
rename to example/.gitignore
index ad572e6..1254704 100644
--- a/examples/.gitignore
+++ b/example/.gitignore
@@ -1,59 +1,72 @@
-# OSX
-#
-.DS_Store
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# Android/IntelliJ
-#
-build/
-.idea
-.gradle
-local.properties
-*.iml
-
-# node.js
-#
-node_modules/
-npm-debug.log
-yarn-error.log
-
-# BUCK
-buck-out/
-\.buckd/
-*.keystore
-!debug.keystore
-
-# fastlane
-#
-# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
-# screenshots whenever they are needed.
-# For more information about the recommended setup visit:
-# https://docs.fastlane.tools/best-practices/source-control/
-
-*/fastlane/report.xml
-*/fastlane/Preview.html
-*/fastlane/screenshots
-
-# Bundle artifact
-*.jsbundle
-
-# CocoaPods
-/ios/Pods/
+# OSX
+#
+.DS_Store
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+ios/.xcode.env.local
+
+# Android/IntelliJ
+#
+build/
+.idea
+.gradle
+local.properties
+*.iml
+*.hprof
+.cxx/
+*.keystore
+!debug.keystore
+
+# node.js
+#
+node_modules/
+npm-debug.log
+yarn-error.log
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
+# screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/
+
+**/fastlane/report.xml
+**/fastlane/Preview.html
+**/fastlane/screenshots
+**/fastlane/test_output
+
+# Bundle artifact
+*.jsbundle
+
+# HarmonyOS bundle
+harmony/entry/src/main/resources/rawfile/bundle.harmony.js
+harmony/entry/src/main/resources/rawfile/hermes_bundle.hbc
+
+# Ruby / CocoaPods
+/ios/Pods/
+/vendor/bundle/
+
+# Temporary files created by Metro to check the health of the file watcher
+.metro-health-check*
+
+# testing
+/coverage
+
+package-lock.json
\ No newline at end of file
diff --git a/example/App.tsx b/example/App.tsx
new file mode 100644
index 0000000..7b5c9f6
--- /dev/null
+++ b/example/App.tsx
@@ -0,0 +1,480 @@
+/**
+ * react-native-headless 鸿蒙适配 Example
+ *
+ * 覆盖全部 5 个公开 API(startService / stopService / toForeground /
+ * toBackground / noLock)与降级能力 HeadlessTick 周期事件监听,
+ * 每个操作均展示真实返回值(成功 / BusinessError code+message)。
+ */
+
+import React, {useCallback, useEffect, useRef, useState} from 'react';
+import {
+ AppState,
+ DeviceEventEmitter,
+ SafeAreaView,
+ ScrollView,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import Headless from 'react-native-headless';
+
+// Hermes 无 Intl,用 Date getter 手拼时间(HH:mm:ss)
+function formatTime(ts: number): string {
+ const d = new Date(ts);
+ const p = (n: number) => (n < 10 ? '0' + n : '' + n);
+ return p(d.getHours()) + ':' + p(d.getMinutes()) + ':' + p(d.getSeconds());
+}
+
+type LogItem = {
+ id: number;
+ time: string;
+ api: string;
+ ok: boolean;
+ detail: string;
+};
+
+type TickInfo = {
+ task: string;
+ tick: number;
+ timestamp: number;
+};
+
+const MAX_LOGS = 50;
+
+function App(): JSX.Element {
+ const [logs, setLogs] = useState([]);
+ const [tickInfo, setTickInfo] = useState(null);
+ const [tickTotal, setTickTotal] = useState(0);
+ const [isRunning, setIsRunning] = useState(false);
+ const [appState, setAppState] = useState(
+ AppState.currentState === undefined ? 'unknown' : AppState.currentState,
+ );
+ // toBackground 后自动回前台(模拟原库来电场景:后台事件把应用拉回前台)
+ const [autoReturn, setAutoReturn] = useState(true);
+ const logIdRef = useRef(0);
+ const autoReturnTimerRef = useRef | null>(null);
+
+ const appendLog = useCallback((api: string, ok: boolean, detail: string) => {
+ logIdRef.current += 1;
+ const item: LogItem = {
+ id: logIdRef.current,
+ time: formatTime(Date.now()),
+ api: api,
+ ok: ok,
+ detail: detail,
+ };
+ setLogs(prev => [item, ...prev].slice(0, MAX_LOGS));
+ }, []);
+
+ // 调用库方法并记录真实结果(成功 / BusinessError code+message)
+ const callApi = useCallback(
+ (api: string, fn: () => Promise, onDone?: (ok: boolean) => void) => {
+ if (!Headless) {
+ appendLog(api, false, '模块未注册(TurboModule HeadlessModule 不可用)');
+ return;
+ }
+ fn()
+ .then(() => {
+ appendLog(api, true, 'resolve(成功)');
+ if (onDone) {
+ onDone(true);
+ }
+ })
+ .catch((error: {code?: number; message?: string}) => {
+ const code = error && error.code !== undefined ? error.code : '?';
+ const message =
+ error && error.message !== undefined ? error.message : String(error);
+ appendLog(api, false, `reject code=${code} message=${message}`);
+ if (onDone) {
+ onDone(false);
+ }
+ });
+ },
+ [appendLog],
+ );
+
+ const onStartService = useCallback(() => {
+ callApi('startService', () => Headless.startService(), ok => {
+ if (ok) {
+ setIsRunning(true);
+ setTickTotal(0);
+ setTickInfo(null);
+ }
+ });
+ }, [callApi]);
+
+ const onStopService = useCallback(() => {
+ callApi('stopService', () => Headless.stopService(), ok => {
+ if (ok) {
+ setIsRunning(false);
+ }
+ });
+ }, [callApi]);
+
+ const onToForeground = useCallback(() => {
+ callApi('toForeground', () => Headless.toForeground());
+ }, [callApi]);
+
+ const onToBackground = useCallback(() => {
+ callApi('toBackground', () => Headless.toBackground(), ok => {
+ if (ok && autoReturn) {
+ // 后台停留 5s 后拉回前台:真实还原原库场景
+ // (HeadlessHandler 收到来电 → toForeground 把应用带回前台)
+ if (autoReturnTimerRef.current !== null) {
+ clearTimeout(autoReturnTimerRef.current);
+ }
+ autoReturnTimerRef.current = setTimeout(() => {
+ autoReturnTimerRef.current = null;
+ callApi('toForeground(自动)', () => Headless.toForeground());
+ }, 5000);
+ }
+ });
+ }, [callApi, autoReturn]);
+
+ const onNoLock = useCallback(() => {
+ callApi('noLock', () => Headless.noLock());
+ }, [callApi]);
+
+ // HeadlessTick 周期事件监听(对应 Android registerHeadlessTask('HeadlessHandler'),
+ // 鸿蒙无 HeadlessJsTaskService,降级为 DeviceEventEmitter 事件)
+ useEffect(() => {
+ const subscription = DeviceEventEmitter.addListener(
+ 'HeadlessTick',
+ (payload: TickInfo) => {
+ if (payload && typeof payload.tick === 'number') {
+ setTickInfo(payload);
+ setTickTotal(payload.tick);
+ setIsRunning(true);
+ }
+ },
+ );
+ // 长时任务被系统/用户取消(如 DATA_TRANSFER 超 10 分钟未更新进度):
+ // 库侧同步状态并通知 JS,Example 更新运行态展示
+ const cancelSubscription = DeviceEventEmitter.addListener(
+ 'HeadlessTaskCancelled',
+ (payload: {task?: string; reason?: number}) => {
+ const reasonText =
+ payload && typeof payload.reason === 'number'
+ ? payload.reason === 1
+ ? '用户取消(移除通知)'
+ : payload.reason === 2
+ ? '系统取消'
+ : `reason=${payload.reason}`
+ : '未知原因';
+ setIsRunning(false);
+ appendLog('HeadlessTaskCancelled', false, `长时任务已停止:${reasonText}`);
+ },
+ );
+ return () => {
+ subscription.remove();
+ cancelSubscription.remove();
+ };
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ // 前后台状态变化展示(toBackground 副作用可见)
+ useEffect(() => {
+ const subscription = AppState.addEventListener('change', nextAppState => {
+ setAppState(nextAppState);
+ });
+ return () => {
+ subscription.remove();
+ };
+ }, []);
+
+ // 卸载时清理自动回前台定时器
+ useEffect(() => {
+ return () => {
+ if (autoReturnTimerRef.current !== null) {
+ clearTimeout(autoReturnTimerRef.current);
+ autoReturnTimerRef.current = null;
+ }
+ };
+ }, []);
+
+ const statusColor = isRunning ? '#2e7d32' : '#757575';
+
+ return (
+
+
+ react-native-headless 鸿蒙适配
+
+ 长时任务 / 前后台切换 Example(HarmonyOS)
+
+
+ {!Headless ? (
+
+
+ HeadlessModule 不可用:TurboModule 未注册,请检查 RNOHPackagesFactory
+
+
+ ) : null}
+
+ {/* 状态总览 */}
+
+ 状态
+
+ 长时任务
+
+ {isRunning ? '运行中' : '未运行'}
+
+
+
+ 应用前后台
+ {appState}
+
+
+ Tick 计数
+ {tickTotal}
+
+
+
+ {/* API:startService / stopService */}
+
+ 后台长时任务
+
+ startService 申请长时任务(对应 Android 前台服务,通知栏出现任务通知);{'\n'}
+ 运行期间每 2s 向 JS 发送 HeadlessTick 事件{'\n'}
+ 注:演示用 DATA_TRANSFER 类型,超 10 分钟未更新进度会被系统取消(收到
+ HeadlessTaskCancelled 事件),实际业务应换用匹配的类型
+
+
+
+ startService()
+
+
+ stopService()
+
+
+
+
+ {/* HeadlessTick 事件实时展示 */}
+
+ HeadlessTick 事件(降级能力)
+
+ Android 端为 registerHeadlessTask('HeadlessHandler') 每 2s 触发;
+ RNOH 无 HeadlessJsTaskService,降级为原生周期事件,此处为真实监听结果
+
+ {tickInfo ? (
+
+
+ task
+ {tickInfo.task}
+
+
+ tick
+ #{tickInfo.tick}
+
+
+ timestamp
+
+ {tickInfo.timestamp}({formatTime(tickInfo.timestamp)})
+
+
+
+ ) : (
+
+ 未收到事件(startService 成功后每 2s 到达一次)
+
+ )}
+
+
+ {/* API:toForeground / toBackground */}
+
+ 前后台切换
+
+ toBackground 会退到后台(可开启 5s 后自动 toForeground 模拟来电拉回场景);
+ 应用在后台时 toForeground 受系统管控可能被拒绝
+
+ setAutoReturn(prev => !prev)}>
+
+ 自动回前台:{autoReturn ? '开' : '关'}
+
+
+
+
+ toForeground()
+
+
+ toBackground()
+
+
+
+
+ {/* API:noLock */}
+
+ noLock()
+
+ Android 原实现为空实现(锁屏窗口标志代码未生效),鸿蒙侧行为对等:no-op
+
+
+ noLock()
+
+
+
+ {/* 平台差异明示 */}
+
+ 平台能力差异
+
+ ⛔ 开机自启(Android BootUpReceiver / BOOT_COMPLETED):鸿蒙不向三方应用开放开机广播,{'\n'}
+ 本库在鸿蒙端不支持该能力,无替代实现{'\n'}
+ ⚠️ Headless JS 无头任务:进程模型不同,降级为长时任务周期事件(见上方 HeadlessTick)
+
+
+
+ {/* 结果日志面板 */}
+
+ 调用结果(真实返回)
+ {logs.length === 0 ? (
+ 暂无调用记录
+ ) : (
+ logs.map(item => (
+
+
+ {item.time} {item.ok ? '✓' : '✗'}
+
+ {item.api}
+ {item.detail}
+
+ ))
+ )}
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ root: {
+ flex: 1,
+ backgroundColor: '#f5f5f5',
+ },
+ content: {
+ padding: 16,
+ paddingBottom: 40,
+ },
+ title: {
+ fontSize: 20,
+ fontWeight: '700',
+ color: '#212121',
+ },
+ subtitle: {
+ fontSize: 13,
+ color: '#757575',
+ marginTop: 4,
+ marginBottom: 12,
+ },
+ card: {
+ backgroundColor: '#ffffff',
+ borderRadius: 10,
+ borderWidth: StyleSheet.hairlineWidth,
+ borderColor: '#e0e0e0',
+ padding: 14,
+ marginBottom: 12,
+ },
+ cardTitle: {
+ fontSize: 15,
+ fontWeight: '600',
+ color: '#212121',
+ marginBottom: 6,
+ },
+ cardDesc: {
+ fontSize: 12,
+ color: '#757575',
+ lineHeight: 18,
+ marginBottom: 10,
+ },
+ statusRow: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ paddingVertical: 3,
+ },
+ statusLabel: {
+ fontSize: 13,
+ color: '#616161',
+ },
+ statusValue: {
+ fontSize: 13,
+ color: '#212121',
+ fontWeight: '600',
+ },
+ buttonRow: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ },
+ button: {
+ flex: 1,
+ borderRadius: 8,
+ paddingVertical: 10,
+ alignItems: 'center',
+ marginHorizontal: 4,
+ },
+ buttonPrimary: {
+ backgroundColor: '#1565c0',
+ },
+ buttonDanger: {
+ backgroundColor: '#c62828',
+ },
+ buttonGhost: {
+ backgroundColor: '#ffffff',
+ borderWidth: 1,
+ borderColor: '#9e9e9e',
+ },
+ buttonText: {
+ color: '#ffffff',
+ fontSize: 13,
+ fontWeight: '600',
+ },
+ buttonGhostText: {
+ color: '#616161',
+ fontSize: 13,
+ fontWeight: '600',
+ },
+ hintText: {
+ fontSize: 12,
+ color: '#9e9e9e',
+ },
+ errorText: {
+ fontSize: 13,
+ color: '#c62828',
+ },
+ logRow: {
+ paddingVertical: 4,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: '#eeeeee',
+ },
+ logTime: {
+ fontSize: 11,
+ fontWeight: '700',
+ },
+ logApi: {
+ fontSize: 13,
+ color: '#212121',
+ fontWeight: '600',
+ },
+ logDetail: {
+ fontSize: 11,
+ color: '#616161',
+ },
+});
+
+export default App;
diff --git a/example/app.json b/example/app.json
new file mode 100644
index 0000000..113c48a
--- /dev/null
+++ b/example/app.json
@@ -0,0 +1,4 @@
+{
+ "name": "AwesomeProject",
+ "displayName": "AwesomeProject"
+}
diff --git a/example/babel.config.js b/example/babel.config.js
new file mode 100644
index 0000000..26513cb
--- /dev/null
+++ b/example/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ['module:@react-native/babel-preset'],
+};
diff --git a/example/harmony/.gitignore b/example/harmony/.gitignore
new file mode 100644
index 0000000..679906e
--- /dev/null
+++ b/example/harmony/.gitignore
@@ -0,0 +1,13 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+/.appanalyzer
+oh-package-lock.json5
\ No newline at end of file
diff --git a/example/harmony/AppScope/app.json5 b/example/harmony/AppScope/app.json5
new file mode 100644
index 0000000..869605d
--- /dev/null
+++ b/example/harmony/AppScope/app.json5
@@ -0,0 +1,10 @@
+{
+ "app": {
+ "bundleName": "com.example.application",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:layered_image",
+ "label": "$string:app_name"
+ }
+}
diff --git a/example/harmony/AppScope/resources/base/element/string.json b/example/harmony/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000..d71e5ea
--- /dev/null
+++ b/example/harmony/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication"
+ }
+ ]
+}
diff --git a/example/harmony/AppScope/resources/base/media/background.png b/example/harmony/AppScope/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f
GIT binary patch
literal 91942
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