diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 681f41ae2aee4749eb4ddda94f8c6a76c825c825..0000000000000000000000000000000000000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- xmlns:android
-
- ^$
-
-
-
-
-
-
-
-
- xmlns:.*
-
- ^$
-
-
- BY_NAME
-
-
-
-
-
-
- .*:id
-
- http://schemas.android.com/apk/res/android
-
-
-
-
-
-
-
-
- .*:name
-
- http://schemas.android.com/apk/res/android
-
-
-
-
-
-
-
-
- name
-
- ^$
-
-
-
-
-
-
-
-
- style
-
- ^$
-
-
-
-
-
-
-
-
- .*
-
- ^$
-
-
- BY_NAME
-
-
-
-
-
-
- .*
-
- http://schemas.android.com/apk/res/android
-
-
- ANDROID_ATTRIBUTE_ORDER
-
-
-
-
-
-
- .*
-
- .*
-
-
- BY_NAME
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Dart_SDK.xml b/.idea/libraries/Dart_SDK.xml
deleted file mode 100644
index 5afd599130e3a2dec3f0dd9272b8e639e0598f5e..0000000000000000000000000000000000000000
--- a/.idea/libraries/Dart_SDK.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml
deleted file mode 100644
index 53449daeefb5613c1dda1ab2c4b7940d064889c6..0000000000000000000000000000000000000000
--- a/.idea/libraries/Flutter_Plugins.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Flutter_for_Android.xml b/.idea/libraries/Flutter_for_Android.xml
deleted file mode 100644
index fc6d95aed6acfb6648edfd000447b536cddd9074..0000000000000000000000000000000000000000
--- a/.idea/libraries/Flutter_for_Android.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/example_lib_main_dart.xml b/.idea/runConfigurations/example_lib_main_dart.xml
deleted file mode 100644
index bac2c8a79e6d460d9466b19eb766ff091bee76fe..0000000000000000000000000000000000000000
--- a/.idea/runConfigurations/example_lib_main_dart.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index d9208ab19e7448b48c86e1d98557febb0e4106bd..0000000000000000000000000000000000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6a189cda997b3c0dd6453ce89e71e0a35160c674
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/.gitignore b/android/.idea/.gitignore
similarity index 51%
rename from .idea/.gitignore
rename to android/.idea/.gitignore
index 5c98b428844d9f7d529e2b6fb918d15bf072f3df..26d33521af10bcc7fd8cea344038eaaeb78d0ef5 100644
--- a/.idea/.gitignore
+++ b/android/.idea/.gitignore
@@ -1,2 +1,3 @@
# Default ignored files
-/workspace.xml
\ No newline at end of file
+/shelf/
+/workspace.xml
diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4019936a4de3a8a32d56a77224905915b9a29a46
--- /dev/null
+++ b/android/.idea/gradle.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/android/.idea/migrations.xml
similarity index 37%
rename from .idea/runConfigurations.xml
rename to android/.idea/migrations.xml
index 797acea53eb091cf5b30518802c3073f544adeed..f8051a6f973e69a86e6f07f1a1c87f17a31c7235 100644
--- a/.idea/runConfigurations.xml
+++ b/android/.idea/migrations.xml
@@ -1,9 +1,9 @@
-
-
+
+
-
+
diff --git a/.idea/misc.xml b/android/.idea/misc.xml
similarity index 36%
rename from .idea/misc.xml
rename to android/.idea/misc.xml
index f1fbd79c26920c6d222f08553ec6a6f92a5b4409..8bb1dd1e4e707d3dde012eee7f9387eb907ae9fb 100644
--- a/.idea/misc.xml
+++ b/android/.idea/misc.xml
@@ -1,12 +1,9 @@
-
-
-
-
+
-
+
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/android/.idea/modules.xml
similarity index 59%
rename from .idea/modules.xml
rename to android/.idea/modules.xml
index 36e5948c41985ba5235936b5914bfd6509372739..9dddca504199d17fc0a51ce8f2d0963945dd0c6d 100644
--- a/.idea/modules.xml
+++ b/android/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/android/.idea/other.xml b/android/.idea/other.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4604c44601dbfadb8a37238f101b7b9533bdf151
--- /dev/null
+++ b/android/.idea/other.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index d690323a4cfea9eabd97dfa7a4913bb8067fb419..375d0ccafc0d7065802978025f3b6f1545061e6b 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -22,7 +22,7 @@ rootProject.allprojects {
apply plugin: 'com.android.library'
android {
- compileSdkVersion 28
+ compileSdkVersion 31
defaultConfig {
minSdkVersion 21
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 019065d1d650ce87992f9d60b7a162f7f2f8caf9..29fb08c6f953b004610e2ea7587d09f59619055b 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
+#Tue Aug 06 15:13:18 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies
deleted file mode 100644
index aff7a672b542e1f1b678f6a99847b6210ef86e1b..0000000000000000000000000000000000000000
--- a/example/.flutter-plugins-dependencies
+++ /dev/null
@@ -1 +0,0 @@
-{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"image_picker","path":"/Users/lipenghui/.pub-cache/hosted/pub.flutter-io.cn/image_picker-0.6.7+14/","dependencies":[]},{"name":"permission_handler","path":"/Users/lipenghui/.pub-cache/hosted/pub.flutter-io.cn/permission_handler-3.3.0/","dependencies":[]},{"name":"r_scan","path":"/Users/lipenghui/Documents/flutter_project/other/r_scan/","dependencies":[]}],"android":[{"name":"flutter_plugin_android_lifecycle","path":"/Users/lipenghui/.pub-cache/hosted/pub.flutter-io.cn/flutter_plugin_android_lifecycle-1.0.11/","dependencies":[]},{"name":"image_picker","path":"/Users/lipenghui/.pub-cache/hosted/pub.flutter-io.cn/image_picker-0.6.7+14/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"permission_handler","path":"/Users/lipenghui/.pub-cache/hosted/pub.flutter-io.cn/permission_handler-3.3.0/","dependencies":[]},{"name":"r_scan","path":"/Users/lipenghui/Documents/flutter_project/other/r_scan/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"permission_handler","dependencies":[]},{"name":"r_scan","dependencies":[]}],"date_created":"2021-06-11 20:23:05.203628","version":"2.2.0"}
\ No newline at end of file
diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
index fac15ccdfff25bb478e5557c157087190e0c6f0f..35bb4305b4d6fa8717950b851cbdb3954842edb9 100644
--- a/example/android/app/build.gradle
+++ b/example/android/app/build.gradle
@@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
- compileSdkVersion 30
+ compileSdkVersion 33
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -36,7 +36,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.rhyme.r_scan_example"
minSdkVersion 21
- targetSdkVersion 30
+ targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml
index 34dd77efb2efe9fe743e3cbfa6a6430c0113a24d..9991c9e25f8bd16a3d43a8cb6edb6d30b4926477 100644
--- a/example/android/app/src/main/AndroidManifest.xml
+++ b/example/android/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
android:icon="@mipmap/ic_launcher">
1.4.1)
+ - Flutter
+ - ZXingObjC (~> 3.6.5)
+ - ZXingObjC (3.6.5):
+ - ZXingObjC/All (= 3.6.5)
+ - ZXingObjC/All (3.6.5)
+
+DEPENDENCIES:
+ - Flutter (from `Flutter`)
+ - image_picker (from `.symlinks/plugins/image_picker/ios`)
+ - permission_handler (from `.symlinks/plugins/permission_handler/ios`)
+ - r_scan (from `.symlinks/plugins/r_scan/ios`)
+
+SPEC REPOS:
+ trunk:
+ - ATBarSDK
+ - ZXingObjC
+
+EXTERNAL SOURCES:
+ Flutter:
+ :path: Flutter
+ image_picker:
+ :path: ".symlinks/plugins/image_picker/ios"
+ permission_handler:
+ :path: ".symlinks/plugins/permission_handler/ios"
+ r_scan:
+ :path: ".symlinks/plugins/r_scan/ios"
+
+SPEC CHECKSUMS:
+ ATBarSDK: b6aa2b6a120ac7d6b1ff041bd60b9edde6bb17c4
+ Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
+ image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
+ permission_handler: 67637977b227d62d46bfbf524f335f8568de5a73
+ r_scan: 5672d9b68f8cece3835895a6aaab12047acf65bd
+ ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
+
+PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
+
+COCOAPODS: 1.10.1
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 481615d584fc792f437dabcf6447128e981f2b60..f838b3246ed2a8208fcc70b82ebe9af272fc3eaa 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -51,7 +51,7 @@ class _MyPageState extends State {
? '点击下方按钮开始扫码'
: '扫码结果${result.toString().split(',').join('\n')}')),
Center(
- child: FlatButton(
+ child: TextButton(
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
@@ -65,7 +65,7 @@ class _MyPageState extends State {
),
),
Center(
- child: FlatButton(
+ child: TextButton(
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
@@ -78,24 +78,22 @@ class _MyPageState extends State {
),
),
Center(
- child: FlatButton(
+ child: TextButton(
onPressed: () async {
- if (await canReadStorage()) {
- var image =
- await ImagePicker.pickImage(source: ImageSource.gallery);
- if (image != null) {
- final result = await RScan.scanImagePath(image.path);
- setState(() {
- this.result = result;
- });
- }
+ var image =
+ await ImagePicker().pickImage(source: ImageSource.gallery);
+ if (image != null) {
+ final result = await RScan.scanImagePath(image.path);
+ setState(() {
+ this.result = result;
+ });
}
},
child: Text('选择图片扫描'),
),
),
Center(
- child: FlatButton(
+ child: TextButton(
onPressed: () async {
final result = await RScan.scanImageUrl(
"https://s.cn.bing.net/th?id=OJ.5F0gxqWmxskS0Q&w=75&h=75&pid=MSNJVFeeds");
@@ -107,7 +105,7 @@ class _MyPageState extends State {
),
),
Center(
- child: FlatButton(
+ child: TextButton(
onPressed: () async {
ByteData data = await rootBundle.load('images/qrCode.png');
final result =
@@ -126,19 +124,12 @@ class _MyPageState extends State {
Future canReadStorage() async {
if (Platform.isIOS) return true;
- var status = await PermissionHandler()
- .checkPermissionStatus(PermissionGroup.storage);
- if (status != PermissionStatus.granted) {
- var future = await PermissionHandler()
- .requestPermissions([PermissionGroup.storage]);
- for (final item in future.entries) {
- if (item.value != PermissionStatus.granted) {
- return false;
- }
- }
+ var status = await Permission.storage.status;
+ if (!status.isGranted) {
+ status = await Permission.storage.request();
+ return status.isGranted;
} else {
return true;
}
- return true;
}
}
diff --git a/example/lib/scan_camera_dialog.dart b/example/lib/scan_camera_dialog.dart
index 34be92e858ee40a35eda57b1a88edcdce9e72fe4..a0832d304ddb7123f634a18be35dd9ac4d11d902 100644
--- a/example/lib/scan_camera_dialog.dart
+++ b/example/lib/scan_camera_dialog.dart
@@ -16,16 +16,15 @@ class _RScanCameraDialogState extends State {
void initCamera() async {
if (rScanCameras == null || rScanCameras.length == 0) {
- final result = await PermissionHandler()
- .checkPermissionStatus(PermissionGroup.camera);
- if (result == PermissionStatus.granted) {
+ final result = await Permission.camera.status;
+ if (result.isGranted) {
rScanCameras = await availableRScanCameras();
print('返回可用的相机:${rScanCameras.join('\n')}');
} else {
- final resultMap = await PermissionHandler()
- .requestPermissions([PermissionGroup.camera]);
- if (resultMap[PermissionGroup.camera] == PermissionStatus.granted) {
+ final result = await Permission.camera.request();
+ if (result.isGranted) {
rScanCameras = await availableRScanCameras();
+ print('返回可用的相机:${rScanCameras.join('\n')}');
} else {
print('相机权限被拒绝,无法使用');
}
@@ -87,12 +86,44 @@ class _RScanCameraDialogState extends State {
child: RScanCamera(_controller),
),
),
- Align(
- alignment: Alignment.bottomCenter,
- child: FutureBuilder(
- future: getFlashMode(),
- builder: _buildFlashBtn,
- ))
+ Row(
+ children: [
+ Container(
+ padding: EdgeInsets.only(bottom: 24 + MediaQuery
+ .of(context)
+ .padding
+ .bottom,left: 12),
+ child: Align(
+ alignment: Alignment.bottomCenter,
+ child: TextButton(
+ onPressed: () async {
+ _controller.stopScan();
+ },
+ child: Text('关闭扫描'),
+ )),
+ ),
+ Container(
+ padding: EdgeInsets.only(bottom: 24 + MediaQuery
+ .of(context)
+ .padding
+ .bottom,left: 12),
+ child: Align(
+ alignment: Alignment.bottomCenter,
+ child: TextButton(
+ onPressed: () async {
+ _controller.startScan();
+ },
+ child: Text('开启扫描'),
+ )),
+ ),
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: FutureBuilder(
+ future: getFlashMode(),
+ builder: _buildFlashBtn,
+ )),
+ ],
+ )
],
),
);
@@ -109,21 +140,24 @@ class _RScanCameraDialogState extends State {
Widget _buildFlashBtn(BuildContext context, AsyncSnapshot snapshot) {
return snapshot.hasData
? Padding(
- padding: EdgeInsets.only(
- bottom: 24 + MediaQuery.of(context).padding.bottom),
- child: IconButton(
- icon: Icon(snapshot.data ? Icons.flash_on : Icons.flash_off),
- color: Colors.white,
- iconSize: 46,
- onPressed: () {
- if (snapshot.data) {
- _controller.setFlashMode(false);
- } else {
- _controller.setFlashMode(true);
- }
- setState(() {});
- }),
- )
+ padding: EdgeInsets.only(
+ bottom: 24 + MediaQuery
+ .of(context)
+ .padding
+ .bottom),
+ child: IconButton(
+ icon: Icon(snapshot.data ? Icons.flash_on : Icons.flash_off),
+ color: Colors.white,
+ iconSize: 46,
+ onPressed: () {
+ if (snapshot.data) {
+ _controller.setFlashMode(false);
+ } else {
+ _controller.setFlashMode(true);
+ }
+ setState(() {});
+ }),
+ )
: Container();
}
}
diff --git a/example/lib/scan_dialog.dart b/example/lib/scan_dialog.dart
index 2f997684aa31f4a852c6ef3cdc6a3e9f7a57ffc4..e8e62efa826d0eef837f2b5f9a9f42955e2fef96 100644
--- a/example/lib/scan_dialog.dart
+++ b/example/lib/scan_dialog.dart
@@ -46,12 +46,44 @@ class _RScanDialogState extends State {
controller: _controller,
),
),
- Align(
- alignment: Alignment.bottomCenter,
- child: FutureBuilder(
- future: getFlashMode(),
- builder: _buildFlashBtn,
- ))
+ Row(
+ children: [
+ Container(
+ padding: EdgeInsets.only(bottom: 24 + MediaQuery
+ .of(context)
+ .padding
+ .bottom,left: 12),
+ child: Align(
+ alignment: Alignment.bottomCenter,
+ child: TextButton(
+ onPressed: () async {
+ _controller.stopScan();
+ },
+ child: Text('关闭扫描'),
+ )),
+ ),
+ Container(
+ padding: EdgeInsets.only(bottom: 24 + MediaQuery
+ .of(context)
+ .padding
+ .bottom,left: 12),
+ child: Align(
+ alignment: Alignment.bottomCenter,
+ child: TextButton(
+ onPressed: () async {
+ _controller.startScan();
+ },
+ child: Text('开启扫描'),
+ )),
+ ),
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: FutureBuilder(
+ future: getFlashMode(),
+ builder: _buildFlashBtn,
+ ))
+ ],
+ ),
],
);
} else {
@@ -71,16 +103,10 @@ class _RScanDialogState extends State {
}
Future canOpenCameraView() async {
- var status =
- await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
- if (status != PermissionStatus.granted) {
- var future = await PermissionHandler()
- .requestPermissions([PermissionGroup.camera]);
- for (final item in future.entries) {
- if (item.value != PermissionStatus.granted) {
- return false;
- }
- }
+ var status = await Permission.camera.status;
+ if (!status.isGranted) {
+ var future = await Permission.camera.request();
+ return future.isGranted;
} else {
return true;
}
diff --git a/example/ohos/AppScope/app.json5 b/example/ohos/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..426bf944505ee6b925c019650650fc38354329e8
--- /dev/null
+++ b/example/ohos/AppScope/app.json5
@@ -0,0 +1,10 @@
+{
+ "app": {
+ "bundleName": "com.example.r_scan_ohos",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/AppScope/resources/base/element/string.json b/example/ohos/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..cf49bab5b301101794b19d66d4eb4d4c9e07d15d
--- /dev/null
+++ b/example/ohos/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "r_scan_ohos"
+ }
+ ]
+}
diff --git a/example/ohos/AppScope/resources/base/media/app_icon.png b/example/ohos/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/example/ohos/AppScope/resources/base/media/app_icon.png differ
diff --git a/example/ohos/build-profile.json5 b/example/ohos/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..1d12140d202702d7c73d64f1b291fe5c45a660ce
--- /dev/null
+++ b/example/ohos/build-profile.json5
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "signingConfigs": [],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "compatibleSdkVersion": "5.0.0(12)",
+ "runtimeOS": "HarmonyOS"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/ohos/entry/.gitignore b/example/ohos/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043
--- /dev/null
+++ b/example/ohos/entry/.gitignore
@@ -0,0 +1,7 @@
+
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/example/ohos/entry/build-profile.json5 b/example/ohos/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb
--- /dev/null
+++ b/example/ohos/entry/build-profile.json5
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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.
+*/
+
+{
+ "apiType": 'stageMode',
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default",
+ "runtimeOS": "HarmonyOS"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/ohos/entry/hvigorfile.ts b/example/ohos/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5bda56eeac3f79703639db986e2faaa433b0e48c
--- /dev/null
+++ b/example/ohos/entry/hvigorfile.ts
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+export { hapTasks } from '@ohos/hvigor-ohos-plugin';
diff --git a/example/ohos/entry/oh-package.json5 b/example/ohos/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..078610f17b4a9d75c48dc65508a230e5a4a552fb
--- /dev/null
+++ b/example/ohos/entry/oh-package.json5
@@ -0,0 +1,10 @@
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b5888ed9002dd328f9abd3141ee3e63e88b40d0f
--- /dev/null
+++ b/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';
+import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
+
+export default class EntryAbility extends FlutterAbility {
+ configureFlutterEngine(flutterEngine: FlutterEngine) {
+ super.configureFlutterEngine(flutterEngine)
+ GeneratedPluginRegistrant.registerWith(flutterEngine)
+ }
+}
diff --git a/example/ohos/entry/src/main/ets/pages/Index.ets b/example/ohos/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..5d9647743f4651f3dab7aa3076ed0707b207b436
--- /dev/null
+++ b/example/ohos/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import common from '@ohos.app.ability.common';
+import { FlutterPage } from '@ohos/flutter_ohos'
+
+let storage = LocalStorage.getShared()
+const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'
+
+@Entry(storage)
+@Component
+struct Index {
+ private context = getContext(this) as common.UIAbilityContext
+ @LocalStorageLink('viewId') viewId: string = "";
+
+ build() {
+ Column() {
+ FlutterPage({ viewId: this.viewId })
+ }
+ }
+
+ onBackPress(): boolean {
+ this.context.eventHub.emit(EVENT_BACK_PRESS)
+ return true
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets b/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets
new file mode 100644
index 0000000000000000000000000000000000000000..72b30566d5d8483957faece8d86829ce35c4f92a
--- /dev/null
+++ b/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { FlutterEngine, Log } from '@ohos/flutter_ohos';
+import ImagePickerPlugin from 'image_picker_ohos';
+import PermissionHandlerPlugin from 'permission_handler_ohos';
+import RScanPlugin from 'r_scan';
+
+/**
+ * Generated file. Do not edit.
+ * This file is generated by the Flutter tool based on the
+ * plugins that support the Ohos platform.
+ */
+
+const TAG = "GeneratedPluginRegistrant";
+
+export class GeneratedPluginRegistrant {
+
+ static registerWith(flutterEngine: FlutterEngine) {
+ try {
+ flutterEngine.getPlugins()?.add(new ImagePickerPlugin());
+ flutterEngine.getPlugins()?.add(new PermissionHandlerPlugin());
+ flutterEngine.getPlugins()?.add(new RScanPlugin());
+ } catch (e) {
+ Log.e(
+ TAG,
+ "Tried to register plugins with FlutterEngine ("
+ + flutterEngine
+ + ") failed.");
+ Log.e(TAG, "Received exception while registering", e);
+ }
+ }
+}
diff --git a/example/ohos/entry/src/main/module.json5 b/example/ohos/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..34e8cf791dd653283481f6534792b09c9ac4df9f
--- /dev/null
+++ b/example/ohos/entry/src/main/module.json5
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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.
+*/
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "phone"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "abilities": [
+ {
+ "name": "EntryAbility",
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:icon",
+ "startWindowBackground": "$color:start_window_background",
+ "exported": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {"name" : "ohos.permission.INTERNET"},
+ {
+ "name": "ohos.permission.CAMERA",
+ "reason": "$string:camera_permissions_reason",
+ "usedScene": {
+ "abilities": [
+ "EntryAbility"
+ ],
+ "when": "inuse"
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/main/resources/base/element/color.json b/example/ohos/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/example/ohos/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/example/ohos/entry/src/main/resources/base/element/string.json b/example/ohos/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..d0b2997ee99cf6355b65fccdc4d0d60215f1a54f
--- /dev/null
+++ b/example/ohos/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,20 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "r_scan_ohos"
+ },
+ {
+ "name": "camera_permissions_reason",
+ "value": "使用相机扫码"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/main/resources/base/media/icon.png b/example/ohos/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/example/ohos/entry/src/main/resources/base/media/icon.png differ
diff --git a/example/ohos/entry/src/main/resources/base/profile/main_pages.json b/example/ohos/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/example/ohos/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/example/ohos/entry/src/main/resources/en_US/element/string.json b/example/ohos/entry/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..ee58e0e226102b585e8e0ed7760177449d8779d9
--- /dev/null
+++ b/example/ohos/entry/src/main/resources/en_US/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "r_scan_ohos"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/main/resources/zh_CN/element/string.json b/example/ohos/entry/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..648c0784d758a1c54d257cfb1c3aade76bccb75d
--- /dev/null
+++ b/example/ohos/entry/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "模块描述"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "r_scan_ohos"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..bdb2d4b3479e7c4b3d4ffb539abc734470c57f32
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import hilog from '@ohos.hilog';
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
+
+export default function abilityTest() {
+ describe('ActsAbilityTest', function () {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(function () {
+ // 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(function () {
+ // 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(function () {
+ // 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(function () {
+ // 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, function () {
+ // 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/example/ohos/entry/src/ohosTest/ets/test/List.test.ets b/example/ohos/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..5ed99383f79bb67de7472f356de5b0421fa26e71
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/ets/test/List.test.ets
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import abilityTest from './Ability.test'
+
+export default function testsuite() {
+ abilityTest()
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..465211ee2e66f8b16d8c28881acc0f534df700e5
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import UIAbility from '@ohos.app.ability.UIAbility';
+import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
+import hilog from '@ohos.hilog';
+import { Hypium } from '@ohos/hypium';
+import testsuite from '../test/List.test';
+import window from '@ohos.window';
+
+export default class TestAbility extends UIAbility {
+ onCreate(want, launchParam) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
+ hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
+ hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? '');
+ var abilityDelegator: any
+ abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+ var abilityDelegatorArguments: any
+ abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
+ hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
+ Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
+ }
+
+ onDestroy() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage) {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
+ windowStage.loadContent('testability/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() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
+ }
+
+ onForeground() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
+ }
+
+ onBackground() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..bdf1e5f905bcacd6a73af7709c41d4a79d41b170
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import hilog from '@ohos.hilog';
+
+@Entry
+@Component
+struct Index {
+ aboutToAppear() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear');
+ }
+ @State message: string = 'Hello World'
+ build() {
+ Row() {
+ Column() {
+ Text(this.message)
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ Button() {
+ Text('next page')
+ .fontSize(20)
+ .fontWeight(FontWeight.Bold)
+ }.type(ButtonType.Capsule)
+ .margin({
+ top: 20
+ })
+ .backgroundColor('#0D9FFB')
+ .width('35%')
+ .height('5%')
+ .onClick(()=>{
+ })
+ }
+ .width('100%')
+ }
+ .height('100%')
+ }
+ }
\ No newline at end of file
diff --git a/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
new file mode 100644
index 0000000000000000000000000000000000000000..58d9c312f08e7c9ac01e4d6f2d0a33ddc6188ed9
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import hilog from '@ohos.hilog';
+import TestRunner from '@ohos.application.testRunner';
+import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
+
+var abilityDelegator = undefined
+var abilityDelegatorArguments = undefined
+
+async function onAbilityCreateCallback() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
+}
+
+async function addAbilityMonitorCallback(err: any) {
+ hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
+}
+
+export default class OpenHarmonyTestRunner implements TestRunner {
+ constructor() {
+ }
+
+ onPrepare() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
+ }
+
+ async onRun() {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
+ abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
+ abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+ var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
+ let lMonitor = {
+ abilityName: testAbilityName,
+ onAbilityCreate: onAbilityCreateCallback,
+ };
+ abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
+ var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
+ var debug = abilityDelegatorArguments.parameters['-D']
+ if (debug == 'true')
+ {
+ cmd += ' -D'
+ }
+ hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd);
+ abilityDelegator.executeShellCommand(cmd,
+ (err: any, d: any) => {
+ hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? '');
+ hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? '');
+ hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? '');
+ })
+ hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/ohosTest/module.json5 b/example/ohos/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/module.json5
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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.
+*/
+
+{
+ "module": {
+ "name": "entry_test",
+ "type": "feature",
+ "description": "$string:module_test_desc",
+ "mainElement": "TestAbility",
+ "deviceTypes": [
+ "phone"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:test_pages",
+ "abilities": [
+ {
+ "name": "TestAbility",
+ "srcEntry": "./ets/testability/TestAbility.ets",
+ "description": "$string:TestAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:TestAbility_label",
+ "exported": true,
+ "startWindowIcon": "$media:icon",
+ "startWindowBackground": "$color:start_window_background",
+ "skills": [
+ {
+ "actions": [
+ "action.system.home"
+ ],
+ "entities": [
+ "entity.system.home"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/example/ohos/entry/src/ohosTest/resources/base/element/color.json b/example/ohos/entry/src/ohosTest/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/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/example/ohos/entry/src/ohosTest/resources/base/element/string.json b/example/ohos/entry/src/ohosTest/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_test_desc",
+ "value": "test ability description"
+ },
+ {
+ "name": "TestAbility_desc",
+ "value": "the test ability"
+ },
+ {
+ "name": "TestAbility_label",
+ "value": "test label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example/ohos/entry/src/ohosTest/resources/base/media/icon.png b/example/ohos/entry/src/ohosTest/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/example/ohos/entry/src/ohosTest/resources/base/media/icon.png differ
diff --git a/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe
--- /dev/null
+++ b/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "testability/pages/Index"
+ ]
+}
diff --git a/example/ohos/hvigor/hvigor-config.json5 b/example/ohos/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..541ba35711b75986f9295410ee38fdb8f2572878
--- /dev/null
+++ b/example/ohos/hvigor/hvigor-config.json5
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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.
+*/
+
+{
+ "modelVersion": "5.0.0",
+ "dependencies": {
+ }
+}
\ No newline at end of file
diff --git a/example/ohos/hvigorfile.ts b/example/ohos/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..38626e385a5b47dd3cba0e1e83c614f091b7cc9e
--- /dev/null
+++ b/example/ohos/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+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. */
+}
\ No newline at end of file
diff --git a/example/ohos/oh-package.json5 b/example/ohos/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fd52e97edf3b25ee95f9685b496f304aee4ce62d
--- /dev/null
+++ b/example/ohos/oh-package.json5
@@ -0,0 +1,17 @@
+{
+ "modelVersion": "5.0.0",
+ "name": "r_scan_ohos",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ "@ohos/flutter_ohos": "file:./har/flutter.har"
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.6"
+ },
+ "overrides": {
+ }
+}
\ No newline at end of file
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 56ade147a2e4a4ced23917c9166ff7204b5c1ea0..16964f4bbc05b01dab4c8fb489a95bc48c9bcfb6 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -5,58 +5,98 @@ packages:
dependency: transitive
description:
name: async
- url: "https://pub.flutter-io.cn"
+ sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.6.1"
+ version: "2.10.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.flutter-io.cn"
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.flutter-io.cn"
+ sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.flutter-io.cn"
- source: hosted
- version: "1.2.0"
+ version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.flutter-io.cn"
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.0"
+ version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.flutter-io.cn"
+ sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.15.0"
+ version: "1.17.0"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "445db18de832dba8d851e287aff8ccf169bed30d2e94243cb54c7d2f1ed2142c"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.3.3+6"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
- url: "https://pub.flutter-io.cn"
+ sha256: a937da4c006989739ceb4d10e3bd6cce64ca85d0fe287fc5b2b9f6ee757dcee6
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "0.1.3"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.flutter-io.cn"
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.2.0"
+ version: "1.3.1"
+ file_selector_linux:
+ dependency: transitive
+ description:
+ name: file_selector_linux
+ sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.9.2+1"
+ file_selector_macos:
+ dependency: transitive
+ description:
+ name: file_selector_macos
+ sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.9.3+3"
+ file_selector_platform_interface:
+ dependency: transitive
+ description:
+ name: file_selector_platform_interface
+ sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "2.6.1"
+ file_selector_windows:
+ dependency: transitive
+ description:
+ name: file_selector_windows
+ sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.9.3+1"
flutter:
dependency: "direct main"
description: flutter
@@ -66,91 +106,223 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
- url: "https://pub.flutter-io.cn"
+ sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.0.11"
+ version: "2.0.17"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
http:
dependency: transitive
description:
name: http
- url: "https://pub.flutter-io.cn"
+ sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "0.12.2"
+ version: "0.13.6"
http_parser:
dependency: transitive
description:
name: http_parser
- url: "https://pub.flutter-io.cn"
+ sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "3.1.4"
+ version: "4.0.2"
image_picker:
dependency: "direct main"
description:
- name: image_picker
- url: "https://pub.flutter-io.cn"
+ path: "packages/image_picker/image_picker"
+ ref: HEAD
+ resolved-ref: fa347ab8df0ce39c547d576d785ed670ec25a919
+ url: "https://gitee.com/openharmony-sig/flutter_packages.git"
+ source: git
+ version: "1.0.2"
+ image_picker_android:
+ dependency: transitive
+ description:
+ name: image_picker_android
+ sha256: d6a6e78821086b0b737009b09363018309bbc6de3fd88cc5c26bc2bb44a4957f
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.8.8+2"
+ image_picker_for_web:
+ dependency: transitive
+ description:
+ name: image_picker_for_web
+ sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "3.0.1"
+ image_picker_ios:
+ dependency: transitive
+ description:
+ name: image_picker_ios
+ sha256: "76ec722aeea419d03aa915c2c96bf5b47214b053899088c9abb4086ceecf97a7"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.8.8+4"
+ image_picker_linux:
+ dependency: transitive
+ description:
+ name: image_picker_linux
+ sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "0.6.7+14"
+ version: "0.2.1+1"
+ image_picker_macos:
+ dependency: transitive
+ description:
+ name: image_picker_macos
+ sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.2.1+1"
+ image_picker_ohos:
+ dependency: transitive
+ description:
+ path: "packages/image_picker/image_picker_ohos"
+ ref: HEAD
+ resolved-ref: fa347ab8df0ce39c547d576d785ed670ec25a919
+ url: "https://gitee.com/openharmony-sig/flutter_packages.git"
+ source: git
+ version: "0.8.7+4"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
- url: "https://pub.flutter-io.cn"
+ sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.1"
+ version: "2.9.1"
+ image_picker_windows:
+ dependency: transitive
+ description:
+ name: image_picker_windows
+ sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.2.1+1"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.6.5"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.flutter-io.cn"
+ sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.12.13"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "0.12.10"
+ version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.flutter-io.cn"
+ sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.3.0"
- path:
+ version: "1.8.0"
+ mime:
dependency: transitive
description:
- name: path
- url: "https://pub.flutter-io.cn"
+ name: mime
+ sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.8.0"
- pedantic:
+ version: "1.0.4"
+ path:
dependency: transitive
description:
- name: pedantic
- url: "https://pub.flutter-io.cn"
+ name: path
+ sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.9.2"
+ version: "1.8.2"
permission_handler:
dependency: "direct main"
description:
- name: permission_handler
- url: "https://pub.flutter-io.cn"
+ path: permission_handler
+ ref: HEAD
+ resolved-ref: "0795d78231400c6b3d22304bffcdd1984e75623d"
+ url: "https://gitee.com/openharmony-sig/flutter_permission_handler.git"
+ source: git
+ version: "10.4.3"
+ permission_handler_android:
+ dependency: transitive
+ description:
+ name: permission_handler_android
+ sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "10.3.6"
+ permission_handler_apple:
+ dependency: transitive
+ description:
+ name: permission_handler_apple
+ sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "9.1.4"
+ permission_handler_ohos:
+ dependency: transitive
+ description:
+ path: permission_handler_ohos
+ ref: master
+ resolved-ref: "0795d78231400c6b3d22304bffcdd1984e75623d"
+ url: "https://gitee.com/openharmony-sig/flutter_permission_handler.git"
+ source: git
+ version: "10.3.2"
+ permission_handler_platform_interface:
+ dependency: transitive
+ description:
+ name: permission_handler_platform_interface
+ sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "3.3.0"
+ version: "3.12.0"
+ permission_handler_windows:
+ dependency: transitive
+ description:
+ name: permission_handler_windows
+ sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.1.3"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
- url: "https://pub.flutter-io.cn"
+ sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.0.3"
+ version: "2.1.6"
r_scan:
dependency: "direct dev"
description:
path: ".."
relative: true
source: path
- version: "0.1.6"
+ version: "0.1.6+1"
sky_engine:
dependency: transitive
description: flutter
@@ -160,58 +332,66 @@ packages:
dependency: transitive
description:
name: source_span
- url: "https://pub.flutter-io.cn"
+ sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.8.1"
+ version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.flutter-io.cn"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.10.0"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.flutter-io.cn"
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.flutter-io.cn"
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.0"
+ version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.flutter-io.cn"
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.2.0"
+ version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.flutter-io.cn"
+ sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "0.3.0"
+ version: "0.4.16"
typed_data:
dependency: transitive
description:
name: typed_data
- url: "https://pub.flutter-io.cn"
+ sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.3.0"
+ version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
- url: "https://pub.flutter-io.cn"
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.1.0"
+ version: "2.1.4"
sdks:
- dart: ">=2.12.0 <3.0.0"
- flutter: ">=1.12.13"
+ dart: ">=2.19.0 <3.0.0"
+ flutter: ">=3.7.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index a5620d09f59b8c89a2d2761b47b89fb28bcdf7a3..42deb1e48ab0dc93f11ac961b17e6d7cb9178a14 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -10,11 +10,17 @@ dependencies:
flutter:
sdk: flutter
#权限请求
- permission_handler: ^3.0.0
+ permission_handler:
+ git:
+ url: "https://gitee.com/openharmony-sig/flutter_permission_handler.git"
+ path: "permission_handler"
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
- image_picker: ^0.6.1+10
+ image_picker:
+ git:
+ url: "https://gitee.com/openharmony-sig/flutter_packages.git"
+ path: "packages/image_picker/image_picker"
dev_dependencies:
flutter_test:
sdk: flutter
diff --git a/lib/r_scan.dart b/lib/r_scan.dart
index b0e7563f27968b56c955ea3585abaebdc0a2d4a3..0f6253e1b6e01f04fe82de2edf2e6736b3fcb455 100644
--- a/lib/r_scan.dart
+++ b/lib/r_scan.dart
@@ -117,8 +117,8 @@ class RScanResult {
? (map['points'] as List)
.map(
(data) => RScanPoint(
- data['X'],
- data['Y'],
+ data['X'].toDouble(),
+ data['Y'].toDouble(),
),
)
.toList()
diff --git a/lib/src/r_scan_view.dart b/lib/src/r_scan_view.dart
index f71eed63ab103e6f7d2fcf55a0bb588fcd967988..65ba7e4a1d22c66190a6c357fc2adc56c2289acf 100644
--- a/lib/src/r_scan_view.dart
+++ b/lib/src/r_scan_view.dart
@@ -6,6 +6,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
+import 'package:flutter/foundation.dart';
import '../r_scan.dart';
@@ -50,20 +51,27 @@ class _RScanViewState extends State {
"isPlay": _controller.isPlay,
};
Widget child;
- if (Platform.isAndroid) {
+ if (defaultTargetPlatform == TargetPlatform.android) {
child = AndroidView(
viewType: _scanType,
onPlatformViewCreated: onPlatformViewCreated,
creationParams: params,
creationParamsCodec: StandardMessageCodec(),
);
- } else if (Platform.isIOS) {
+ } else if (defaultTargetPlatform == TargetPlatform.iOS) {
child = UiKitView(
viewType: _scanType,
onPlatformViewCreated: onPlatformViewCreated,
creationParams: params,
creationParamsCodec: StandardMessageCodec(),
);
+ } else if (defaultTargetPlatform == TargetPlatform.ohos) {
+ child = OhosView(
+ viewType: _scanType,
+ onPlatformViewCreated: onPlatformViewCreated,
+ creationParams: params,
+ creationParamsCodec: StandardMessageCodec(),
+ );
} else {
child = Container(
child: Text('Not support ${Platform.operatingSystem} platform.'),
diff --git a/ohos/.gitignore b/ohos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/ohos/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/ohos/BuildProfile.ets b/ohos/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..c7fd7d77a23ab1f7fc61ea94df328906455050ae
--- /dev/null
+++ b/ohos/BuildProfile.ets
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+export default class BuildProfile {
+ static readonly HAR_VERSION = '1.0.0';
+ static readonly BUILD_MODE_NAME = 'debug';
+ static readonly DEBUG = true;
+ static readonly TARGET_NAME = 'default';
+}
\ No newline at end of file
diff --git a/ohos/Index.ets b/ohos/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d0c91c9fb31c4d37bb432bcc60a696f8030e5640
--- /dev/null
+++ b/ohos/Index.ets
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import RScanPlugin from './src/main/ets/RScanPlugin'
+export default RScanPlugin
diff --git a/ohos/build-profile.json5 b/ohos/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..697dff23e224373edb713dc2b8a08ed7341d5b4c
--- /dev/null
+++ b/ohos/build-profile.json5
@@ -0,0 +1,31 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": true,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ },
+ "consumerFiles": [
+ "./consumer-rules.txt"
+ ]
+ }
+ },
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest"
+ }
+ ]
+}
diff --git a/ohos/consumer-rules.txt b/ohos/consumer-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ohos/hvigorfile.ts b/ohos/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12a327db0aeeb9462eb1dc098f5e808df40e3dce
--- /dev/null
+++ b/ohos/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { harTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/ohos/obfuscation-rules.txt b/ohos/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..69c4d6a8a5531548e4886fa766090c5c157a87d9
--- /dev/null
+++ b/ohos/obfuscation-rules.txt
@@ -0,0 +1,18 @@
+# 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
\ No newline at end of file
diff --git a/ohos/oh-package-lock.json5 b/ohos/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..91decb0cba331c12cc94499cc5935b0c0f229b53
--- /dev/null
+++ b/ohos/oh-package-lock.json5
@@ -0,0 +1,38 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/flutter_ohos@../example/ohos/har/flutter.har": "@ohos/flutter_ohos@../example/ohos/har/flutter.har",
+ "@ohos/zxing@^2.0.3": "@ohos/zxing@2.0.3",
+ "@zxing/text-encoding@^0.9.0": "@zxing/text-encoding@0.9.0"
+ },
+ "packages": {
+ "@ohos/flutter_ohos@../example/ohos/har/flutter.har": {
+ "name": "flutter",
+ "version": "1.0.0-20240802",
+ "resolved": "../example/ohos/har/flutter.har",
+ "registryType": "local"
+ },
+ "@ohos/zxing@2.0.3": {
+ "name": "@ohos/zxing",
+ "version": "2.0.3",
+ "integrity": "sha512-Gj5zkETMqrxs3ji/uXmixfiiGtx2YCMxc+JNnSOaXEsUFWgceksjqUF+ZxXPdWcwHMYTd6NhqJ2g2b2JUZrF6Q==",
+ "resolved": "https://repo.harmonyos.com/ohpm/@ohos/zxing/-/zxing-2.0.3.har",
+ "registryType": "ohpm",
+ "dependencies": {
+ "@zxing/text-encoding": "^0.9.0"
+ }
+ },
+ "@zxing/text-encoding@0.9.0": {
+ "name": "@zxing/text-encoding",
+ "version": "0.9.0",
+ "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
+ "resolved": "https://repo.harmonyos.com/ohpm/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
+ "shasum": "fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b",
+ "registryType": "ohpm"
+ }
+ }
+}
\ No newline at end of file
diff --git a/ohos/oh-package.json5 b/ohos/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..675bd90ceb95812b9f751c7b4ac9f127044c1d27
--- /dev/null
+++ b/ohos/oh-package.json5
@@ -0,0 +1,11 @@
+{
+ "name": "r_scan",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "Index.ets",
+ "author": "",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ohos/flutter_ohos": "file:./har/flutter.har",
+ }
+}
diff --git a/ohos/src/main/ets/ImageScanHelper.ets b/ohos/src/main/ets/ImageScanHelper.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7a69823576d52d7ea370278ee129b3b3174d539b
--- /dev/null
+++ b/ohos/src/main/ets/ImageScanHelper.ets
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { detectBarcode, scanBarcode } from '@kit.ScanKit';
+import { http } from '@kit.NetworkKit';
+import { image } from '@kit.ImageKit';
+import { fileIo as fs } from '@kit.CoreFileKit';
+import { Log, MethodCall, MethodResult } from '@ohos/flutter_ohos';
+import { RScanResult, RScanResultUtils } from './RScanResultUtils';
+
+const TAG: string = "ImageScanHelper";
+
+export class ImageScanHelper {
+ constructor() {
+ Log.i(TAG, 'constructor')
+ }
+
+ public async scanImagePath(call: MethodCall, result: MethodResult) {
+ let path: string = call.argument("path");
+ if (path == null) {
+ result.error("1001", "please enter your file path", null);
+ return;
+ }
+ let res: scanBarcode.ScanResult[] = await detectBarcode.decode({ uri: path })
+ let resultData = RScanResultUtils.toResult(res[0])
+ result.success(resultData)
+ }
+
+ public async scanImageUrl(call: MethodCall, result: MethodResult) {
+ const url: string = call.argument("url");
+ if (url == null) {
+ result.error("1002", "please enter your url", null);
+ return;
+ }
+ let httpRequest = http.createHttp();
+ let resultData: RScanResult | null = null
+ try {
+ //请求图片并打包成文件
+ let data = await httpRequest.request(url)
+ let imgData = data.result
+ if (imgData instanceof ArrayBuffer) {
+ let imgSource = image.createImageSource(imgData)
+ const imagePackerApi: image.ImagePacker = image.createImagePacker();
+ let file = fs.openSync(getContext().cacheDir + '/result.jpg', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
+ await imagePackerApi.packToFile(imgSource, file.fd, { format: 'image/jpeg', quality: 100 })
+ fs.closeSync(file)
+ //调用接口进行二维码识别
+ let res: scanBarcode.ScanResult[] = await detectBarcode.decode({ uri: getContext().cacheDir + '/result.jpg' })
+ resultData = RScanResultUtils.toResult(res[0])
+ }
+ result.success(resultData)
+ } catch (error) {
+ Log.e(TAG, 'scanImageMemory Catch , error = ' + JSON.stringify(error));
+ result.success(null)
+ }
+ }
+
+ public async scanImageMemory(call: MethodCall, result: MethodResult) {
+ const uint8list: Uint8Array = call.argument("uint8list");
+ if (uint8list == null) {
+ result.error("1003", "uint8list is not null", null);
+ return;
+ }
+ let arrBuff = uint8list.buffer
+ try {
+ //先将图片打包为图片文件
+ let imgDatas = image.createImageSource(arrBuff)
+ const imagePackerApi: image.ImagePacker = image.createImagePacker();
+ let file = fs.openSync(getContext().cacheDir + '/result.jpg', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
+ await imagePackerApi.packToFile(imgDatas, file.fd, { format: 'image/jpeg', quality: 100 })
+ fs.closeSync(file)
+ //调用接口进行二维码识别
+ let res: scanBarcode.ScanResult[] = await detectBarcode.decode({ uri: getContext().cacheDir + '/result.jpg' })
+ let resultData = RScanResultUtils.toResult(res[0])
+ result.success(resultData)
+ } catch (error) {
+ Log.e(TAG, 'scanImageMemory Catch , error = ' + JSON.stringify(error));
+ result.success(null)
+ }
+ }
+}
diff --git a/ohos/src/main/ets/MethodCallHandlerImpl.ets b/ohos/src/main/ets/MethodCallHandlerImpl.ets
new file mode 100644
index 0000000000000000000000000000000000000000..284cfe44bd09fcce6d94e04b433cd251f7750275
--- /dev/null
+++ b/ohos/src/main/ets/MethodCallHandlerImpl.ets
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import UIAbility from '@ohos.app.ability.UIAbility';
+import {
+ BinaryMessenger,
+ Log,
+ MethodCall,
+ MethodCallHandler,
+ MethodChannel,
+ MethodResult,
+ TextureRegistry
+} from '@ohos/flutter_ohos';
+import { ImageScanHelper } from './ImageScanHelper';
+import { RScanCameraMethodHandler } from './RScanCamera/RScanCameraMethodHandler';
+
+const TAG: string = "MethodCallHandlerImpl";
+
+export class MethodCallHandlerImpl implements MethodCallHandler {
+ private scanHelper?: ImageScanHelper;
+ private ability: UIAbility;
+ private messenger: BinaryMessenger;
+ private textureRegistry: TextureRegistry;
+ private methodChannel?: MethodChannel;
+
+ constructor(ability: UIAbility, messenger: BinaryMessenger, textureRegistry: TextureRegistry) {
+ Log.i(TAG, "MethodCallHandlerImpl constructor");
+ this.ability = ability;
+ this.messenger = messenger;
+ this.textureRegistry = textureRegistry;
+ this.scanHelper = new ImageScanHelper();
+ this.methodChannel = new MethodChannel(messenger, "com.rhyme_lph/r_scan");
+ this.methodChannel.setMethodCallHandler(this);
+
+ new RScanCameraMethodHandler(
+ this.ability,
+ this.messenger,
+ this.textureRegistry
+ );
+ }
+
+ stopListening(): void {
+ this.methodChannel?.setMethodCallHandler(null);
+ }
+
+ onMethodCall(call: MethodCall, result: MethodResult): void {
+ Log.i(TAG, "MethodCallHandlerImpl onMethodCall : " + call.method);
+ if (this.scanHelper) {
+ if (call.method == "scanImagePath") {
+ this.scanHelper.scanImagePath(call, result);
+ } else if (call.method == "scanImageUrl") {
+ this.scanHelper.scanImageUrl(call, result);
+ } else if (call.method == "scanImageMemory") {
+ this.scanHelper.scanImageMemory(call, result);
+ } else {
+ result.notImplemented();
+ }
+ }
+ }
+}
diff --git a/ohos/src/main/ets/RScanCamera/CameraUtils.ets b/ohos/src/main/ets/RScanCamera/CameraUtils.ets
new file mode 100644
index 0000000000000000000000000000000000000000..96bc228cb288022989fb5ebf65648d7ad4114d42
--- /dev/null
+++ b/ohos/src/main/ets/RScanCamera/CameraUtils.ets
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { camera } from '@kit.CameraKit';
+import common from '@ohos.app.ability.common';
+import { Size } from '@kit.ArkUI';
+
+export interface CamerasInfo {
+ name: string
+ lensFacing: string
+}
+
+export class CameraUtils {
+ public static getAvailableCameras(context: common.Context): Array {
+ //获取相机
+ let cameraManager: camera.CameraManager = camera.getCameraManager(context);
+ let cameras: Array = cameraManager.getSupportedCameras();
+ let camerasInfo: CamerasInfo[] = []
+ for (let device of cameras) {
+ let lensFacing = 'null'
+ switch (device.cameraPosition) {
+ case camera.CameraPosition.CAMERA_POSITION_BACK:
+ lensFacing = 'back'
+ break
+ case camera.CameraPosition.CAMERA_POSITION_FRONT:
+ lensFacing = 'front'
+ break
+ case camera.CameraPosition.CAMERA_POSITION_FOLD_INNER:
+ lensFacing = 'fold_inner'
+ break
+ default:
+ lensFacing = 'external'
+ break
+ }
+ //只传后摄像头
+ if (lensFacing == 'back') {
+ camerasInfo.push({
+ name: device.cameraId,
+ lensFacing: lensFacing
+ })
+ }
+ }
+ return camerasInfo;
+ }
+
+ public static getCameraPreviewSize(context: common.Context, cameraName: string): Size {
+ let cameraManager: camera.CameraManager = camera.getCameraManager(context);
+ let cameras: Array = cameraManager.getSupportedCameras();
+ let cameraDevice = cameras.find(item => item.cameraId == cameraName) as camera.CameraDevice;
+ let cameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraDevice, 1);
+ let previewSize: Size = cameraOutputCapability.previewProfiles[0].size;
+ return previewSize;
+ }
+}
\ No newline at end of file
diff --git a/ohos/src/main/ets/RScanCamera/RScanCamera.ets b/ohos/src/main/ets/RScanCamera/RScanCamera.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0e52d8d0a99631a687cde37e0f57b2ea888c76a4
--- /dev/null
+++ b/ohos/src/main/ets/RScanCamera/RScanCamera.ets
@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import common from '@ohos.app.ability.common';
+import { Size } from '@kit.ArkUI';
+import { customScan, scanBarcode, scanCore } from '@kit.ScanKit';
+import { MethodResult, SurfaceTextureEntry, Log } from '@ohos/flutter_ohos';
+import { RScanMessenger } from './RScanMessenger';
+import { RScanResultUtils } from '../RScanResultUtils';
+import { CameraUtils } from './CameraUtils';
+import { BusinessError } from '@kit.BasicServicesKit';
+
+export enum ResolutionPreset {
+ low,
+ medium,
+ high,
+ veryHigh,
+ ultraHigh,
+ max,
+}
+
+const TAG: string = "RScanCamera";
+
+export class RScanCamera {
+ private context: common.Context;
+ private flutterTexture: SurfaceTextureEntry;
+ private cameraName: string;
+ private previewSize: Size;
+ private rScanMessenger: RScanMessenger;
+ private isScan: boolean = true;
+ private isAutoOpenFlash: boolean = false;
+
+ constructor(context: common.Context,
+ flutterTexture: SurfaceTextureEntry,
+ cameraName: string,
+ rScanMessenger: RScanMessenger) {
+ this.context = context
+ this.cameraName = cameraName;
+ this.flutterTexture = flutterTexture;
+ this.rScanMessenger = rScanMessenger;
+ this.previewSize = CameraUtils.getCameraPreviewSize(this.context, this.cameraName);
+ //注册闪光灯亮度变化回调 api12 Beta3支持
+ // customScan.on('lightingFlash', this.lightingFlashChange)
+ Log.i(TAG, "previewSize" + JSON.stringify(this.previewSize));
+ }
+
+ startScan(): void {
+ if (this.isScan) {
+ return
+ }
+ this.isScan = true
+ let viewControl: customScan.ViewControl = {
+ width: this.previewSize.width,
+ height: this.previewSize.height,
+ surfaceId: this.flutterTexture.getSurfaceId().toString()
+ }
+ customScan.start(viewControl).then((data) => {
+ Log.w(TAG, "startScan result" + JSON.stringify(data));
+ this.scanResultSend(data)
+ })
+ }
+
+ stopScan(): void {
+ if (this.isScan) {
+ this.isScan = false
+ customScan.stop()
+ }
+ }
+
+ enableTorch(b: boolean): void {
+ if (b) {
+ customScan.openFlashLight()
+ } else {
+ customScan.closeFlashLight()
+ }
+ }
+
+ setAutoFlash(b: boolean): void {
+ this.isAutoOpenFlash = b
+ }
+
+ lightingFlashChange(e: BusinessError, data: boolean) {
+ if (e) {
+ Log.w(TAG, "lightingFlashChange err" + JSON.stringify(e));
+ return;
+ }
+ if (this.isAutoOpenFlash) {
+ if (data) {
+ customScan.openFlashLight()
+ } else {
+ customScan.closeFlashLight()
+ }
+ }
+ }
+
+ isTorchOn(): boolean {
+ let torchStat = false;
+ try {
+ torchStat = customScan.getFlashLightStatus();
+ } catch (e) {
+ Log.w(TAG, "isTorchOn err" + JSON.stringify(e));
+ }
+ return torchStat;
+ }
+
+ open(result: MethodResult): void {
+ let options: scanBarcode.ScanOptions = {
+ scanTypes: [scanCore.ScanType.ALL],
+ enableMultiMode: true,
+ enableAlbum: true
+ }
+ customScan.init(options)
+ let viewControl: customScan.ViewControl = {
+ width: this.previewSize.width,
+ height: this.previewSize.height,
+ surfaceId: this.flutterTexture.getSurfaceId().toString()
+ }
+ customScan.start(viewControl).then((data) => {
+ Log.w(TAG, "startScan result" + JSON.stringify(data));
+ this.scanResultSend(data)
+ })
+ result.success({
+ textureId: this.flutterTexture.getTextureId(),
+ previewWidth: this.previewSize.width,
+ previewHeight: this.previewSize.height
+ })
+ }
+
+ scanResultSend(data: scanBarcode.ScanResult[]) {
+ let result = RScanResultUtils.toResult(data[0])
+ if (this.rScanMessenger && result) {
+ this.rScanMessenger.send(result)
+ customScan.release()
+ }
+ }
+
+ dispose(): void {
+ //注册闪光灯亮度变化回调 api12 Beta3支持
+ // customScan.off('lightingFlash')
+ customScan.release()
+ }
+}
diff --git a/ohos/src/main/ets/RScanCamera/RScanCameraMethodHandler.ets b/ohos/src/main/ets/RScanCamera/RScanCameraMethodHandler.ets
new file mode 100644
index 0000000000000000000000000000000000000000..2ed60031274892c2031f68c0106e1dbd6a9b9e5e
--- /dev/null
+++ b/ohos/src/main/ets/RScanCamera/RScanCameraMethodHandler.ets
@@ -0,0 +1,147 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import UIAbility from '@ohos.app.ability.UIAbility';
+import {
+ BinaryMessenger,
+ Log,
+ MethodCall,
+ MethodChannel,
+ MethodResult,
+ StandardMethodCodec,
+ SurfaceTextureEntry,
+ TextureRegistry
+} from '@ohos/flutter_ohos';
+import { CameraUtils } from './CameraUtils';
+import { RScanCamera } from './RScanCamera';
+import { RScanMessenger } from './RScanMessenger';
+
+
+const TAG: string = "RScanCameraMethodHandler";
+
+export class RScanCameraMethodHandler extends MethodChannel {
+ private static scanViewType: string = "com.rhyme_lph/r_scan_camera";
+ private textureRegistry: TextureRegistry;
+ private ability: UIAbility;
+ private messengers: BinaryMessenger;
+ private rScanCamera: RScanCamera | null = null;
+ private flutterTexture: SurfaceTextureEntry | null = null;
+ private textureId: number = -1;
+ private rScanMessenger: RScanMessenger | null = null;
+
+ constructor(ability: UIAbility,
+ messenger: BinaryMessenger,
+ textureRegistry: TextureRegistry) {
+ super(messenger, RScanCameraMethodHandler.scanViewType, StandardMethodCodec.INSTANCE)
+ this.messengers = messenger
+ this.ability = ability;
+ this.textureRegistry = textureRegistry;
+ let methodChannel: MethodChannel = new MethodChannel(messenger, RScanCameraMethodHandler.scanViewType + "/method");
+ methodChannel.setMethodCallHandler(this);
+ }
+
+ private registerCameraTexture(): void {
+ this.textureId = this.textureRegistry.getTextureId();
+ this.flutterTexture = this.textureRegistry.registerTexture(this.textureId);
+ }
+
+ onMethodCall(call: MethodCall, result: MethodResult): void {
+ Log.i(TAG, "RScanCameraMethodHandler onMethodCall ");
+ switch (call.method) {
+ case "availableCameras":
+ try {
+ let cameras = CameraUtils.getAvailableCameras(this.ability.context)
+ Log.i(TAG, "RScanCameraMethodHandler onMethodCall " + cameras.length);
+ Log.i(TAG, "RScanCameraMethodHandler onMethodCall " + JSON.stringify(cameras));
+ result.success(cameras);
+ } catch (e) {
+ result.error('CameraAccess', 'Catch: startScan error = ' + JSON.stringify(e), null);
+ }
+ break;
+ case "initialize":
+ this.instantiateCamera(call, result);
+ break;
+ case "startScan":
+ if (this.rScanCamera != null) {
+ this.rScanCamera.startScan();
+ }
+ result.success(null);
+ break;
+ case "stopScan":
+ if (this.rScanCamera != null) {
+ this.rScanCamera.stopScan();
+ }
+ result.success(null);
+ break;
+ case "setAutoFlashMode":
+ let isAuto: boolean = call.argument("isAuto") as boolean;
+ if (this.rScanCamera != null) {
+ this.rScanCamera.setAutoFlash(isAuto);
+ result.success(true);
+ } else {
+ result.success(true);
+ }
+ break;
+ case "setFlashMode":
+ let isOpen: boolean = call.argument("isOpen") as boolean;
+ if (this.rScanCamera != null) {
+ try {
+ this.rScanCamera.enableTorch(isOpen);
+ } catch (e) {
+ Log.i(TAG, "RScanCameraMethodHandler onMethodCall setFlashMode Err" + JSON.stringify(e));
+ }
+ result.success(true);
+ } else {
+ result.success(true);
+ }
+ break;
+ case "getFlashMode":
+ if (this.rScanCamera != null) {
+ result.success(this.rScanCamera.isTorchOn());
+ } else {
+ result.success(false);
+ }
+ break;
+ case "dispose": {
+ if (this.rScanCamera != null) {
+ this.rScanCamera.dispose();
+ }
+ result.success(null);
+ break;
+ }
+ default:
+ result.notImplemented();
+ break;
+ }
+ }
+
+ //初始化相机
+ private instantiateCamera(call: MethodCall, result: MethodResult): void {
+ let cameraName: string = call.argument("cameraName");
+ Log.i(TAG, "instantiateCamera cameraName : " + cameraName);
+ let resolutionPreset: string = call.argument("resolutionPreset");
+ Log.i(TAG, "instantiateCamera resolutionPreset : " + resolutionPreset);
+ this.registerCameraTexture();
+ if (this.flutterTexture) {
+ this.rScanMessenger = new RScanMessenger(this.messengers, this.flutterTexture?.getTextureId());
+ this.rScanCamera =
+ new RScanCamera(this.ability.context, this.flutterTexture, cameraName, this.rScanMessenger);
+ }
+ if (this.rScanCamera) {
+ this.rScanCamera.open(result);
+ }
+ }
+
+}
diff --git a/ohos/src/main/ets/RScanCamera/RScanMessenger.ets b/ohos/src/main/ets/RScanCamera/RScanMessenger.ets
new file mode 100644
index 0000000000000000000000000000000000000000..18c3a8d3618cc25fbde6ce46c84fada89e6b1a04
--- /dev/null
+++ b/ohos/src/main/ets/RScanCamera/RScanMessenger.ets
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { BinaryMessenger, EventChannel, Log } from '@ohos/flutter_ohos';
+import { EventSink } from '@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel';
+import { RScanResult } from '../RScanResultUtils';
+
+const TAG: string = "RScanMessenger";
+const scanViewType: string = "com.rhyme_lph/r_scan_camera";
+
+export class RScanMessenger {
+ public eventSink: EventSink | null = null;
+
+ constructor(messenger: BinaryMessenger, eventChannelId: number) {
+ new EventChannel(messenger, scanViewType + "_" + eventChannelId + "/event").setStreamHandler(this);
+ }
+
+ onListen(arg: Object, sink: EventSink) {
+ this.eventSink = sink
+ }
+
+ onCancel(arg: Object) {
+ Log.i(TAG, "onCancel");
+ this.eventSink = null;
+ }
+
+ send(decode: RScanResult): void {
+ Log.i(TAG, "send " + JSON.stringify(decode));
+ if (this.eventSink == null) {
+ return;
+ }
+ this.eventSink.success(decode);
+ }
+
+}
+
+
diff --git a/ohos/src/main/ets/RScanPlugin.ets b/ohos/src/main/ets/RScanPlugin.ets
new file mode 100644
index 0000000000000000000000000000000000000000..35fa8a5b06c6d83c2f80e52240794fec6b403edd
--- /dev/null
+++ b/ohos/src/main/ets/RScanPlugin.ets
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import UIAbility from '@ohos.app.ability.UIAbility';
+import window from '@ohos.window';
+import {
+ AbilityAware,
+ AbilityPluginBinding,
+ BinaryMessenger,
+ FlutterManager,
+ FlutterPlugin,
+ FlutterPluginBinding,
+ Log,
+ TextureRegistry
+} from '@ohos/flutter_ohos';
+import { MethodCallHandlerImpl } from './MethodCallHandlerImpl';
+import { RScanViewFactory } from './RScanView/RScanViewFactory';
+
+const TAG: string = "RScanPlugin";
+
+export default class RScanPlugin implements FlutterPlugin, AbilityAware {
+ private pluginBinding: FlutterPluginBinding | null = null;
+ private methodCallHandler: MethodCallHandlerImpl | null = null;
+ private mainWindow: window.Window | null = null;
+
+ getUniqueClassName(): string {
+ return TAG;
+ }
+
+ maybeStartListening(context: UIAbility, messenger: BinaryMessenger, textureRegistry: TextureRegistry) {
+ this.methodCallHandler = new MethodCallHandlerImpl(context, messenger, textureRegistry)
+ }
+
+ onAttachedToEngine(binding: FlutterPluginBinding): void {
+ this.pluginBinding = binding;
+ }
+
+ onDetachedFromEngine(binding: FlutterPluginBinding): void {
+ this.pluginBinding = null;
+ }
+
+ onAttachedToAbility(binding: AbilityPluginBinding): void {
+ Log.i(TAG, "onAttachedToAbility");
+ if (!binding || !this.pluginBinding) {
+ return
+ }
+ this.maybeStartListening(
+ binding.getAbility(),
+ this.pluginBinding.getBinaryMessenger(),
+ this.pluginBinding.getTextureRegistry());
+
+ this.mainWindow = FlutterManager.getInstance()
+ .getWindowStage(FlutterManager.getInstance().getUIAbility(binding.getAbility().context))
+ .getMainWindowSync();
+
+ this.pluginBinding.getPlatformViewRegistry()
+ .registerViewFactory(
+ "com.rhyme_lph/r_scan_view",
+ new RScanViewFactory(this.pluginBinding.getBinaryMessenger(),
+ this.mainWindow));
+ }
+
+ onDetachedFromAbility(): void {
+ if (this.methodCallHandler == null) {
+ return;
+ }
+ this.methodCallHandler.stopListening();
+ this.methodCallHandler = null;
+ }
+}
+
diff --git a/ohos/src/main/ets/RScanResultUtils.ets b/ohos/src/main/ets/RScanResultUtils.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a0c94891693113948526a8aa338a0a5a7e9d1d41
--- /dev/null
+++ b/ohos/src/main/ets/RScanResultUtils.ets
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { scanBarcode } from '@kit.ScanKit';
+import { Log } from '@ohos/flutter_ohos';
+
+export interface Point {
+ X: number;
+ Y: number;
+}
+
+export interface RScanResult {
+ type?: number
+ message?: string
+ points?: Point[]
+}
+
+const TAG: string = "RScanResultUtils";
+
+export class RScanResultUtils {
+ public static toResult(result: scanBarcode.ScanResult): RScanResult | null {
+ Log.i(TAG, 'Result : ' + JSON.stringify(result))
+ if (result == null) {
+ return null
+ }
+ let data: RScanResult = {};
+ data.type = result.scanType
+ data.message = result.originalValue
+ if (result.cornerPoints != null) {
+ let rScanPointList: Array = []
+ result.cornerPoints.forEach((item) => {
+ rScanPointList.push({ X: item.x, Y: item.y });
+ })
+ data.points = rScanPointList;
+ }
+ Log.i(TAG, 'toResult : ' + JSON.stringify(data))
+ return data;
+ }
+}
diff --git a/ohos/src/main/ets/RScanView/CameraConstants.ets b/ohos/src/main/ets/RScanView/CameraConstants.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f228dd7853dfb7564678c552aed51f664f39b281
--- /dev/null
+++ b/ohos/src/main/ets/RScanView/CameraConstants.ets
@@ -0,0 +1,116 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+/**
+ * 相机相关常量
+ */
+export default class CameraConstants {
+ /**
+ * 相机权限名称
+ */
+ static readonly PERMISSION_CAMERA = 'ohos.permission.CAMERA';
+ /**
+ * 相机流展示组件(XComponent)唯一标识
+ */
+ static readonly CAMERA_COMPONENT_ID = 'me.hetian.flutter_qr_reader_component_id';
+ /**
+ * 相机流展示组件(XComponent)类型
+ */
+ static readonly CAMERA_COMPONENT_TYPE = 'surface';
+ /**
+ * 相机扫描框顶部距离
+ */
+ static readonly SCAN_TO_TOP_HEIGHT = 120;
+ /**
+ * 相机闪光灯按钮尺寸
+ */
+ static readonly SCAN_FLASH_BUTTON_SIZE = 40;
+ /**
+ * 相机返回按钮尺寸
+ */
+ static readonly SCAN_CANCEL_BUTTON_SIZE = 40;
+ /**
+ * 相机扫描框尺寸
+ */
+ static readonly SCAN_BORDER_SIZE = 280;
+ /**
+ * 扫描动画组件线宽
+ */
+ static readonly SCAN_DIVIDER_STROKE_WIDTH = 1;
+ /**
+ * 扫描动画组件高度
+ */
+ static readonly SCAN_DIVIDER_HEIGHT = 4;
+ /**
+ * 扫描动画组件起点偏移量
+ */
+ static readonly SCAN_DIVIDER_OFFSET_BEGIN = 0;
+ /**
+ * 扫描动画组件终点偏移量
+ */
+ static readonly SCAN_DIVIDER_OFFSET_END = 390;
+ /**
+ * 组件安全边距
+ */
+ static readonly SCAN_SAFE_MARGINS = 24;
+ /**
+ * 组件宽度100%
+ */
+ static readonly SCAN_COMPONENT_WIDTH_100 = '100%';
+ /**
+ * 组件宽度50%
+ */
+ static readonly SCAN_COMPONENT_WIDTH_50 = '50%';
+ /**
+ * 组件位置X坐标
+ */
+ static readonly SCAN_COMPONENT_POSITION_X = 0;
+ /**
+ * 组件位置Y坐标
+ */
+ static readonly SCAN_COMPONENT_POSITION_Y= 0;
+ /**
+ * 组件translate X坐标
+ */
+ static readonly SCAN_COMPONENT_TRANSLATE_X= 0;
+ /**
+ * 按钮文字大小
+ */
+ static readonly SCAN_BUTTON_FONT_SIZE = 18;
+ /**
+ * 按钮和文字间距
+ */
+ static readonly SCAN_BUTTON_TEXT_SAFE_MARGINS = 4;
+ /**
+ * 多按钮之间安全间距
+ */
+ static readonly SCAN_BUTTON_SAFE_MARGINS = 50;
+ /**
+ * 按钮距离顶部距离
+ */
+ static readonly SCAN_BUTTON_TOP_MARGINS = 190;
+ /**
+ * 扫描动画配置
+ */
+ static readonly SCAN_ANI_CONFIG: AnimateParam = {
+ duration: 1000, // 动画时间
+ tempo: 0.5, // 动画速率
+ curve: Curve.EaseInOut,
+ delay: 200, // 动画延迟时间
+ iterations: -1, // 动画是否重复播放
+ playMode: PlayMode.Normal,
+ }
+}
+
diff --git a/ohos/src/main/ets/RScanView/CustomScanPage.ets b/ohos/src/main/ets/RScanView/CustomScanPage.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a6894962047d3e402882dabf21cd611130bc6312
--- /dev/null
+++ b/ohos/src/main/ets/RScanView/CustomScanPage.ets
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { window } from '@kit.ArkUI';
+import { Log } from '@ohos/flutter_ohos';
+import CameraConstants from './CameraConstants';
+import { FlutterRScanView } from './FlutterRScanView';
+
+const TAG: string = "CustomScanPage";
+
+@Component
+export struct CustomScanPage {
+ @State window: window.Window | null = null
+ private mXComponentController: XComponentController = new XComponentController();
+ private flutterRScanView: FlutterRScanView | null = null
+ @State previewWidth: number = 0
+ @State previewHeight: number = 0
+
+ build() {
+ Column() {
+ Stack() {
+ XComponent({
+ id: CameraConstants.CAMERA_COMPONENT_ID,
+ type: CameraConstants.CAMERA_COMPONENT_TYPE,
+ controller: this.mXComponentController
+ })
+ .onLoad(() => {
+ Log.i("FlutterQrReaderPlugin", 'XComponent onLoad')
+ if (this.flutterRScanView) {
+ this.flutterRScanView.setSurfaceId(this.mXComponentController.getXComponentSurfaceId())
+ this.flutterRScanView.startScan()
+ }
+ })
+ .width(this.previewWidth)
+ .height(this.previewHeight)
+ .position({
+ x: CameraConstants.SCAN_COMPONENT_POSITION_X,
+ y: CameraConstants.SCAN_COMPONENT_POSITION_Y
+ })
+ }
+ .alignContent(Alignment.Bottom)
+ .height(CameraConstants.SCAN_COMPONENT_WIDTH_100)
+ .width(CameraConstants.SCAN_COMPONENT_WIDTH_100)
+ .position({
+ x: CameraConstants.SCAN_COMPONENT_POSITION_X,
+ y: CameraConstants.SCAN_COMPONENT_POSITION_Y
+ })
+ .backgroundColor(Color.Grey)
+ }
+ .height(CameraConstants.SCAN_COMPONENT_WIDTH_100)
+ .width(CameraConstants.SCAN_COMPONENT_WIDTH_100)
+ .backgroundColor(Color.White)
+ }
+
+ aboutToAppear(): void {
+ Log.i(TAG, 'aboutToAppear')
+ if (this.flutterRScanView) {
+ this.previewWidth = this.flutterRScanView.getPreviewSize().width
+ this.previewHeight = this.flutterRScanView.getPreviewSize().height
+ }
+ }
+
+ aboutToDisappear() {
+ Log.i("FlutterQrReaderPlugin", 'aboutToDisappear')
+ }
+
+ updateCameraSurfaceSize(width: number, height: number): void {
+ this.mXComponentController.setXComponentSurfaceSize({
+ surfaceWidth: width,
+ surfaceHeight: height,
+ })
+ }
+
+}
diff --git a/ohos/src/main/ets/RScanView/FlutterRScanView.ets b/ohos/src/main/ets/RScanView/FlutterRScanView.ets
new file mode 100644
index 0000000000000000000000000000000000000000..25811949cfd869d8d66dc3a3cb4d1da30d7e1cdf
--- /dev/null
+++ b/ohos/src/main/ets/RScanView/FlutterRScanView.ets
@@ -0,0 +1,161 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { Size } from '@kit.ArkUI';
+import window from '@ohos.window';
+import common from '@ohos.app.ability.common';
+import { customScan, scanBarcode, scanCore } from '@kit.ScanKit';
+import { MethodCall, MethodCallHandler, MethodResult, Log, BinaryMessenger, MethodChannel } from '@ohos/flutter_ohos';
+import PlatformView, { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView';
+import EventChannel, { EventSink, StreamHandler } from '@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel';
+import { CustomScanPage } from './CustomScanPage';
+import { RScanResultUtils } from '../RScanResultUtils';
+import { CameraUtils } from '../RScanCamera/CameraUtils';
+
+
+const TAG: string = "FlutterRScanView";
+const scanViewType = "com.rhyme_lph/r_scan_view"
+
+let mainWindow: window.Window | null = null
+let flutterRScanView: FlutterRScanView | null = null
+
+@Observed
+export class FlutterRScanView extends PlatformView implements MethodCallHandler, StreamHandler, MethodCallHandler {
+ private eventSink: EventSink | null = null;
+ private surfaceId: string = '';
+ private previewSize: Size = { width: 100, height: 100 };
+ private isScan: boolean = false;
+ private customScanInitOptions: scanBarcode.ScanOptions = {
+ scanTypes: [scanCore.ScanType.ALL],
+ enableMultiMode: true,
+ enableAlbum: true
+ }
+
+ constructor(context: common.Context, messenger: BinaryMessenger, viewId: number, args: object,
+ mainWindow: window.Window) {
+ super()
+ mainWindow = mainWindow;
+ new EventChannel(messenger, scanViewType + "_" + viewId + "/event").setStreamHandler(this)
+ new MethodChannel(messenger, scanViewType + "_" + viewId + "/method").setMethodCallHandler(this)
+ flutterRScanView = this;
+ let cameras = CameraUtils.getAvailableCameras(context);
+ if (cameras.length > 0) {
+ this.previewSize = CameraUtils.getCameraPreviewSize(context, cameras[0].name)
+ }
+ }
+
+ setSurfaceId(surfaceId: string) {
+ this.surfaceId = surfaceId;
+ }
+
+ getPreviewSize() {
+ return this.previewSize;
+ }
+
+
+ public getView(): WrappedBuilder<[Params]> {
+ return new WrappedBuilder(WebBuilder);
+ }
+
+
+ onListen(args: Object, events: EventSink): void {
+ this.eventSink = events;
+ }
+
+ onCancel(args: Object): void {
+ Log.d("CameraX", "onCancel");
+ this.eventSink = null;
+ }
+
+ dispose() {
+ customScan.release();
+ }
+
+ public onMethodCall(call: MethodCall, result: MethodResult): void {
+ Log.i(TAG, 'onMethodCall = ' + call.method)
+ switch (call.method) {
+ case "startScan":
+ this.startScan()
+ result.success(null);
+ break;
+ case "stopScan":
+ this.stopScan();
+ result.success(null);
+ break;
+ case "setFlashMode":
+ let isOpen: boolean = call.argument("isOpen") as boolean;
+ if (isOpen) {
+ customScan.openFlashLight();
+ } else {
+ customScan.closeFlashLight();
+ }
+ result.success(true);
+ break;
+ case "getFlashMode":
+ let flashLightStatus = false
+ flashLightStatus = customScan.getFlashLightStatus();
+ result.success(flashLightStatus);
+ break;
+ default:
+ result.notImplemented();
+ break;
+ }
+ }
+
+ async startScan() {
+ if (this.isScan) {
+ return
+ }
+ this.isScan = true
+ try {
+ const viewControl: customScan.ViewControl = {
+ width: this.previewSize.width,
+ height: this.previewSize.height,
+ surfaceId: this.surfaceId
+ };
+ Log.i(TAG, 'startScan viewControl ' + JSON.stringify(viewControl));
+ customScan.init(this.customScanInitOptions);
+ customScan.start(viewControl).then((data) => {
+ let result = RScanResultUtils.toResult(data[0]);
+ customScan.release();
+ this.eventSink?.success(result);
+ })
+ } catch (error) {
+ Log.e(TAG, 'Catch: startScan error = ' + JSON.stringify(error));
+ }
+ }
+
+ async stopScan() {
+ try {
+ if (this.isScan) {
+ this.isScan = false
+ await customScan.stop();
+ await customScan.release();
+ }
+ } catch (error) {
+ Log.e(TAG, 'Catch: stopScan error = ' + JSON.stringify(error));
+ }
+ }
+
+ async restartScan() {
+ await this.stopScan();
+ await this.startScan();
+ }
+}
+
+@Builder
+function WebBuilder(params: Params) {
+ CustomScanPage({ window: mainWindow, flutterRScanView: flutterRScanView });
+}
\ No newline at end of file
diff --git a/ohos/src/main/ets/RScanView/RScanViewFactory.ets b/ohos/src/main/ets/RScanView/RScanViewFactory.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4b21719fc61e1f2bea1868a10c2f3fe0053190e7
--- /dev/null
+++ b/ohos/src/main/ets/RScanView/RScanViewFactory.ets
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import common from '@ohos.app.ability.common';
+import window from '@ohos.window';
+import { BinaryMessenger, PlatformView, PlatformViewFactory, StandardMessageCodec } from '@ohos/flutter_ohos';
+import { FlutterRScanView } from './FlutterRScanView';
+
+export class RScanViewFactory extends PlatformViewFactory {
+ private messenger: BinaryMessenger;
+ private mainWindow: window.Window;
+
+ constructor(messenger: BinaryMessenger, mainWindow: window.Window) {
+ super(StandardMessageCodec.INSTANCE);
+ this.messenger = messenger;
+ this.mainWindow = mainWindow;
+ }
+
+ public create(context: common.Context, viewId: number, args: object): PlatformView {
+ return new FlutterRScanView(context, this.messenger, viewId, args, this.mainWindow);
+ }
+}
diff --git a/ohos/src/main/ets/RScanView/RScanViewPlugin.ets b/ohos/src/main/ets/RScanView/RScanViewPlugin.ets
new file mode 100644
index 0000000000000000000000000000000000000000..6ce74190546f25122c1e850e311c61ef7054dc13
--- /dev/null
+++ b/ohos/src/main/ets/RScanView/RScanViewPlugin.ets
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import { BinaryMessenger, PlatformViewRegistry } from '@ohos/flutter_ohos';
+import { RScanViewFactory } from './RScanViewFactory';
+
+export class RScanViewPlugin {
+ public static registerWith(platformViewRegistry: PlatformViewRegistry, messenger: BinaryMessenger): void {
+ platformViewRegistry
+ .registerViewFactory("com.rhyme_lph/r_scan_view", new RScanViewFactory(messenger));
+ }
+}
diff --git a/ohos/src/main/module.json5 b/ohos/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..745339c168ae44540e11d73ff04fa9366405d80d
--- /dev/null
+++ b/ohos/src/main/module.json5
@@ -0,0 +1,10 @@
+{
+ "module": {
+ "name": "r_scan",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ]
+ }
+}
diff --git a/ohos/src/main/resources/base/element/string.json b/ohos/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607
--- /dev/null
+++ b/ohos/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from package"
+ }
+ ]
+}
diff --git a/ohos/src/main/resources/en_US/element/string.json b/ohos/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607
--- /dev/null
+++ b/ohos/src/main/resources/en_US/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from package"
+ }
+ ]
+}
diff --git a/ohos/src/main/resources/zh_CN/element/string.json b/ohos/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607
--- /dev/null
+++ b/ohos/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from package"
+ }
+ ]
+}
diff --git a/ohos/src/test/List.test.ets b/ohos/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..e3f1904373eb8182a07290c5b9a1287d1a9dd219
--- /dev/null
+++ b/ohos/src/test/List.test.ets
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+import localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/ohos/src/test/LocalUnit.test.ets b/ohos/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..13b2128b8428b9368a257451baf665e38434bbac
--- /dev/null
+++ b/ohos/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2024 SwanLink (Jiangsu) Technology Development 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.
+*/
+
+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/pubspec.lock b/pubspec.lock
index 02e1c6678b2ca57810f44d2d6864ce5744b6ec77..42e9344abda3bb6cbaa0d4806c33f73c489ca0c5 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,51 +5,50 @@ packages:
dependency: transitive
description:
name: async
- url: "https://pub.flutter-io.cn"
+ sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.6.1"
+ version: "2.10.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.flutter-io.cn"
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.flutter-io.cn"
+ sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.flutter-io.cn"
- source: hosted
- version: "1.2.0"
+ version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.flutter-io.cn"
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.0"
+ version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.flutter-io.cn"
+ sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.15.0"
+ version: "1.17.0"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.flutter-io.cn"
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.2.0"
+ version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
@@ -60,27 +59,46 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.6.5"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.flutter-io.cn"
+ sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
+ source: hosted
+ version: "0.12.13"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "0.12.10"
+ version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.flutter-io.cn"
+ sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.3.0"
+ version: "1.8.0"
path:
dependency: transitive
description:
name: path
- url: "https://pub.flutter-io.cn"
+ sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.8.0"
+ version: "1.8.2"
sky_engine:
dependency: transitive
description: flutter
@@ -90,58 +108,58 @@ packages:
dependency: transitive
description:
name: source_span
- url: "https://pub.flutter-io.cn"
+ sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.8.1"
+ version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.flutter-io.cn"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.10.0"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.flutter-io.cn"
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.flutter-io.cn"
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.1.0"
+ version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.flutter-io.cn"
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.2.0"
+ version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.flutter-io.cn"
- source: hosted
- version: "0.3.0"
- typed_data:
- dependency: transitive
- description:
- name: typed_data
- url: "https://pub.flutter-io.cn"
+ sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "1.3.0"
+ version: "0.4.16"
vector_math:
dependency: transitive
description:
name: vector_math
- url: "https://pub.flutter-io.cn"
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
- version: "2.1.0"
+ version: "2.1.4"
sdks:
- dart: ">=2.12.0 <3.0.0"
+ dart: ">=2.18.0 <3.0.0"
flutter: ">=1.12.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 7a0727196ada1f4d3162a7c42b9b85c82d7da654..a14e5edf31500046e84bb2d3133e27be99c76d46 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -29,6 +29,9 @@ flutter:
pluginClass: RScanPlugin
ios:
pluginClass: RScanPlugin
+ ohos:
+ package: com.rhyme.r_scan
+ pluginClass: RScanPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
diff --git a/r_scan.iml b/r_scan.iml
index ee2091e512909dec59898f800617aae05aec243d..14a47504e9b1c3078f08fe00777873b5c8d50d3f 100644
--- a/r_scan.iml
+++ b/r_scan.iml
@@ -16,8 +16,10 @@
+
+
\ No newline at end of file