├── .github └── workflows │ └── android.yml ├── .gitignore ├── LICENSE ├── README.md ├── README_ZH.md ├── Screenshot.jpg ├── app ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── example │ │ ├── scankitdemo │ │ ├── CameraOperation.java │ │ ├── CommonActivity.java │ │ ├── CommonHandler.java │ │ ├── DefinedActivity.java │ │ ├── DisPlayActivity.java │ │ ├── DisPlayMulActivity.java │ │ ├── GenerateCodeActivity.java │ │ ├── MainActivity.java │ │ ├── action │ │ │ ├── CalendarEventAction.java │ │ │ ├── ContactInfoAction.java │ │ │ ├── DialAction.java │ │ │ ├── EmailAction.java │ │ │ ├── LocationAction.java │ │ │ ├── SMSAction.java │ │ │ └── WifiAdmin.java │ │ └── draw │ │ │ └── ScanResultView.java │ │ └── scankitdemokotlin │ │ ├── CommonActivity.kt │ │ ├── CommonHandler.kt │ │ ├── DefinedActivity.kt │ │ ├── DisPlayActivity.kt │ │ ├── DisPlayMulActivity.kt │ │ ├── GenerateCodeActivity.kt │ │ └── MainActivity.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── back.png │ ├── cloors.xml │ ├── clors_btn.xml │ ├── clors_dis.xml │ ├── contact.png │ ├── dialog_bg.xml │ ├── email.png │ ├── event.png │ ├── flashlight_off.png │ ├── flashlight_on.png │ ├── ic_back.png │ ├── ic_launcher_background.xml │ ├── isbn.png │ ├── location.png │ ├── photo.png │ ├── product.png │ ├── scan_kit_logo.png │ ├── sms.png │ ├── tel.png │ ├── text.png │ ├── website.png │ └── wifi.png │ ├── layout-land │ └── activity_mwcmain_landscape.xml │ ├── layout │ ├── activity_common.xml │ ├── activity_defined.xml │ ├── activity_display.xml │ ├── activity_display_item.xml │ ├── activity_display_mul.xml │ ├── activity_generate.xml │ ├── activity_mwcmain.xml │ └── data_single_item.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── values-en │ └── strings.xml │ ├── values-zh │ └── strings.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: set up JDK 1.8 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 1.8 20 | - name: Build with Gradle 21 | run: chmod +x gradlew; ./gradlew build 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | # Uncomment the following line in case you need and you don't have the release build type files in your app 18 | # release/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # IntelliJ 40 | *.iml 41 | .idea/ 42 | 43 | # Keystore files 44 | # Uncomment the following lines if you do not want to check your keystore files in. 45 | #*.jks 46 | #*.keystore 47 | 48 | # External native build folder generated in Android Studio 2.2 and later 49 | .externalNativeBuild 50 | .cxx/ 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | # google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | 67 | # Version control 68 | vcs.xml 69 | 70 | # lint 71 | lint/intermediates/ 72 | lint/generated/ 73 | lint/outputs/ 74 | lint/tmp/ 75 | # lint/reports/ 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HMS Core Scan Kit Sample Code (Android) 2 | 3 | English | [中文](README_ZH.md) 4 | ## Contents 5 | 6 | * [Introduction](#Introduction) 7 | * [Environment Requirements](#Environment-Requirements) 8 | * [Sample Code](#Sample-Code) 9 | * [Result](#Result) 10 | * [License](#License) 11 | 12 | 13 | 14 | ## Introduction 15 | 16 | This sample code shows how to quickly build barcode scanning functions into your app using the capabilities of the [HMS Core Scan Kit](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/service-introduction-0000001050041994). Currently, Scan Kit supports the following barcode formats: 17 | 18 | - 1D barcode formats: [EAN-8](https://en.wikipedia.org/wiki/EAN-8), [EAN-13](https://en.wikipedia.org/wiki/International_Article_Number), [UPC-A](https://en.wikipedia.org/wiki/Universal_Product_Code), [UPC-E](https://en.wikipedia.org/wiki/Universal_Product_Code#UPC-E), [Codabar](https://en.wikipedia.org/wiki/Codabar), [Code 39](https://en.wikipedia.org/wiki/Code_39), [Code 93](https://en.wikipedia.org/wiki/Code_93), [Code 128](https://en.wikipedia.org/wiki/Code_128), and [ITF-14](https://en.wikipedia.org/wiki/ITF-14) 19 | - 2D barcode formats: [QR Code](https://en.wikipedia.org/wiki/QR_code), [Data Matrix](https://en.wikipedia.org/wiki/Data_Matrix), [PDF417](https://en.wikipedia.org/wiki/PDF417), and [Aztec](https://en.wikipedia.org/wiki/Aztec_Code) 20 | 21 | 22 | 23 | ## Environment Requirements 24 | 25 | Android Studio 3.6.1 or later and JDK 1.8.211 or later. 26 | 27 | A Huawei device that runs EMUI 3.0 or later, compatible with HMS Core (APK) 4.0.0 or a generic device running Android 4.4 or later. 28 | 29 | 30 | 31 | ## Sample Code 32 | 33 | Barcode scanning and barcode generating can be achieved in different ways, showcased by the demo. 34 | 35 | **Default view** 36 | 37 | The [default view](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-default-view-0000001050043961) mode will start a dedicated `Activity` provided by Scan Kit that will display a predefined UI, control the camera and pass back the scanning result via the `onActivityResult()` of the original activity (`com.example.scankitdemo.MainActivity` in the demo) . 38 | 39 | **Customized view** 40 | 41 | In [customized view](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-customized-view-0000001050042012) mode, you can define a custom UI, with the help of a `com.huawei.hms.hmsscankit.RemoteView`, and then obtain the scanning result through an asynchronous callback. As with the *default view* mode, you do not need to worry about developing the scanning process or controlling the camera. See `com.example.scankitdemo.DefinedActivity`. 42 | 43 | **Bitmap** 44 | 45 | Use this mode when you wish to have full control over the input to the scanning process and the moment when you wish to get the results back. In `com.example.scankitdemo.CommonActivity` , the demo will pass a `Bitmap` to `com.huawei.hms.hmsscankit.ScanUtil.decodeWithBitmap()` ([definition](https://developer.huawei.com/consumer/en/doc/development/HMSCore-References/scan-scanutil4-0000001050167699#section14774629143713)). 46 | 47 | **Multi-processor** 48 | 49 | Recognize multiple barcodes at the same time. When working together with the [HMS ML Kit](https://developer.huawei.com/consumer/en/hms/huawei-mlkit/), Scan Kit can detecting both barcodes and human faces. Frame data is transmitted and decoded through [the multi-processor API](https://developer.huawei.com/consumer/en/doc/development/HMSCore-References/scan-analyzer4-0000001050167905). See `com.example.scankitdemo.CommonActivity` and read more about [how it works](https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-synchronous-mode-0000001050043967). 50 | 51 | **Generating barcodes** 52 | 53 | Generate your own barcodes by calling `com.huawei.hms.hmsscankit.ScanUtil.buildBitmap()` ([definition](https://developer.huawei.com/consumer/en/doc/development/HMSCore-References/scan-scanutil4-0000001050167699#section56266161243)) in `com.example.scankitdemo.GenerateCodeActivity`. 54 | 55 | 56 | 57 | ## Result 58 | 59 | 60 | 61 | 62 | 63 | ## Technical Support 64 | 65 | You can visit the [Reddit community](https://www.reddit.com/r/HuaweiDevelopers/) to obtain the latest information about HMS Core and communicate with other developers. 66 | 67 | If you have any questions about the sample code, try the following: 68 | - Visit [Stack Overflow](https://stackoverflow.com/questions/tagged/huawei-mobile-services?tab=Votes), submit your questions, and tag them with `huawei-mobile-services`. Huawei experts will answer your questions. 69 | - Visit the HMS Core section in the [HUAWEI Developer Forum](https://forums.developer.huawei.com/forumPortal/en/home?fid=0101187876626530001?ha_source=hms1) and communicate with other developers. 70 | 71 | If you encounter any issues when using the sample code, submit your [issues](https://github.com/HMS-Core/hms-scan-demo/issues) or submit a [pull request](https://github.com/HMS-Core/hms-scan-demo/pulls). 72 | 73 | 74 | 75 | ## License 76 | 77 | The sample code is licensed under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0). 78 | 79 | -------------------------------------------------------------------------------- /README_ZH.md: -------------------------------------------------------------------------------- 1 | # 华为统一扫码服务Android示例代码 2 | 3 | 中文 | [English](README.md) 4 | 5 | ## 目录 6 | 7 | * [简介](#简介) 8 | * [开发准备](#开发准备) 9 | * [环境要求](#环境要求) 10 | * [示例代码](#示例代码) 11 | * [运行结果](#运行结果) 12 | * [授权许可](#授权许可) 13 | 14 | 15 | ## 简介 16 | 示例代码显示了如何使用HMS扫描套件的代码扫描功能来帮助开发人员在应用程序中快速构建代码扫描功能。 17 | 18 | 该示例也可以通过HMS Toolkit快速启动运行,且支持各Kit一站式集成,并提供远程真机免费调测等功能。了解更多信息,请参考[HMS Toolkit文档](https://developer.huawei.com/consumer/cn/doc/development/Tools-Guides/getting-started-0000001077381096?ha_source=hms1) 。 19 | 20 | ## 开发准备 21 | 1)创建app应用,并配置AppGallery Connect。 22 | 见详情:[HUWEI Scan Development Preparation](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-config-agc-0000001050043955?ha_source=hms1) 23 | 24 | 2)添加当前应用的AppGallery Connect配置文件 25 | 26 | 3)配置HMS Core SDK的Maven仓地址 27 | 28 | ## 环境要求 29 | 使用Android Studio3.6.1及以上和JDK1.8.211及以上进行编译。 30 | 华为设备需要运行EMUI 3.0或更高版本,适应HMS APK 4.0.0 或更高版本;非华为设备需要Android 4.4或更高版本。 31 | 32 | ## 示例代码 33 | ### 演示提供了四种模式,以适应不同情况下的代码扫描能力。 34 | 35 | * Default View 36 | 37 | 该应用程序直接调用HUAWEI Scan Kit的扫码活动,并通过异步回调API获取扫描结果。 可以使用设备相机或通过导入的图像扫描条形码。 38 | 39 | 代码位置:example/scankitdemo/MainActivity.java 40 | 41 | * Customized View 42 | 43 | 该应用程序直接创建RemoteView,并通过异步回调API获取扫描结果。 可以使用设备相机或通过导入的图像扫描条形码。 44 | 45 | 代码位置:example/scankitdemo/DefinedActivity.java 46 | 47 | * Bitmap API 48 | 49 | 该应用程序直接通过位图API传递位图,并通过API获得扫描结果。 在您的应用中,您可以调用相机API或导入本地图像以获得位图,然后调用HUAWEI Scan Kit的位图API来解码位图。 50 | 51 | 代码位置:example/scankitdemo/CommonActivity.java example/scankitdemo/CommonHandler.java 52 | 53 | * MultiProcessor API 54 | 55 | 该应用程序使用与HUAWEI ML Kit相同的技术,通过MultiProcessor API传递帧数据以进行解码,并检测条形码以及诸如面部。 56 | 57 | 代码位置:example/scankitdemo/CommonActivity.java example/scankitdemo/CommonHandler.java 58 | 59 | ### 演示提供了码生成功能 60 | * Generate Code API 61 | 62 | 该应用程序允许您生成一维或条形码。 63 | 64 | 代码位置:example/scankitdemo/GenerateCodeActivity.java 65 | 66 | ## 运行结果 67 | 68 | 69 | ## 技术支持 70 | 如果您对HMS Core还处于评估阶段,可在[Reddit社区](https://www.reddit.com/r/HuaweiDevelopers/)获取关于HMS Core的最新讯息,并与其他开发者交流见解。 71 | 72 | 如果您对使用HMS示例代码有疑问,请尝试: 73 | - 开发过程遇到问题上[Stack Overflow](https://stackoverflow.com/questions/tagged/huawei-mobile-services?tab=Votes),在`huawei-mobile-services`标签下提问,有华为研发专家在线一对一解决您的问题。 74 | - 到[华为开发者论坛](https://developer.huawei.com/consumer/cn/forum/blockdisplay?fid=18?ha_source=hms1) HMS Core板块与其他开发者进行交流。 75 | 76 | 如果您在尝试示例代码中遇到问题,请向仓库提交[issue](https://github.com/HMS-Core/hms-scan-demo/issues),也欢迎您提交[Pull Request](https://github.com/HMS-Core/hms-scan-demo/pulls)。 77 | 78 | ## 授权许可 79 | 华为统一扫码服务示例代码经过[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0)授权许可。 80 | 81 | -------------------------------------------------------------------------------- /Screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/Screenshot.jpg -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'com.huawei.agconnect' 5 | android { 6 | compileSdkVersion 33 7 | buildToolsVersion "29.0.3" 8 | defaultConfig { 9 | applicationId "com.example.scankitdemo" 10 | minSdkVersion 21 11 | targetSdkVersion 34 12 | versionCode 1 13 | versionName "1.0" 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | 23 | lintOptions { 24 | abortOnError false 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | // scankitSDK 31 | implementation 'com.huawei.hms:scanplus:2.9.0.300' 32 | // components used by view in demo,not scankit sdk 33 | implementation 'androidx.appcompat:appcompat:1.1.0' 34 | implementation 'androidx.cardview:cardview:1.0.0' 35 | implementation 'androidx.recyclerview:recyclerview:1.1.0' 36 | implementation "androidx.core:core-ktx:1.1.0" 37 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 38 | } 39 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -ignorewarnings 24 | -keepattributes *Annotation* 25 | -keepattributes Exceptions 26 | -keepattributes InnerClasses 27 | -keepattributes Signature 28 | -keepattributes SourceFile,LineNumberTable 29 | -keep class com.huawei.hianalytics.**{*;} 30 | -keep class com.huawei.updatesdk.**{*;} 31 | -keep class com.huawei.hms.**{*;} -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/CameraOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo; 17 | 18 | import android.graphics.ImageFormat; 19 | import android.hardware.Camera; 20 | import android.os.Handler; 21 | import android.os.Message; 22 | import android.util.Log; 23 | import android.view.SurfaceHolder; 24 | 25 | import java.io.IOException; 26 | import java.util.List; 27 | 28 | public class CameraOperation { 29 | 30 | private static final String TAG = "CameraOperation"; 31 | private Camera camera = null; 32 | private Camera.Parameters parameters = null; 33 | private boolean isPreview = false; 34 | private FrameCallback frameCallback = new FrameCallback(); 35 | private int width = 1920; 36 | private int height = 1080; 37 | private double defaultZoom = 1.0; 38 | 39 | /** 40 | * Open up the camera. 41 | */ 42 | public synchronized void open(SurfaceHolder holder) throws IOException { 43 | camera = Camera.open(); 44 | parameters = camera.getParameters(); 45 | parameters.setPictureSize(width, height); 46 | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 47 | parameters.setPictureFormat(ImageFormat.NV21); 48 | camera.setPreviewDisplay(holder); 49 | camera.setDisplayOrientation(90); 50 | camera.setParameters(parameters); 51 | } 52 | 53 | public synchronized void close() { 54 | if (camera != null) { 55 | camera.stopPreview(); 56 | camera.release(); 57 | camera = null; 58 | } 59 | } 60 | 61 | public synchronized void startPreview() { 62 | if (camera != null && !isPreview) { 63 | camera.startPreview(); 64 | isPreview = true; 65 | } 66 | } 67 | 68 | public synchronized void stopPreview() { 69 | if (camera != null && isPreview) { 70 | camera.stopPreview(); 71 | frameCallback.setProperties(null); 72 | isPreview = false; 73 | } 74 | } 75 | 76 | public synchronized void callbackFrame(Handler handler, double zoomValue) { 77 | if (camera != null && isPreview) { 78 | frameCallback.setProperties(handler); 79 | if (camera.getParameters().isZoomSupported() && zoomValue != defaultZoom) { 80 | //Auto zoom. 81 | parameters.setZoom(convertZoomInt(zoomValue)); 82 | camera.setParameters(parameters); 83 | } 84 | camera.setOneShotPreviewCallback(frameCallback); 85 | } 86 | } 87 | 88 | public int convertZoomInt(double zoomValue) { 89 | List allZoomRatios = parameters.getZoomRatios(); 90 | float maxZoom = Math.round(allZoomRatios.get(allZoomRatios.size() - 1) / 100f); 91 | if (zoomValue >= maxZoom) { 92 | return allZoomRatios.size() - 1; 93 | } 94 | for (int i = 1; i < allZoomRatios.size(); i++) { 95 | if (allZoomRatios.get(i) >= (zoomValue * 100) && allZoomRatios.get(i - 1) <= (zoomValue * 100)) { 96 | return i; 97 | } 98 | } 99 | return -1; 100 | } 101 | 102 | 103 | 104 | class FrameCallback implements Camera.PreviewCallback { 105 | 106 | private Handler handler; 107 | 108 | public void setProperties(Handler handler) { 109 | this.handler = handler; 110 | 111 | } 112 | 113 | @Override 114 | public void onPreviewFrame(byte[] data, Camera camera) { 115 | if (handler != null) { 116 | Message message = handler.obtainMessage(0, camera.getParameters().getPreviewSize().width, 117 | camera.getParameters().getPreviewSize().height, data); 118 | message.sendToTarget(); 119 | handler = null; 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/CommonHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo; 17 | import android.app.Activity; 18 | 19 | import android.content.Intent; 20 | import android.graphics.Bitmap; 21 | import android.graphics.BitmapFactory; 22 | import android.graphics.Color; 23 | import android.graphics.ImageFormat; 24 | import android.graphics.Rect; 25 | import android.graphics.YuvImage; 26 | import android.os.Handler; 27 | import android.os.HandlerThread; 28 | import android.os.Message; 29 | import android.text.TextUtils; 30 | import android.util.Log; 31 | import android.util.SparseArray; 32 | 33 | import com.example.scankitdemo.draw.ScanResultView; 34 | import com.huawei.hmf.tasks.OnFailureListener; 35 | import com.huawei.hmf.tasks.OnSuccessListener; 36 | import com.huawei.hms.hmsscankit.ScanUtil; 37 | import com.huawei.hms.ml.scan.HmsScan; 38 | import com.huawei.hms.ml.scan.HmsScanAnalyzer; 39 | import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions; 40 | import com.huawei.hms.mlsdk.common.MLFrame; 41 | 42 | import java.io.ByteArrayOutputStream; 43 | import java.util.List; 44 | 45 | import static android.app.Activity.RESULT_OK; 46 | 47 | public final class CommonHandler extends Handler { 48 | 49 | private static final String TAG = "MainHandler"; 50 | private static final double DEFAULT_ZOOM = 1.0; 51 | private CameraOperation cameraOperation; 52 | private HandlerThread decodeThread; 53 | private Handler decodeHandle; 54 | private Activity activity; 55 | private int mode; 56 | 57 | public CommonHandler(final Activity activity, CameraOperation cameraOperation, final int mode) { 58 | this.cameraOperation = cameraOperation; 59 | this.activity = activity; 60 | this.mode = mode; 61 | decodeThread = new HandlerThread("DecodeThread"); 62 | decodeThread.start(); 63 | decodeHandle = new Handler(decodeThread.getLooper()){ 64 | @Override 65 | public void handleMessage(Message msg) { 66 | if (msg == null) { 67 | return; 68 | } 69 | if (mode == MainActivity.BITMAP_CODE || mode == MainActivity.MULTIPROCESSOR_SYN_CODE) { 70 | HmsScan[] result = decodeSyn(msg.arg1, msg.arg2, (byte[]) msg.obj, activity, HmsScan.ALL_SCAN_TYPE, mode); 71 | if (result == null || result.length == 0) { 72 | restart(DEFAULT_ZOOM); 73 | } else if (TextUtils.isEmpty(result[0].getOriginalValue()) && result[0].getZoomValue() != 1.0) { 74 | restart(result[0].getZoomValue()); 75 | } else if (!TextUtils.isEmpty(result[0].getOriginalValue())) { 76 | Message message = new Message(); 77 | message.what = msg.what; 78 | message.obj = result; 79 | CommonHandler.this.sendMessage(message); 80 | restart(DEFAULT_ZOOM); 81 | } else{ 82 | restart(DEFAULT_ZOOM); 83 | } 84 | } 85 | if (mode == MainActivity.MULTIPROCESSOR_ASYN_CODE) { 86 | decodeAsyn(msg.arg1, msg.arg2, (byte[]) msg.obj, activity, HmsScan.ALL_SCAN_TYPE); 87 | } 88 | } 89 | }; 90 | cameraOperation.startPreview(); 91 | restart(DEFAULT_ZOOM); 92 | } 93 | 94 | /** 95 | * Call the MultiProcessor API in synchronous mode. 96 | */ 97 | private HmsScan[] decodeSyn(int width, int height, byte[] data, final Activity activity, int type, int mode) { 98 | Bitmap bitmap = convertToBitmap(width, height, data); 99 | if (mode == MainActivity.BITMAP_CODE) { 100 | HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(type).setPhotoMode(false).create(); 101 | return ScanUtil.decodeWithBitmap(activity, bitmap, options); 102 | } else if (mode == MainActivity.MULTIPROCESSOR_SYN_CODE) { 103 | MLFrame image = MLFrame.fromBitmap(bitmap); 104 | HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(type).create(); 105 | HmsScanAnalyzer analyzer = new HmsScanAnalyzer(options);; 106 | SparseArray result = analyzer.analyseFrame(image); 107 | if (result != null && result.size() > 0 && result.valueAt(0) != null && !TextUtils.isEmpty(result.valueAt(0).getOriginalValue())) { 108 | HmsScan[] info = new HmsScan[result.size()]; 109 | for (int index = 0; index < result.size(); index++) { 110 | info[index] = result.valueAt(index); 111 | } 112 | return info; 113 | } 114 | } 115 | return null; 116 | } 117 | 118 | /** 119 | * Convert camera data into bitmap data. 120 | */ 121 | private Bitmap convertToBitmap(int width, int height, byte[] data) { 122 | YuvImage yuv = new YuvImage(data, ImageFormat.NV21, width, height, null); 123 | ByteArrayOutputStream stream = new ByteArrayOutputStream(); 124 | yuv.compressToJpeg(new Rect(0, 0, width, height), 100, stream); 125 | return BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.toByteArray().length); 126 | } 127 | 128 | /** 129 | * Call the MultiProcessor API in asynchronous mode. 130 | */ 131 | private void decodeAsyn(int width, int height, byte[] data, final Activity activity, int type) { 132 | final Bitmap bitmap = convertToBitmap(width, height, data); 133 | MLFrame image = MLFrame.fromBitmap(bitmap); 134 | HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(type).create(); 135 | HmsScanAnalyzer analyzer = new HmsScanAnalyzer(options); 136 | analyzer.analyzInAsyn(image).addOnSuccessListener(new OnSuccessListener>() { 137 | @Override 138 | public void onSuccess(List hmsScans) { 139 | if (hmsScans != null && hmsScans.size() > 0 && hmsScans.get(0) != null && !TextUtils.isEmpty(hmsScans.get(0).getOriginalValue())) { 140 | HmsScan[] infos = new HmsScan[hmsScans.size()]; 141 | Message message = new Message(); 142 | message.obj = hmsScans.toArray(infos); 143 | CommonHandler.this.sendMessage(message); 144 | restart(DEFAULT_ZOOM); 145 | } else { 146 | restart(DEFAULT_ZOOM); 147 | } 148 | bitmap.recycle(); 149 | } 150 | }).addOnFailureListener(new OnFailureListener() { 151 | @Override 152 | public void onFailure(Exception e) { 153 | Log.w(TAG, e); 154 | restart(DEFAULT_ZOOM); 155 | bitmap.recycle(); 156 | } 157 | }); 158 | } 159 | 160 | @Override 161 | public void handleMessage(Message message) { 162 | Log.e(TAG, String.valueOf(message.what)); 163 | removeMessages(1); 164 | if (message.what == 0) { 165 | CommonActivity commonActivity1 = (CommonActivity) activity; 166 | commonActivity1.scanResultView.clear(); 167 | Intent intent = new Intent(); 168 | intent.putExtra(CommonActivity.SCAN_RESULT, (HmsScan[]) message.obj); 169 | activity.setResult(RESULT_OK, intent); 170 | //Show the scanning result on the screen. 171 | if (mode == MainActivity.MULTIPROCESSOR_ASYN_CODE || mode == MainActivity.MULTIPROCESSOR_SYN_CODE) { 172 | CommonActivity commonActivity = (CommonActivity) activity; 173 | 174 | HmsScan[] arr = (HmsScan[]) message.obj; 175 | for (int i = 0; i < arr.length; i++) { 176 | if (i == 0) { 177 | commonActivity.scanResultView.add(new ScanResultView.HmsScanGraphic(commonActivity.scanResultView, arr[i], Color.YELLOW)); 178 | } else if (i == 1) { 179 | commonActivity.scanResultView.add(new ScanResultView.HmsScanGraphic(commonActivity.scanResultView, arr[i], Color.BLUE)); 180 | } else if (i == 2){ 181 | commonActivity.scanResultView.add(new ScanResultView.HmsScanGraphic(commonActivity.scanResultView, arr[i], Color.RED)); 182 | } else if (i == 3){ 183 | commonActivity.scanResultView.add(new ScanResultView.HmsScanGraphic(commonActivity.scanResultView, arr[i], Color.GREEN)); 184 | } else { 185 | commonActivity.scanResultView.add(new ScanResultView.HmsScanGraphic(commonActivity.scanResultView, arr[i])); 186 | } 187 | } 188 | commonActivity.scanResultView.setCameraInfo(1080, 1920); 189 | commonActivity.scanResultView.invalidate(); 190 | sendEmptyMessageDelayed(1,1000); 191 | } else { 192 | activity.finish(); 193 | } 194 | }else if(message.what == 1){ 195 | CommonActivity commonActivity1 = (CommonActivity) activity; 196 | commonActivity1.scanResultView.clear(); 197 | } 198 | } 199 | 200 | public void quit() { 201 | try { 202 | cameraOperation.stopPreview(); 203 | decodeHandle.getLooper().quit(); 204 | decodeThread.join(500); 205 | } catch (InterruptedException e) { 206 | Log.w(TAG, e); 207 | } 208 | } 209 | 210 | public void restart(double zoomValue) { 211 | cameraOperation.callbackFrame(decodeHandle, zoomValue); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/DefinedActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo; 17 | import android.app.Activity; 18 | import android.content.Intent; 19 | import android.graphics.Bitmap; 20 | import android.graphics.Rect; 21 | import android.os.Bundle; 22 | import android.provider.MediaStore; 23 | import android.text.TextUtils; 24 | import android.util.DisplayMetrics; 25 | import android.view.View; 26 | import android.view.Window; 27 | import android.widget.FrameLayout; 28 | import android.widget.ImageView; 29 | import android.widget.LinearLayout; 30 | 31 | import com.huawei.hms.hmsscankit.OnLightVisibleCallBack; 32 | import com.huawei.hms.hmsscankit.OnResultCallback; 33 | import com.huawei.hms.hmsscankit.RemoteView; 34 | import com.huawei.hms.hmsscankit.ScanUtil; 35 | import com.huawei.hms.ml.scan.HmsScan; 36 | import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions; 37 | 38 | import java.io.IOException; 39 | 40 | public class DefinedActivity extends Activity { 41 | private FrameLayout frameLayout; 42 | private RemoteView remoteView; 43 | private ImageView backBtn; 44 | private ImageView imgBtn; 45 | private ImageView flushBtn; 46 | int mScreenWidth; 47 | int mScreenHeight; 48 | //The width and height of scan_view_finder is both 240 dp. 49 | final int SCAN_FRAME_SIZE = 240; 50 | 51 | private int[] img = {R.drawable.flashlight_on, R.drawable.flashlight_off}; 52 | private static final String TAG = "DefinedActivity"; 53 | 54 | //Declare the key. It is used to obtain the value returned from Scan Kit. 55 | public static final String SCAN_RESULT = "scanResult"; 56 | public static final int REQUEST_CODE_PHOTO = 0X1113; 57 | @Override 58 | protected void onCreate(Bundle savedInstanceState) { 59 | super.onCreate(savedInstanceState); 60 | requestWindowFeature(Window.FEATURE_NO_TITLE); 61 | setContentView(R.layout.activity_defined); 62 | // Bind the camera preview screen. 63 | frameLayout = findViewById(R.id.rim); 64 | 65 | //1. Obtain the screen density to calculate the viewfinder's rectangle. 66 | DisplayMetrics dm = getResources().getDisplayMetrics(); 67 | float density = dm.density; 68 | //2. Obtain the screen size. 69 | mScreenWidth = getResources().getDisplayMetrics().widthPixels; 70 | mScreenHeight = getResources().getDisplayMetrics().heightPixels; 71 | 72 | int scanFrameSize = (int) (SCAN_FRAME_SIZE * density); 73 | 74 | //3. Calculate the viewfinder's rectangle, which in the middle of the layout. 75 | //Set the scanning area. (Optional. Rect can be null. If no settings are specified, it will be located in the middle of the layout.) 76 | Rect rect = new Rect(); 77 | rect.left = mScreenWidth / 2 - scanFrameSize / 2; 78 | rect.right = mScreenWidth / 2 + scanFrameSize / 2; 79 | rect.top = mScreenHeight / 2 - scanFrameSize / 2; 80 | rect.bottom = mScreenHeight / 2 + scanFrameSize / 2; 81 | 82 | 83 | //Initialize the RemoteView instance, and set callback for the scanning result. 84 | remoteView = new RemoteView.Builder().setContext(this).setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build(); 85 | // When the light is dim, this API is called back to display the flashlight switch. 86 | flushBtn = findViewById(R.id.flush_btn); 87 | remoteView.setOnLightVisibleCallback(new OnLightVisibleCallBack() { 88 | @Override 89 | public void onVisibleChanged(boolean visible) { 90 | if(visible){ 91 | flushBtn.setVisibility(View.VISIBLE); 92 | } 93 | } 94 | }); 95 | // Subscribe to the scanning result callback event. 96 | remoteView.setOnResultCallback(new OnResultCallback() { 97 | @Override 98 | public void onResult(HmsScan[] result) { 99 | //Check the result. 100 | if (result != null && result.length > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) { 101 | Intent intent = new Intent(); 102 | intent.putExtra(SCAN_RESULT, result[0]); 103 | setResult(RESULT_OK, intent); 104 | DefinedActivity.this.finish(); 105 | } 106 | } 107 | }); 108 | // Load the customized view to the activity. 109 | remoteView.onCreate(savedInstanceState); 110 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); 111 | frameLayout.addView(remoteView, params); 112 | // Set the back, photo scanning, and flashlight operations. 113 | setBackOperation(); 114 | setPictureScanOperation(); 115 | setFlashOperation(); 116 | } 117 | 118 | /** 119 | * Call the lifecycle management method of the remoteView activity. 120 | */ 121 | private void setPictureScanOperation() { 122 | imgBtn = findViewById(R.id.img_btn); 123 | imgBtn.setOnClickListener(new View.OnClickListener() { 124 | @Override 125 | public void onClick(View v) { 126 | Intent pickIntent = new Intent(Intent.ACTION_PICK, 127 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 128 | pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); 129 | DefinedActivity.this.startActivityForResult(pickIntent, REQUEST_CODE_PHOTO); 130 | 131 | } 132 | }); 133 | } 134 | 135 | private void setFlashOperation() { 136 | flushBtn.setOnClickListener(new View.OnClickListener() { 137 | @Override 138 | public void onClick(View v) { 139 | if (remoteView.getLightStatus()) { 140 | remoteView.switchLight(); 141 | flushBtn.setImageResource(img[1]); 142 | } else { 143 | remoteView.switchLight(); 144 | flushBtn.setImageResource(img[0]); 145 | } 146 | } 147 | }); 148 | } 149 | 150 | private void setBackOperation() { 151 | backBtn = findViewById(R.id.back_img); 152 | backBtn.setOnClickListener(new View.OnClickListener() { 153 | @Override 154 | public void onClick(View v) { 155 | DefinedActivity.this.finish(); 156 | } 157 | }); 158 | } 159 | 160 | /** 161 | * Call the lifecycle management method of the remoteView activity. 162 | */ 163 | @Override 164 | protected void onStart() { 165 | super.onStart(); 166 | remoteView.onStart(); 167 | } 168 | 169 | @Override 170 | protected void onResume() { 171 | super.onResume(); 172 | remoteView.onResume(); 173 | } 174 | 175 | @Override 176 | protected void onPause() { 177 | super.onPause(); 178 | remoteView.onPause(); 179 | } 180 | 181 | @Override 182 | protected void onDestroy() { 183 | super.onDestroy(); 184 | remoteView.onDestroy(); 185 | } 186 | 187 | @Override 188 | protected void onStop() { 189 | super.onStop(); 190 | remoteView.onStop(); 191 | } 192 | 193 | /** 194 | * Handle the return results from the album. 195 | */ 196 | @Override 197 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 198 | super.onActivityResult(requestCode, resultCode, data); 199 | if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_PHOTO) { 200 | try { 201 | Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData()); 202 | HmsScan[] hmsScans = ScanUtil.decodeWithBitmap(DefinedActivity.this, bitmap, new HmsScanAnalyzerOptions.Creator().setPhotoMode(true).create()); 203 | if (hmsScans != null && hmsScans.length > 0 && hmsScans[0] != null && !TextUtils.isEmpty(hmsScans[0].getOriginalValue())) { 204 | Intent intent = new Intent(); 205 | intent.putExtra(SCAN_RESULT, hmsScans[0]); 206 | setResult(RESULT_OK, intent); 207 | DefinedActivity.this.finish(); 208 | } 209 | } catch (IOException e) { 210 | e.printStackTrace(); 211 | } 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/DisPlayMulActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo; 17 | import android.app.Activity; 18 | import android.os.Build; 19 | import android.os.Bundle; 20 | import android.os.Parcelable; 21 | import android.os.Vibrator; 22 | import android.text.TextUtils; 23 | import android.view.LayoutInflater; 24 | import android.view.View; 25 | import android.view.Window; 26 | import android.view.WindowManager; 27 | import android.widget.Button; 28 | import android.widget.ImageView; 29 | import android.widget.LinearLayout; 30 | import android.widget.RelativeLayout; 31 | import android.widget.TextView; 32 | import com.huawei.hms.ml.scan.HmsScan; 33 | 34 | 35 | public class DisPlayMulActivity extends Activity { 36 | //Define a view. 37 | private ImageView backBtn; 38 | private TextView codeFormat; 39 | private TextView resultType; 40 | private TextView rawResult; 41 | private LinearLayout scrollView; 42 | private View view; 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | requestWindowFeature(Window.FEATURE_NO_TITLE); 48 | setContentView(R.layout.activity_display_mul); 49 | backBtn = findViewById(R.id.result_back_img_in); 50 | backBtn.setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | DisPlayMulActivity.this.finish(); 54 | } 55 | }); 56 | scrollView = findViewById(R.id.scroll_item); 57 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 58 | Window window = getWindow(); 59 | this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 60 | if (window != null) { 61 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 62 | } 63 | RelativeLayout relativeLayout = findViewById(R.id.result_title); 64 | if (relativeLayout != null) { 65 | RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(relativeLayout.getLayoutParams().width, relativeLayout.getLayoutParams().height); 66 | lp.setMargins(0, getStatusBarHeight(), 0, 0); 67 | relativeLayout.setLayoutParams(lp); 68 | } 69 | } 70 | Vibrator vibrator = (Vibrator) this.getSystemService(this.VIBRATOR_SERVICE); 71 | vibrator.vibrate(300); 72 | LayoutInflater layoutInflater = LayoutInflater.from(this); 73 | //Obtain the scanning result. 74 | Parcelable[] obj = getIntent().getParcelableArrayExtra(MainActivity.RESULT); 75 | if (obj != null) { 76 | for (int i = 0; i < obj.length; i++) { 77 | if (obj[i] instanceof HmsScan && !TextUtils.isEmpty(((HmsScan) obj[i]).getOriginalValue())) { 78 | view = layoutInflater.inflate(R.layout.activity_display_item, null); 79 | scrollView.addView(view); 80 | valueFillIn((HmsScan) obj[i], view); 81 | } 82 | } 83 | } 84 | view.findViewById(R.id.line).setVisibility(View.GONE); 85 | } 86 | 87 | /** 88 | * Display the scanning result in TextView. 89 | */ 90 | private void valueFillIn(final HmsScan hmsScan, View view) { 91 | codeFormat = view.findViewById(R.id.barcode_type); 92 | 93 | resultType = view.findViewById(R.id.barcode_type_mon); 94 | rawResult = view.findViewById(R.id.barcode_rawValue); 95 | 96 | rawResult.setText(hmsScan.getOriginalValue()); 97 | if (hmsScan.getScanType() == HmsScan.QRCODE_SCAN_TYPE) { 98 | codeFormat.setText("QR code"); 99 | } else if (hmsScan.getScanType() == HmsScan.AZTEC_SCAN_TYPE) { 100 | codeFormat.setText("AZTEC code"); 101 | } else if (hmsScan.getScanType() == HmsScan.DATAMATRIX_SCAN_TYPE) { 102 | codeFormat.setText("DATAMATRIX code"); 103 | } else if (hmsScan.getScanType() == HmsScan.PDF417_SCAN_TYPE) { 104 | codeFormat.setText("PDF417 code"); 105 | } else if (hmsScan.getScanType() == HmsScan.CODE93_SCAN_TYPE) { 106 | codeFormat.setText("CODE93"); 107 | } else if (hmsScan.getScanType() == HmsScan.CODE39_SCAN_TYPE) { 108 | codeFormat.setText("CODE39"); 109 | } else if (hmsScan.getScanType() == HmsScan.CODE128_SCAN_TYPE) { 110 | codeFormat.setText("CODE128"); 111 | 112 | } else if (hmsScan.getScanType() == HmsScan.EAN13_SCAN_TYPE) { 113 | codeFormat.setText("EAN13 code"); 114 | 115 | } else if (hmsScan.getScanType() == HmsScan.EAN8_SCAN_TYPE) { 116 | codeFormat.setText("EAN8 code"); 117 | 118 | } else if (hmsScan.getScanType() == HmsScan.ITF14_SCAN_TYPE) { 119 | codeFormat.setText("ITF14 code"); 120 | 121 | } else if (hmsScan.getScanType() == HmsScan.UPCCODE_A_SCAN_TYPE) { 122 | codeFormat.setText("UPCCODE_A"); 123 | 124 | } else if (hmsScan.getScanType() == HmsScan.UPCCODE_E_SCAN_TYPE) { 125 | codeFormat.setText("UPCCODE_E"); 126 | 127 | } else if (hmsScan.getScanType() == HmsScan.CODABAR_SCAN_TYPE) { 128 | codeFormat.setText("CODABAR"); 129 | } 130 | if (hmsScan.getScanType() == HmsScan.QRCODE_SCAN_TYPE) { 131 | if (hmsScan.getScanTypeForm() == HmsScan.PURE_TEXT_FORM) { 132 | resultType.setText("Text"); 133 | } else if (hmsScan.getScanTypeForm() == HmsScan.EVENT_INFO_FORM) { 134 | resultType.setText("Event"); 135 | } else if (hmsScan.getScanTypeForm() == HmsScan.CONTACT_DETAIL_FORM) { 136 | resultType.setText("Contact"); 137 | } else if (hmsScan.getScanTypeForm() == HmsScan.DRIVER_INFO_FORM) { 138 | resultType.setText("License"); 139 | } else if (hmsScan.getScanTypeForm() == HmsScan.EMAIL_CONTENT_FORM) { 140 | resultType.setText("Email"); 141 | } else if (hmsScan.getScanTypeForm() == HmsScan.TEL_PHONE_NUMBER_FORM) { 142 | resultType.setText("Tel"); 143 | } else if (hmsScan.getScanTypeForm() == HmsScan.SMS_FORM) { 144 | resultType.setText("SMS"); 145 | 146 | } else if (hmsScan.getScanTypeForm() == HmsScan.WIFI_CONNECT_INFO_FORM) { 147 | resultType.setText("Wi-Fi"); 148 | 149 | } else if (hmsScan.getScanTypeForm() == HmsScan.URL_FORM) { 150 | resultType.setText("WebSite"); 151 | 152 | } else if (hmsScan.getScanTypeForm() == HmsScan.ARTICLE_NUMBER_FORM) { 153 | resultType.setText("Product"); 154 | 155 | } else { 156 | resultType.setText("Text"); 157 | } 158 | } else if (hmsScan.getScanType() == HmsScan.EAN13_SCAN_TYPE) { 159 | if (hmsScan.getScanTypeForm() == HmsScan.ISBN_NUMBER_FORM) { 160 | resultType.setText("ISBN"); 161 | } else if (hmsScan.getScanTypeForm() == HmsScan.ARTICLE_NUMBER_FORM) { 162 | resultType.setText("Product"); 163 | } else { 164 | resultType.setText("Text"); 165 | } 166 | } else if (hmsScan.getScanType() == HmsScan.EAN8_SCAN_TYPE || hmsScan.getScanType() == HmsScan.UPCCODE_A_SCAN_TYPE 167 | || hmsScan.getScanType() == HmsScan.UPCCODE_E_SCAN_TYPE) { 168 | if (hmsScan.getScanTypeForm() == HmsScan.ARTICLE_NUMBER_FORM) { 169 | resultType.setText("Product"); 170 | } else { 171 | resultType.setText("Text"); 172 | } 173 | } else { 174 | resultType.setText("Text"); 175 | } 176 | } 177 | 178 | protected int getStatusBarHeight() { 179 | int result = 0; 180 | // Obtain the ID. 181 | if (getResources() != null) { 182 | int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 183 | if (resourceId > 0) { 184 | result = getResources().getDimensionPixelSize(resourceId); 185 | } 186 | } 187 | return result; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/GenerateCodeActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo; 17 | import android.app.Activity; 18 | import android.content.Intent; 19 | import android.graphics.Bitmap; 20 | import android.graphics.Color; 21 | import android.net.Uri; 22 | import android.os.Build; 23 | import android.os.Bundle; 24 | import android.os.Environment; 25 | import android.util.Log; 26 | import android.view.View; 27 | import android.view.Window; 28 | import android.view.WindowManager; 29 | import android.widget.AdapterView; 30 | import android.widget.EditText; 31 | import android.widget.ImageView; 32 | import android.widget.Spinner; 33 | import android.widget.Toast; 34 | 35 | import com.huawei.hms.hmsscankit.ScanUtil; 36 | import com.huawei.hms.hmsscankit.WriterException; 37 | import com.huawei.hms.ml.scan.HmsBuildBitmapOption; 38 | import com.huawei.hms.ml.scan.HmsScan; 39 | 40 | import java.io.File; 41 | import java.io.FileOutputStream; 42 | import java.util.Objects; 43 | 44 | public class GenerateCodeActivity extends Activity { 45 | 46 | private static final String TAG = "GenerateCodeActivity" ; 47 | private static final int[] BARCODE_TYPES = {HmsScan.QRCODE_SCAN_TYPE, HmsScan.DATAMATRIX_SCAN_TYPE, HmsScan.PDF417_SCAN_TYPE, HmsScan.AZTEC_SCAN_TYPE, 48 | HmsScan.EAN8_SCAN_TYPE, HmsScan.EAN13_SCAN_TYPE, HmsScan.UPCCODE_A_SCAN_TYPE, HmsScan.UPCCODE_E_SCAN_TYPE, HmsScan.CODABAR_SCAN_TYPE, 49 | HmsScan.CODE39_SCAN_TYPE, HmsScan.CODE93_SCAN_TYPE, HmsScan.CODE128_SCAN_TYPE, HmsScan.ITF14_SCAN_TYPE}; 50 | private static final int[] COLOR = {Color.BLACK, Color.BLUE, Color.GRAY, Color.GREEN, Color.RED, Color.YELLOW}; 51 | private static final int[] BACKGROUND = {Color.WHITE, Color.YELLOW, Color.RED, Color.GREEN, Color.GRAY, Color.BLUE, Color.BLACK}; 52 | //Define a view. 53 | private EditText inputContent; 54 | private Spinner generateType; 55 | private Spinner generateMargin; 56 | private Spinner generateColor; 57 | private Spinner generateBackground; 58 | private ImageView barcodeImage; 59 | private EditText barcodeWidth, barcodeHeight; 60 | private String content; 61 | private int width, height; 62 | private Bitmap resultImage; 63 | private int type = 0; 64 | private int margin = 1; 65 | private int color = Color.BLACK; 66 | private int background = Color.WHITE; 67 | 68 | @Override 69 | protected void onCreate(Bundle savedInstanceState) { 70 | super.onCreate(savedInstanceState); 71 | requestWindowFeature(Window.FEATURE_NO_TITLE); 72 | setContentView(R.layout.activity_generate); 73 | this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 74 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 75 | Window window = getWindow(); 76 | this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 77 | if (window != null) { 78 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 79 | } 80 | } 81 | inputContent = findViewById(R.id.barcode_content); 82 | generateType = findViewById(R.id.generate_type); 83 | generateMargin = findViewById(R.id.generate_margin); 84 | generateColor = findViewById(R.id.generate_color); 85 | generateBackground = findViewById(R.id.generate_backgroundcolor); 86 | barcodeImage = findViewById(R.id.barcode_image); 87 | barcodeWidth = findViewById(R.id.barcode_width); 88 | barcodeHeight = findViewById(R.id.barcode_height); 89 | //Set the barcode type. 90 | generateType.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ 91 | @Override 92 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 93 | type = BARCODE_TYPES[position]; 94 | } 95 | 96 | @Override 97 | public void onNothingSelected(AdapterView parent) { 98 | type = BARCODE_TYPES[0]; 99 | } 100 | }); 101 | 102 | //Set the barcode margin. 103 | generateMargin.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ 104 | @Override 105 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 106 | margin = position + 1; 107 | } 108 | 109 | @Override 110 | public void onNothingSelected(AdapterView parent) { 111 | margin = 1; 112 | } 113 | }); 114 | 115 | //Set the barcode color. 116 | generateColor.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ 117 | @Override 118 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 119 | color = COLOR[position]; 120 | } 121 | 122 | @Override 123 | public void onNothingSelected(AdapterView parent) { 124 | color = COLOR[0]; 125 | } 126 | }); 127 | 128 | //Set the barcode background color. 129 | generateBackground.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ 130 | @Override 131 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 132 | background = BACKGROUND[position]; 133 | } 134 | 135 | @Override 136 | public void onNothingSelected(AdapterView parent) { 137 | background = BACKGROUND[0]; 138 | } 139 | }); 140 | } 141 | 142 | /** 143 | * Generate a barcode. 144 | */ 145 | public void generateCodeBtnClick(View v) { 146 | content = inputContent.getText().toString(); 147 | String inputWidth = barcodeWidth.getText().toString(); 148 | String inputHeight = barcodeHeight.getText().toString(); 149 | //Set the barcode width and height. 150 | if (inputWidth.length() <= 0 || inputHeight.length() <= 0) { 151 | width = 700; 152 | height = 700; 153 | } else { 154 | width = Integer.parseInt(inputWidth); 155 | height = Integer.parseInt(inputHeight); 156 | } 157 | //Set the barcode content. 158 | if (content.length() <= 0) { 159 | Toast.makeText(this, "Please input content first!", Toast.LENGTH_SHORT).show(); 160 | return; 161 | } 162 | if (color == background) { 163 | Toast.makeText(this, "The color and background cannot be the same!", Toast.LENGTH_SHORT).show(); 164 | return; 165 | } 166 | try { 167 | //Generate the barcode. 168 | HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator().setBitmapMargin(margin).setBitmapColor(color).setBitmapBackgroundColor(background).create(); 169 | resultImage = ScanUtil.buildBitmap(content, type, width, height, options); 170 | barcodeImage.setImageBitmap(resultImage); 171 | } catch (WriterException e) { 172 | Toast.makeText(this, "Parameter Error!", Toast.LENGTH_SHORT).show(); 173 | } 174 | } 175 | 176 | /** 177 | * Save the barcode. 178 | */ 179 | public void saveCodeBtnClick(View v) { 180 | if (resultImage == null) { 181 | Toast.makeText(GenerateCodeActivity.this, "Please generate barcode first!", Toast.LENGTH_LONG).show(); 182 | return; 183 | } 184 | try { 185 | String fileName = System.currentTimeMillis() + ".jpg"; 186 | String storePath; 187 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 188 | storePath = getApplicationContext().getExternalFilesDir(null).getAbsolutePath(); 189 | } else { 190 | storePath = Environment.getExternalStorageDirectory().getAbsolutePath(); 191 | } 192 | File appDir = new File(storePath); 193 | if (!appDir.exists()) { 194 | appDir.mkdir(); 195 | } 196 | File file = new File(appDir, fileName); 197 | FileOutputStream fileOutputStream = new FileOutputStream(file); 198 | boolean isSuccess = resultImage.compress(Bitmap.CompressFormat.JPEG, 70, fileOutputStream); 199 | fileOutputStream.flush(); 200 | fileOutputStream.close(); 201 | Uri uri = Uri.fromFile(file); 202 | GenerateCodeActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)); 203 | if (isSuccess) { 204 | Toast.makeText(GenerateCodeActivity.this, "Barcode has been saved locally", Toast.LENGTH_LONG).show(); 205 | } else { 206 | Toast.makeText(GenerateCodeActivity.this, "Barcode save failed", Toast.LENGTH_SHORT).show(); 207 | } 208 | } catch (Exception e) { 209 | Log.w(TAG, Objects.requireNonNull(e.getMessage())); 210 | Toast.makeText(GenerateCodeActivity.this, "Unkown Error", Toast.LENGTH_SHORT).show(); 211 | } 212 | 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo; 17 | import android.Manifest; 18 | import android.app.Activity; 19 | import android.content.Context; 20 | import android.content.Intent; 21 | import android.content.pm.PackageManager; 22 | import android.content.res.Configuration; 23 | import android.content.res.Resources; 24 | import android.os.Build; 25 | import android.os.Bundle; 26 | import android.os.Parcelable; 27 | import android.text.TextUtils; 28 | import android.view.View; 29 | import android.view.Window; 30 | import android.view.WindowManager; 31 | 32 | import androidx.annotation.RequiresApi; 33 | import androidx.core.app.ActivityCompat; 34 | import com.huawei.hms.hmsscankit.ScanUtil; 35 | import com.huawei.hms.ml.scan.HmsScan; 36 | import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions; 37 | 38 | 39 | 40 | public class MainActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback { 41 | 42 | /** 43 | * Define requestCode. 44 | */ 45 | public static final int CAMERA_REQ_CODE = 111; 46 | public static final int DEFINED_CODE = 222; 47 | public static final int BITMAP_CODE = 333; 48 | public static final int MULTIPROCESSOR_SYN_CODE = 444; 49 | public static final int MULTIPROCESSOR_ASYN_CODE = 555; 50 | public static final int GENERATE_CODE = 666; 51 | public static final int DECODE = 1; 52 | public static final int GENERATE = 2; 53 | private static final int REQUEST_CODE_SCAN_ONE = 0X01; 54 | private static final int REQUEST_CODE_DEFINE = 0X0111; 55 | private static final int REQUEST_CODE_SCAN_MULTI = 0X011; 56 | public static final String DECODE_MODE = "decode_mode"; 57 | public static final String RESULT = "SCAN_RESULT"; 58 | 59 | @Override 60 | protected void onCreate(Bundle savedInstanceState) { 61 | super.onCreate(savedInstanceState); 62 | requestWindowFeature(Window.FEATURE_NO_TITLE); 63 | setContentView(R.layout.activity_mwcmain); 64 | 65 | int orientation = Configuration.ORIENTATION_LANDSCAPE; 66 | 67 | Resources resources = this.getResources(); 68 | if (resources != null) { 69 | orientation = resources.getConfiguration().orientation; 70 | } 71 | if (orientation == Configuration.ORIENTATION_LANDSCAPE){ 72 | setContentView(R.layout.activity_mwcmain_landscape); 73 | }else{ 74 | setContentView(R.layout.activity_mwcmain); 75 | } 76 | 77 | 78 | this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 79 | //Set noTitleBar. 80 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 81 | Window window = getWindow(); 82 | this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 83 | if (window != null) { 84 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * Call the default view. 91 | */ 92 | public void loadScanKitBtnClick(View view) { 93 | requestPermission(CAMERA_REQ_CODE, DECODE); 94 | } 95 | 96 | /** 97 | * Call the customized view. 98 | */ 99 | public void newViewBtnClick(View view) { 100 | requestPermission(DEFINED_CODE, DECODE); 101 | } 102 | 103 | /** 104 | * Call the bitmap. 105 | */ 106 | public void bitmapBtnClick(View view) { 107 | requestPermission(BITMAP_CODE, DECODE); 108 | } 109 | 110 | /** 111 | * Call the MultiProcessor API in synchronous mode. 112 | */ 113 | public void multiProcessorSynBtnClick(View view) { 114 | requestPermission(MULTIPROCESSOR_SYN_CODE, DECODE); 115 | } 116 | 117 | /** 118 | * Call the MultiProcessor API in asynchronous mode. 119 | */ 120 | public void multiProcessorAsynBtnClick(View view) { 121 | requestPermission(MULTIPROCESSOR_ASYN_CODE, DECODE); 122 | } 123 | 124 | /** 125 | * Start generating the barcode. 126 | */ 127 | public void generateQRCodeBtnClick(View view) { 128 | requestPermission(GENERATE_CODE, GENERATE); 129 | } 130 | 131 | /** 132 | * Apply for permissions. 133 | */ 134 | private void requestPermission(int requestCode, int mode) { 135 | if (mode == DECODE) { 136 | decodePermission(requestCode); 137 | } else if (mode == GENERATE) { 138 | generatePermission(requestCode); 139 | } 140 | } 141 | 142 | /** 143 | * Apply for permissions. 144 | */ 145 | private void decodePermission(int requestCode) { 146 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 147 | ActivityCompat.requestPermissions( 148 | this, 149 | new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES}, 150 | requestCode); 151 | } else { 152 | ActivityCompat.requestPermissions( 153 | this, 154 | new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, 155 | requestCode); 156 | } 157 | } 158 | 159 | /** 160 | * Apply for permissions. 161 | */ 162 | private void generatePermission(int requestCode) { 163 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 164 | ActivityCompat.requestPermissions( 165 | this, 166 | new String[]{Manifest.permission.MANAGE_EXTERNAL_STORAGE}, 167 | requestCode); 168 | } else { 169 | ActivityCompat.requestPermissions( 170 | this, 171 | new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 172 | requestCode); 173 | } 174 | } 175 | 176 | /** 177 | * Call back the permission application result. If the permission application is successful, the barcode scanning view will be displayed. 178 | * @param requestCode Permission application code. 179 | * @param permissions Permission array. 180 | * @param grantResults: Permission application result array. 181 | */ 182 | @Override 183 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 184 | if (permissions == null || grantResults == null) { 185 | return; 186 | } 187 | 188 | if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == GENERATE_CODE) { 189 | Intent intent = new Intent(this, GenerateCodeActivity.class); 190 | this.startActivity(intent); 191 | } 192 | 193 | if (grantResults.length < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) { 194 | return; 195 | } 196 | //Default View Mode 197 | if (requestCode == CAMERA_REQ_CODE) { 198 | ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, new HmsScanAnalyzerOptions.Creator().create()); 199 | } 200 | //Customized View Mode 201 | if (requestCode == DEFINED_CODE) { 202 | Intent intent = new Intent(this, DefinedActivity.class); 203 | this.startActivityForResult(intent, REQUEST_CODE_DEFINE); 204 | } 205 | //Bitmap Mode 206 | if (requestCode == BITMAP_CODE) { 207 | Intent intent = new Intent(this, CommonActivity.class); 208 | intent.putExtra(DECODE_MODE, BITMAP_CODE); 209 | this.startActivityForResult(intent, REQUEST_CODE_SCAN_MULTI); 210 | } 211 | //Multiprocessor Synchronous Mode 212 | if (requestCode == MULTIPROCESSOR_SYN_CODE) { 213 | Intent intent = new Intent(this, CommonActivity.class); 214 | intent.putExtra(DECODE_MODE, MULTIPROCESSOR_SYN_CODE); 215 | this.startActivityForResult(intent, REQUEST_CODE_SCAN_MULTI); 216 | } 217 | //Multiprocessor Asynchronous Mode 218 | if (requestCode == MULTIPROCESSOR_ASYN_CODE) { 219 | Intent intent = new Intent(this, CommonActivity.class); 220 | intent.putExtra(DECODE_MODE, MULTIPROCESSOR_ASYN_CODE); 221 | this.startActivityForResult(intent, REQUEST_CODE_SCAN_MULTI); 222 | } 223 | } 224 | 225 | /** 226 | * Event for receiving the activity result. 227 | * 228 | * @param requestCode Request code. 229 | * @param resultCode Result code. 230 | * @param data Result. 231 | */ 232 | @RequiresApi(api = Build.VERSION_CODES.N) 233 | @Override 234 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 235 | super.onActivityResult(requestCode, resultCode, data); 236 | if (resultCode != RESULT_OK || data == null) { 237 | return; 238 | } 239 | //Default View 240 | if (requestCode == REQUEST_CODE_SCAN_ONE) { 241 | HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT); 242 | if (obj != null) { 243 | Intent intent = new Intent(this, DisPlayActivity.class); 244 | intent.putExtra(RESULT, obj); 245 | startActivity(intent); 246 | } 247 | //MultiProcessor & Bitmap 248 | } else if (requestCode == REQUEST_CODE_SCAN_MULTI) { 249 | Parcelable[] obj = data.getParcelableArrayExtra(CommonActivity.SCAN_RESULT); 250 | if (obj != null && obj.length > 0) { 251 | //Get one result. 252 | if (obj.length == 1) { 253 | if (obj[0] != null && !TextUtils.isEmpty(((HmsScan) obj[0]).getOriginalValue())) { 254 | Intent intent = new Intent(this, DisPlayActivity.class); 255 | intent.putExtra(RESULT, obj[0]); 256 | startActivity(intent); 257 | } 258 | } else { 259 | Intent intent = new Intent(this, DisPlayMulActivity.class); 260 | intent.putExtra(RESULT, obj); 261 | startActivity(intent); 262 | } 263 | } 264 | //Customized View 265 | } else if (requestCode == REQUEST_CODE_DEFINE) { 266 | HmsScan obj = data.getParcelableExtra(DefinedActivity.SCAN_RESULT); 267 | if (obj != null) { 268 | Intent intent = new Intent(this, DisPlayActivity.class); 269 | intent.putExtra(RESULT, obj); 270 | startActivity(intent); 271 | } 272 | } 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/CalendarEventAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.Intent; 19 | import android.icu.util.Calendar; 20 | import android.os.Build; 21 | import android.provider.CalendarContract; 22 | import android.util.Log; 23 | 24 | import androidx.annotation.RequiresApi; 25 | 26 | import com.huawei.hms.ml.scan.HmsScan; 27 | 28 | 29 | public class CalendarEventAction { 30 | @RequiresApi(api = Build.VERSION_CODES.N) 31 | public static Intent getCalendarEventIntent(HmsScan.EventInfo calendarEvent) { 32 | Intent intent = new Intent(Intent.ACTION_INSERT); 33 | try { 34 | intent.setData(CalendarContract.Events.CONTENT_URI) 35 | .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, getTime(calendarEvent.beginTime)) 36 | .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, getTime(calendarEvent.closeTime)) 37 | .putExtra(CalendarContract.Events.TITLE, calendarEvent.getTheme()) 38 | .putExtra(CalendarContract.Events.DESCRIPTION, calendarEvent.getAbstractInfo()) 39 | .putExtra(CalendarContract.Events.EVENT_LOCATION, calendarEvent.getPlaceInfo()) 40 | .putExtra(CalendarContract.Events.ORGANIZER, calendarEvent.getSponsor()) 41 | .putExtra(CalendarContract.Events.STATUS, calendarEvent.getCondition()); 42 | } catch (NullPointerException e) { 43 | Log.w("getCalendarEventIntent", e); 44 | } 45 | return intent; 46 | } 47 | 48 | @RequiresApi(api = Build.VERSION_CODES.N) 49 | private static long getTime(HmsScan.EventTime calendarDateTime) { 50 | Calendar calendar = Calendar.getInstance(); 51 | calendar.set(calendarDateTime.getYear(), calendarDateTime.getMonth() - 1, calendarDateTime.getDay(), 52 | calendarDateTime.getHours(), calendarDateTime.getMinutes(), calendarDateTime.getSeconds()); 53 | return calendar.getTime().getTime(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/ContactInfoAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.ContentValues; 19 | import android.content.Intent; 20 | import android.provider.ContactsContract; 21 | import android.util.Log; 22 | import android.util.SparseArray; 23 | 24 | import com.huawei.hms.ml.scan.HmsScan; 25 | 26 | import java.util.ArrayList; 27 | 28 | 29 | public class ContactInfoAction { 30 | private static final SparseArray addressMap = new SparseArray(); 31 | private static final SparseArray phoneMap = new SparseArray<>(); 32 | private static final SparseArray emailMap = new SparseArray<>(); 33 | 34 | static { 35 | addressMap.put(HmsScan.AddressInfo.OTHER_USE_TYPE, ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER); 36 | addressMap.put(HmsScan.AddressInfo.OFFICE_TYPE, ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK); 37 | addressMap.put(HmsScan.AddressInfo.RESIDENTIAL_USE_TYPE, ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME); 38 | 39 | phoneMap.put(HmsScan.TelPhoneNumber.OTHER_USE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_OTHER); 40 | phoneMap.put(HmsScan.TelPhoneNumber.OFFICE_USE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK); 41 | phoneMap.put(HmsScan.TelPhoneNumber.RESIDENTIAL_USE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_HOME); 42 | phoneMap.put(HmsScan.TelPhoneNumber.FAX_USE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX); 43 | phoneMap.put(HmsScan.TelPhoneNumber.CELLPHONE_NUMBER_USE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); 44 | 45 | emailMap.put(HmsScan.EmailContent.OTHER_USE_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_OTHER); 46 | emailMap.put(HmsScan.EmailContent.OFFICE_USE_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK); 47 | emailMap.put(HmsScan.EmailContent.RESIDENTIAL_USE_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_HOME); 48 | } 49 | 50 | public static Intent getContactInfoIntent(HmsScan.ContactDetail contactInfo) { 51 | Intent intent = new Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI); 52 | try { 53 | intent.putExtra(ContactsContract.Intents.Insert.NAME, contactInfo.getPeopleName().getFullName()); 54 | intent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, contactInfo.getTitle()); 55 | intent.putExtra(ContactsContract.Intents.Insert.COMPANY, contactInfo.getCompany()); 56 | ArrayList data = new ArrayList<>(); 57 | data.addAll(getAddresses(contactInfo)); 58 | data.addAll(getPhones(contactInfo)); 59 | data.addAll(getEmails(contactInfo)); 60 | data.addAll(getUrls(contactInfo)); 61 | intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, data); 62 | } catch (NullPointerException e) { 63 | Log.w("getCalendarEventIntent", e); 64 | } 65 | return intent; 66 | } 67 | 68 | private static ArrayList getAddresses(HmsScan.ContactDetail contactInfo) { 69 | ArrayList data = new ArrayList<>(); 70 | if ((contactInfo.getAddressesInfos() != null)) { 71 | for (HmsScan.AddressInfo address : contactInfo.getAddressesInfos()) { 72 | if (address.getAddressDetails() != null) { 73 | ContentValues contentValues = new ContentValues(); 74 | contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE); 75 | StringBuilder addressBuilder = new StringBuilder(); 76 | for (String addressLine : address.getAddressDetails()) { 77 | addressBuilder.append(addressLine); 78 | } 79 | contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, addressBuilder.toString()); 80 | Integer type = addressMap.get(address.getAddressType()); 81 | contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, 82 | type != null ? type : ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER); 83 | data.add(contentValues); 84 | } 85 | } 86 | } 87 | return data; 88 | } 89 | 90 | private static ArrayList getPhones(HmsScan.ContactDetail contactInfo) { 91 | ArrayList data = new ArrayList<>(); 92 | if ((contactInfo.getTelPhoneNumbers() != null)) { 93 | for (HmsScan.TelPhoneNumber phone : contactInfo.getTelPhoneNumbers()) { 94 | ContentValues contentValues = new ContentValues(); 95 | contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); 96 | contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone.getTelPhoneNumber()); 97 | Integer type = phoneMap.get(phone.getUseType()); 98 | contentValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, type != null ? type : ContactsContract.CommonDataKinds.Phone.TYPE_OTHER); 99 | data.add(contentValues); 100 | } 101 | } 102 | return data; 103 | } 104 | 105 | private static ArrayList getEmails(HmsScan.ContactDetail contactInfo) { 106 | ArrayList data = new ArrayList<>(); 107 | if ((contactInfo.getEmailContents() != null)) { 108 | for (HmsScan.EmailContent email : contactInfo.getEmailContents()) { 109 | ContentValues contentValues = new ContentValues(); 110 | contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE); 111 | contentValues.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email.getAddressInfo()); 112 | Integer type = emailMap.get(email.getAddressType()); 113 | contentValues.put(ContactsContract.CommonDataKinds.Email.TYPE, type != null ? type : ContactsContract.CommonDataKinds.Email.TYPE_OTHER); 114 | data.add(contentValues); 115 | } 116 | } 117 | return data; 118 | } 119 | 120 | private static ArrayList getUrls(HmsScan.ContactDetail contactInfo) { 121 | ArrayList data = new ArrayList<>(); 122 | if (contactInfo.getContactLinks() != null) { 123 | for (String url : contactInfo.getContactLinks()) { 124 | ContentValues contentValues = new ContentValues(); 125 | contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE); 126 | contentValues.put(ContactsContract.CommonDataKinds.Website.URL, url); 127 | data.add(contentValues); 128 | } 129 | } 130 | return data; 131 | } 132 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/DialAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.Intent; 19 | import android.net.Uri; 20 | 21 | import com.huawei.hms.ml.scan.HmsScan; 22 | 23 | public class DialAction { 24 | 25 | public static Intent getDialIntent(HmsScan.TelPhoneNumber telPhoneNumber) { 26 | Uri uri = Uri.parse("tel:" + telPhoneNumber.getTelPhoneNumber()); 27 | Intent intent = new Intent(Intent.ACTION_DIAL, uri); 28 | return intent; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/EmailAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.Intent; 19 | import android.net.Uri; 20 | 21 | import com.huawei.hms.ml.scan.HmsScan; 22 | 23 | public class EmailAction { 24 | 25 | public static Intent getEmailInfo(HmsScan.EmailContent emailContent) { 26 | Uri uri = Uri.parse("mailto:" + emailContent.addressInfo); 27 | String[] tos = {emailContent.addressInfo}; 28 | Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 29 | intent.putExtra(Intent.EXTRA_EMAIL, tos); 30 | intent.putExtra(Intent.EXTRA_SUBJECT, emailContent.subjectInfo); 31 | intent.putExtra(Intent.EXTRA_TEXT, emailContent.bodyInfo); 32 | return intent; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/LocationAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.Context; 19 | import android.content.Intent; 20 | import android.content.pm.PackageInfo; 21 | import android.net.Uri; 22 | import android.util.Log; 23 | 24 | import com.huawei.hms.ml.scan.HmsScan; 25 | 26 | public class LocationAction { 27 | 28 | private static String TAG = "LocationAction"; 29 | 30 | public final static String GAODE_PKG = "com.autonavi.minimap"; 31 | 32 | public static boolean checkMapAppExist(Context context) { 33 | PackageInfo packageInfo = null; 34 | try { 35 | packageInfo = context.getPackageManager().getPackageInfo(GAODE_PKG, 0); 36 | } catch (Exception e) { 37 | Log.w(TAG, e); 38 | } 39 | if (packageInfo == null) { 40 | return false; 41 | } else { 42 | return true; 43 | } 44 | 45 | } 46 | 47 | 48 | public static Intent getLoactionInfo(HmsScan.LocationCoordinate locationCoordinate) { 49 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("androidamap://viewMap?lat=" + locationCoordinate.getLatitude() + "&lon=" + locationCoordinate.getLongitude())); 50 | return intent; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/SMSAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.Intent; 19 | import android.net.Uri; 20 | 21 | import com.huawei.hms.ml.scan.HmsScan; 22 | 23 | public class SMSAction { 24 | 25 | public static Intent getSMSInfo(HmsScan.SmsContent smsContent) { 26 | Uri uri = Uri.parse("smsto:" + smsContent.getDestPhoneNumber()); 27 | Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 28 | intent.putExtra("sms_body", smsContent.getMsgContent()); 29 | return intent; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/action/WifiAdmin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.action; 17 | 18 | import android.content.Context; 19 | import android.net.wifi.WifiConfiguration; 20 | import android.net.wifi.WifiManager; 21 | 22 | import com.huawei.hms.ml.scan.HmsScan; 23 | 24 | import java.util.List; 25 | 26 | public class WifiAdmin { 27 | 28 | private WifiManager mWifiManager; 29 | 30 | public WifiAdmin(Context context) { 31 | mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 32 | } 33 | 34 | public boolean OpenWifi() { 35 | boolean bRet = true; 36 | if (!mWifiManager.isWifiEnabled()) { 37 | bRet = mWifiManager.setWifiEnabled(true); 38 | } 39 | return bRet; 40 | } 41 | 42 | public boolean Connect(String ssid, String password, int type) { 43 | if (!this.OpenWifi()) { 44 | return false; 45 | } 46 | while (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) { 47 | try { 48 | Thread.currentThread(); 49 | Thread.sleep(100); 50 | } catch (InterruptedException ie) { 51 | } 52 | } 53 | 54 | int netID = this.createWifiInfo(ssid, password, type); 55 | boolean bRet = mWifiManager.enableNetwork(netID, true); 56 | mWifiManager.saveConfiguration(); 57 | return bRet; 58 | } 59 | 60 | public int createWifiInfo(String ssid, String password, int type) 61 | { 62 | WifiConfiguration config = new WifiConfiguration(); 63 | config.allowedAuthAlgorithms.clear(); 64 | config.allowedGroupCiphers.clear(); 65 | config.allowedKeyManagement.clear(); 66 | config.allowedPairwiseCiphers.clear(); 67 | config.allowedProtocols.clear(); 68 | config.SSID = "\"" + ssid + "\""; 69 | 70 | WifiConfiguration tempConfig = this.isExsits(ssid); 71 | if(tempConfig != null) { 72 | if (!mWifiManager.removeNetwork(tempConfig.networkId)) { 73 | return tempConfig.networkId; 74 | } 75 | } 76 | 77 | if(type == HmsScan.WiFiConnectionInfo.NO_PASSWORD_MODE_TYPE) //WIFICIPHER_NOPASS 78 | { 79 | config.wepKeys[0] = ""; 80 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 81 | config.wepTxKeyIndex = 0; 82 | } 83 | if(type == HmsScan.WiFiConnectionInfo.WEP_MODE_TYPE) //WIFICIPHER_WEP 84 | { 85 | config.hiddenSSID = true; 86 | config.wepKeys[0]= "\""+password+"\""; 87 | config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); 88 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); 89 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); 90 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 91 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); 92 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 93 | config.wepTxKeyIndex = 0; 94 | } 95 | if(type == HmsScan.WiFiConnectionInfo.WPA_MODE_TYPE) //WIFICIPHER_WPA 96 | { 97 | config.preSharedKey = "\""+password+"\""; 98 | config.hiddenSSID = true; 99 | config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); 100 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); 101 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); 102 | config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); 103 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); 104 | config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); 105 | config.status = WifiConfiguration.Status.ENABLED; 106 | } 107 | return mWifiManager.addNetwork(config); 108 | } 109 | 110 | private WifiConfiguration isExsits(String SSID) 111 | { 112 | List existingConfigs = mWifiManager.getConfiguredNetworks(); 113 | for (WifiConfiguration existingConfig : existingConfigs) 114 | { 115 | if (existingConfig.SSID.equals("\""+SSID+"\"")) 116 | { 117 | return existingConfig; 118 | } 119 | } 120 | return null; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemo/draw/ScanResultView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.scankitdemo.draw; 17 | 18 | import android.content.Context; 19 | import android.graphics.Canvas; 20 | import android.graphics.Color; 21 | import android.graphics.Paint; 22 | import android.graphics.RectF; 23 | import android.util.AttributeSet; 24 | import android.view.View; 25 | 26 | import com.huawei.hms.ml.scan.HmsScan; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | import androidx.annotation.Nullable; 32 | 33 | public class ScanResultView extends View { 34 | 35 | private final Object lock = new Object(); 36 | protected float widthScaleFactor = 1.0f; 37 | protected float heightScaleFactor = 1.0f; 38 | protected float previewWidth; 39 | protected float previewHeight; 40 | 41 | private final List hmsScanGraphics = new ArrayList<>(); 42 | 43 | public ScanResultView(Context context) { 44 | super(context); 45 | } 46 | 47 | public ScanResultView(Context context, @Nullable AttributeSet attrs) { 48 | super(context, attrs); 49 | } 50 | 51 | public void clear() { 52 | synchronized (lock) { 53 | hmsScanGraphics.clear(); 54 | } 55 | postInvalidate(); 56 | } 57 | 58 | public void add(HmsScanGraphic graphic) { 59 | synchronized (lock) { 60 | hmsScanGraphics.add(graphic); 61 | } 62 | } 63 | 64 | public void setCameraInfo(int previewWidth, int previewHeight) { 65 | synchronized (lock) { 66 | this.previewWidth = previewWidth; 67 | this.previewHeight = previewHeight; 68 | } 69 | postInvalidate(); 70 | } 71 | 72 | /** 73 | * Draw MultiCodes on screen. 74 | */ 75 | @Override 76 | protected void onDraw(Canvas canvas) { 77 | super.onDraw(canvas); 78 | 79 | synchronized (lock) { 80 | if ((previewWidth != 0) && (previewHeight != 0)) { 81 | widthScaleFactor = (float) canvas.getWidth() / (float) previewWidth; 82 | heightScaleFactor = (float) canvas.getHeight() / (float) previewHeight; 83 | } 84 | 85 | for (HmsScanGraphic graphic : hmsScanGraphics) { 86 | graphic.drawGraphic(canvas); 87 | } 88 | } 89 | } 90 | 91 | public static class HmsScanGraphic { 92 | 93 | private static final int TEXT_COLOR = Color.WHITE; 94 | private static final float TEXT_SIZE = 35.0f; 95 | private static final float STROKE_WIDTH = 4.0f; 96 | 97 | private final Paint rectPaint; 98 | private final Paint hmsScanResult; 99 | private final HmsScan hmsScan; 100 | private ScanResultView scanResultView; 101 | 102 | public HmsScanGraphic(ScanResultView scanResultView, HmsScan hmsScan) { 103 | this(scanResultView, hmsScan, Color.WHITE); 104 | } 105 | 106 | public HmsScanGraphic(ScanResultView scanResultView, HmsScan hmsScan, int color) { 107 | this.scanResultView = scanResultView; 108 | this.hmsScan = hmsScan; 109 | 110 | rectPaint = new Paint(); 111 | rectPaint.setColor(color); 112 | rectPaint.setStyle(Paint.Style.STROKE); 113 | rectPaint.setStrokeWidth(STROKE_WIDTH); 114 | 115 | hmsScanResult = new Paint(); 116 | hmsScanResult.setColor(TEXT_COLOR); 117 | hmsScanResult.setTextSize(TEXT_SIZE); 118 | } 119 | 120 | 121 | public void drawGraphic(Canvas canvas) { 122 | if (hmsScan == null) { 123 | return; 124 | } 125 | 126 | RectF rect = new RectF(hmsScan.getBorderRect()); 127 | RectF other = new RectF(); 128 | other.left = canvas.getWidth()-scaleX(rect.top); 129 | other.top = scaleY(rect.left); 130 | other.right = canvas.getWidth()-scaleX(rect.bottom); 131 | other.bottom = scaleY(rect.right); 132 | canvas.drawRect(other, rectPaint); 133 | 134 | canvas.drawText(hmsScan.getOriginalValue(), other.right, other.bottom, hmsScanResult); 135 | } 136 | 137 | public float scaleX(float horizontal) { 138 | return horizontal * scanResultView.widthScaleFactor; 139 | } 140 | 141 | public float scaleY(float vertical) { 142 | return vertical * scanResultView.heightScaleFactor; 143 | } 144 | 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemokotlin/CommonHandler.kt: -------------------------------------------------------------------------------- 1 | package com.example.scankitdemokotlin 2 | 3 | import android.app.Activity 4 | import android.content.Intent 5 | import android.graphics.* 6 | import android.os.Handler 7 | import android.os.HandlerThread 8 | import android.os.Message 9 | import android.text.TextUtils 10 | import android.util.Log 11 | import com.example.scankitdemo.CameraOperation 12 | 13 | import com.example.scankitdemo.draw.ScanResultView.HmsScanGraphic 14 | import com.example.scankitdemokotlin.CommonActivity.Companion.SCAN_RESULT 15 | import com.example.scankitdemokotlin.MainActivity.Companion.BITMAP_CODE 16 | import com.example.scankitdemokotlin.MainActivity.Companion.MULTIPROCESSOR_ASYN_CODE 17 | import com.example.scankitdemokotlin.MainActivity.Companion.MULTIPROCESSOR_SYN_CODE 18 | import com.huawei.hmf.tasks.OnSuccessListener 19 | import com.huawei.hms.hmsscankit.ScanUtil 20 | import com.huawei.hms.ml.scan.HmsScan 21 | import com.huawei.hms.ml.scan.HmsScanAnalyzer 22 | import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions 23 | import com.huawei.hms.mlsdk.common.MLFrame 24 | import java.io.ByteArrayOutputStream 25 | 26 | class CommonHandler(val activity: Activity, val cameraOperation: CameraOperation, val mode: Int) :Handler() { 27 | private var decodeThread: HandlerThread? = null 28 | private var decodeHandle: Handler? = null 29 | 30 | companion object { 31 | const val TAG = "MainHandler" 32 | const val DEFAULT_ZOOM:Double = 1.00 33 | } 34 | 35 | init { 36 | decodeThread = HandlerThread("DecodeThread") 37 | decodeThread?.start() 38 | decodeHandle = object : Handler(decodeThread?.getLooper()!!) { 39 | override fun handleMessage(msg: Message) { 40 | if (msg == null) { 41 | return 42 | } 43 | if (mode == BITMAP_CODE || mode == MULTIPROCESSOR_SYN_CODE) { 44 | var result: Array? = decodeSyn(msg.arg1, msg.arg2, msg.obj as ByteArray, activity, HmsScan.ALL_SCAN_TYPE, mode) 45 | if (result == null || result.size == 0) { 46 | restart(DEFAULT_ZOOM) 47 | } else if (TextUtils.isEmpty(result[0]!!.getOriginalValue()) && result[0]!!.getZoomValue() != 1.0) { 48 | restart(result[0]!!.getZoomValue()) 49 | } else if (!TextUtils.isEmpty(result[0]!!.getOriginalValue())) { 50 | val message = Message() 51 | message.what = msg.what 52 | message.obj = result 53 | this@CommonHandler.sendMessage(message) 54 | restart(DEFAULT_ZOOM) 55 | } else { 56 | restart(DEFAULT_ZOOM) 57 | } 58 | } 59 | if (mode == MULTIPROCESSOR_ASYN_CODE) { 60 | decodeAsyn(msg.arg1, msg.arg2, msg.obj as ByteArray, activity, HmsScan.ALL_SCAN_TYPE) 61 | } 62 | } 63 | } 64 | cameraOperation.startPreview() 65 | restart(DEFAULT_ZOOM) 66 | } 67 | 68 | /** 69 | * Call the MultiProcessor API in synchronous mode. 70 | */ 71 | private fun decodeSyn(width: Int, height: Int, data: ByteArray, activity: Activity, type: Int, mode: Int): Array? { 72 | val bitmap = convertToBitmap(width, height, data) 73 | if (mode == BITMAP_CODE) { 74 | val options = HmsScanAnalyzerOptions.Creator().setHmsScanTypes(type).setPhotoMode(false).create() 75 | return ScanUtil.decodeWithBitmap(activity, bitmap, options) 76 | } else if (mode == MULTIPROCESSOR_SYN_CODE) { 77 | val image = MLFrame.fromBitmap(bitmap) 78 | val options = HmsScanAnalyzerOptions.Creator().setHmsScanTypes(type).create() 79 | val analyzer = HmsScanAnalyzer(options) 80 | val result = analyzer.analyseFrame(image) 81 | if (result != null && result.size() > 0 && result.valueAt(0) != null && !TextUtils.isEmpty(result.valueAt(0)!!.getOriginalValue())) { 82 | val info = arrayOfNulls(result.size()) 83 | for (index in 0 until result.size()) { 84 | info[index] = result.valueAt(index) 85 | } 86 | return info 87 | } 88 | } 89 | return null 90 | } 91 | 92 | /** 93 | * Convert camera data into bitmap data. 94 | */ 95 | private fun convertToBitmap(width: Int, height: Int, data: ByteArray): Bitmap { 96 | val yuv = YuvImage(data, ImageFormat.NV21, width, height, null) 97 | val stream = ByteArrayOutputStream() 98 | yuv.compressToJpeg(Rect(0, 0, width, height), 100, stream) 99 | return BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.toByteArray().size) 100 | } 101 | 102 | /** 103 | * Call the MultiProcessor API in asynchronous mode. 104 | */ 105 | private fun decodeAsyn(width: Int, height: Int, data: ByteArray, activity: Activity, type: Int) { 106 | var bitmap = convertToBitmap(width, height, data) 107 | val image = MLFrame.fromBitmap(bitmap) 108 | val options = HmsScanAnalyzerOptions.Creator().setHmsScanTypes(type).create() 109 | val analyzer = HmsScanAnalyzer(options) 110 | 111 | analyzer.analyzInAsyn(image).addOnSuccessListener(OnSuccessListener?> { 112 | if (it != null && it.size > 0 && it[0] != null && !TextUtils.isEmpty(it[0]!!.getOriginalValue())) { 113 | //val infos:Array = arrayOfNulls(it.size) 114 | val message = Message() 115 | message.obj = it.toTypedArray() 116 | sendMessage(message) 117 | restart(DEFAULT_ZOOM) 118 | } else { 119 | restart(DEFAULT_ZOOM) 120 | } 121 | bitmap.recycle() 122 | }).addOnFailureListener { e -> 123 | Log.w(TAG, e) 124 | restart(DEFAULT_ZOOM) 125 | bitmap.recycle() 126 | } 127 | } 128 | 129 | override fun handleMessage(message: Message) { 130 | Log.e(TAG, message.what.toString()) 131 | removeMessages(1) 132 | if (message.what == 0) { 133 | 134 | val commonActivity1 = activity as CommonActivity 135 | commonActivity1.scanResultView?.clear() 136 | val intent = Intent() 137 | intent.putExtra(SCAN_RESULT, message.obj as Array) 138 | activity.setResult(Activity.RESULT_OK, intent) 139 | //Show the scanning result on the screen. 140 | if (mode == MULTIPROCESSOR_ASYN_CODE || mode == MULTIPROCESSOR_SYN_CODE) { 141 | val commonActivity = activity 142 | val arr = message.obj as Array 143 | if (arr!=null&&arr.size>=0) { 144 | for (i in arr.indices) { 145 | if (i == 0) { 146 | commonActivity.scanResultView?.add(HmsScanGraphic(commonActivity.scanResultView!!, arr[i], Color.YELLOW)) 147 | } else if (i == 1) { 148 | commonActivity.scanResultView?.add(HmsScanGraphic(commonActivity.scanResultView!!, arr[i], Color.BLUE)) 149 | } else if (i == 2) { 150 | commonActivity.scanResultView?.add(HmsScanGraphic(commonActivity.scanResultView!!, arr[i], Color.RED)) 151 | } else if (i == 3) { 152 | commonActivity.scanResultView?.add(HmsScanGraphic(commonActivity.scanResultView!!, arr[i], Color.GREEN)) 153 | } else { 154 | commonActivity.scanResultView?.add(HmsScanGraphic(commonActivity.scanResultView!!, arr[i])) 155 | } 156 | } 157 | } 158 | commonActivity.scanResultView!!.setCameraInfo(1080, 1920) 159 | commonActivity.scanResultView!!.invalidate() 160 | sendEmptyMessageDelayed(1, 1000) 161 | } else { 162 | activity.finish() 163 | } 164 | } else if (message.what == 1) { 165 | val commonActivity1 = activity as CommonActivity 166 | commonActivity1.scanResultView?.clear() 167 | } 168 | } 169 | 170 | fun quit() { 171 | try { 172 | cameraOperation.stopPreview() 173 | decodeHandle!!.looper.quit() 174 | decodeThread!!.join(500) 175 | } catch (e: InterruptedException) { 176 | Log.w(TAG, e) 177 | } 178 | } 179 | 180 | fun restart(zoomValue: Double) { 181 | cameraOperation.callbackFrame(decodeHandle, zoomValue) 182 | } 183 | 184 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemokotlin/DefinedActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.scankitdemokotlin 2 | 3 | import android.app.Activity 4 | import android.content.Intent 5 | import android.graphics.Rect 6 | import android.os.Bundle 7 | import android.provider.MediaStore 8 | import android.text.TextUtils 9 | import android.view.View 10 | import android.view.Window 11 | import android.widget.FrameLayout 12 | import android.widget.ImageView 13 | import android.widget.LinearLayout 14 | import com.example.scankitdemo.R 15 | import com.huawei.hms.hmsscankit.OnLightVisibleCallBack 16 | import com.huawei.hms.hmsscankit.OnResultCallback 17 | import com.huawei.hms.hmsscankit.RemoteView 18 | import com.huawei.hms.hmsscankit.ScanUtil 19 | import com.huawei.hms.ml.scan.HmsScan 20 | import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions 21 | import java.io.IOException 22 | 23 | class DefinedActivity:Activity() { 24 | var frameLayout:FrameLayout? = null 25 | var remoteView:RemoteView? = null 26 | var backBtn:ImageView? = null 27 | var imgBtn:ImageView? = null 28 | var flushBtn:ImageView? = null 29 | 30 | var mScreenWidth = 0 31 | var mScreenHeight = 0 32 | 33 | val SCAN_FRAME_SIZE = 240 34 | val img = intArrayOf(R.drawable.flashlight_on, R.drawable.flashlight_off) 35 | 36 | companion object{ 37 | const val SCAN_RESULT = "scanResult" 38 | const val REQUEST_CODE_PHOTO = 0X1113 39 | } 40 | 41 | override fun onCreate(savedInstanceState: Bundle?) { 42 | super.onCreate(savedInstanceState) 43 | requestWindowFeature(Window.FEATURE_NO_TITLE) 44 | setContentView(R.layout.activity_defined) 45 | 46 | frameLayout = findViewById(R.id.rim) 47 | 48 | //1. Obtain the screen density to calculate the viewfinder's rectangle. 49 | val dm = resources.displayMetrics 50 | val density = dm.density 51 | //2. Obtain the screen size. 52 | //2. Obtain the screen size. 53 | mScreenWidth = resources.displayMetrics.widthPixels 54 | mScreenHeight = resources.displayMetrics.heightPixels 55 | 56 | val scanFrameSize = (SCAN_FRAME_SIZE * density).toInt() 57 | 58 | //3. Calculate the viewfinder's rectangle, which in the middle of the layout. 59 | //Set the scanning area. (Optional. Rect can be null. If no settings are specified, it will be located in the middle of the layout.) 60 | 61 | //3. Calculate the viewfinder's rectangle, which in the middle of the layout. 62 | //Set the scanning area. (Optional. Rect can be null. If no settings are specified, it will be located in the middle of the layout.) 63 | val rect = Rect() 64 | rect.left = mScreenWidth / 2 - scanFrameSize / 2 65 | rect.right = mScreenWidth / 2 + scanFrameSize / 2 66 | rect.top = mScreenHeight / 2 - scanFrameSize / 2 67 | rect.bottom = mScreenHeight / 2 + scanFrameSize / 2 68 | 69 | 70 | //Initialize the RemoteView instance, and set callback for the scanning result. 71 | 72 | 73 | //Initialize the RemoteView instance, and set callback for the scanning result. 74 | remoteView = RemoteView.Builder().setContext(this).setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build() 75 | // When the light is dim, this API is called back to display the flashlight switch. 76 | // When the light is dim, this API is called back to display the flashlight switch. 77 | flushBtn = findViewById(R.id.flush_btn) 78 | remoteView?.setOnLightVisibleCallback(OnLightVisibleCallBack { visible -> 79 | if (visible) { 80 | flushBtn?.setVisibility(View.VISIBLE) 81 | } 82 | }) 83 | // Subscribe to the scanning result callback event. 84 | // Subscribe to the scanning result callback event. 85 | remoteView?.setOnResultCallback(OnResultCallback { result -> //Check the result. 86 | if (result != null && result.size > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) { 87 | val intent = Intent() 88 | intent.putExtra(SCAN_RESULT, result[0]) 89 | setResult(RESULT_OK, intent) 90 | finish() 91 | } 92 | }) 93 | 94 | // Load the customized view to the activity. 95 | // Load the customized view to the activity. 96 | remoteView?.onCreate(savedInstanceState) 97 | val params = FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT) 98 | frameLayout?.addView(remoteView, params) 99 | // Set the back, photo scanning, and flashlight operations. 100 | // Set the back, photo scanning, and flashlight operations. 101 | setBackOperation() 102 | setPictureScanOperation() 103 | setFlashOperation() 104 | } 105 | 106 | private fun setPictureScanOperation() { 107 | imgBtn = findViewById(R.id.img_btn) 108 | imgBtn?.setOnClickListener(View.OnClickListener { 109 | val pickIntent = Intent(Intent.ACTION_PICK, 110 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI) 111 | pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*") 112 | this@DefinedActivity.startActivityForResult(pickIntent, REQUEST_CODE_PHOTO) 113 | }) 114 | } 115 | 116 | private fun setFlashOperation() { 117 | flushBtn?.setOnClickListener { 118 | if (remoteView?.lightStatus ?:false) { 119 | remoteView?.switchLight() 120 | flushBtn?.setImageResource(img[1]) 121 | } else { 122 | remoteView?.switchLight() 123 | flushBtn?.setImageResource(img[0]) 124 | } 125 | } 126 | } 127 | 128 | private fun setBackOperation() { 129 | backBtn = findViewById(R.id.back_img) 130 | backBtn?.setOnClickListener(View.OnClickListener { finish() }) 131 | } 132 | 133 | override fun onStart() { 134 | super.onStart() 135 | remoteView?.onStart() 136 | } 137 | 138 | override fun onResume() { 139 | super.onResume() 140 | remoteView?.onResume() 141 | } 142 | 143 | override fun onPause() { 144 | super.onPause() 145 | remoteView?.onPause() 146 | } 147 | 148 | override fun onStop() { 149 | super.onStop() 150 | remoteView?.onStop() 151 | } 152 | 153 | override fun onDestroy() { 154 | super.onDestroy() 155 | remoteView?.onDestroy() 156 | } 157 | 158 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { 159 | super.onActivityResult(requestCode, resultCode, data) 160 | if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_PHOTO) { 161 | try { 162 | val bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, data.data) 163 | val hmsScans = ScanUtil.decodeWithBitmap(this@DefinedActivity, bitmap, HmsScanAnalyzerOptions.Creator().setPhotoMode(true).create()) 164 | if (hmsScans != null && hmsScans.size > 0 && hmsScans[0] != null && !TextUtils.isEmpty(hmsScans[0]!!.getOriginalValue())) { 165 | val intent = Intent() 166 | intent.putExtra(SCAN_RESULT, hmsScans[0]) 167 | setResult(RESULT_OK, intent) 168 | finish() 169 | } 170 | } catch (e: IOException) { 171 | e.printStackTrace() 172 | } 173 | } 174 | } 175 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemokotlin/DisPlayMulActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.scankitdemokotlin 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.os.Build 6 | import android.os.Bundle 7 | import android.os.Vibrator 8 | import android.text.TextUtils 9 | import android.view.LayoutInflater 10 | import android.view.View 11 | import android.view.Window 12 | import android.view.WindowManager 13 | import android.widget.ImageView 14 | import android.widget.LinearLayout 15 | import android.widget.RelativeLayout 16 | import android.widget.TextView 17 | import com.example.scankitdemo.R 18 | import com.example.scankitdemokotlin.MainActivity.Companion.RESULT 19 | import com.huawei.hms.ml.scan.HmsScan 20 | 21 | class DisPlayMulActivity:Activity() { 22 | private var backBtn: ImageView? = null 23 | private var codeFormat: TextView? = null 24 | private var resultType: TextView? = null 25 | private var rawResult: TextView? = null 26 | private var scrollView: LinearLayout? = null 27 | private var view: View? = null 28 | 29 | override fun onCreate(savedInstanceState: Bundle?) { 30 | super.onCreate(savedInstanceState) 31 | requestWindowFeature(Window.FEATURE_NO_TITLE) 32 | setContentView(R.layout.activity_display_mul) 33 | backBtn = findViewById(R.id.result_back_img_in) 34 | backBtn?.setOnClickListener(View.OnClickListener { finish() }) 35 | scrollView = findViewById(R.id.scroll_item) 36 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 37 | val window = window 38 | window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 39 | window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) 40 | val relativeLayout = findViewById(R.id.result_title) 41 | if (relativeLayout != null) { 42 | val lp = RelativeLayout.LayoutParams(relativeLayout.layoutParams.width, relativeLayout.layoutParams.height) 43 | lp.setMargins(0, getStatusBarHeight(), 0, 0) 44 | relativeLayout.layoutParams = lp 45 | } 46 | } 47 | val vibrator = this.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator 48 | vibrator.vibrate(300) 49 | val layoutInflater = LayoutInflater.from(this) 50 | //Obtain the scanning result. 51 | val obj = intent.getParcelableArrayExtra(RESULT) 52 | if (obj != null) { 53 | for (i in obj.indices) { 54 | if (obj[i] is HmsScan && !TextUtils.isEmpty((obj[i] as HmsScan).getOriginalValue())) { 55 | view = layoutInflater.inflate(R.layout.activity_display_item, null) 56 | scrollView?.addView(view) 57 | valueFillIn(obj[i] as HmsScan, view) 58 | } 59 | } 60 | } 61 | view?.findViewById(R.id.line)?.visibility = View.GONE 62 | } 63 | 64 | /** 65 | * Display the scanning result in TextView. 66 | */ 67 | private fun valueFillIn(hmsScan: HmsScan, view: View?) { 68 | codeFormat = view?.findViewById(R.id.barcode_type) 69 | resultType = view?.findViewById(R.id.barcode_type_mon) 70 | rawResult = view?.findViewById(R.id.barcode_rawValue) 71 | rawResult?.setText(hmsScan.getOriginalValue()) 72 | if (hmsScan.getScanType() == HmsScan.QRCODE_SCAN_TYPE) { 73 | codeFormat?.setText("QR code") 74 | } else if (hmsScan.getScanType() == HmsScan.AZTEC_SCAN_TYPE) { 75 | codeFormat?.setText("AZTEC code") 76 | } else if (hmsScan.getScanType() == HmsScan.DATAMATRIX_SCAN_TYPE) { 77 | codeFormat?.setText("DATAMATRIX code") 78 | } else if (hmsScan.getScanType() == HmsScan.PDF417_SCAN_TYPE) { 79 | codeFormat?.setText("PDF417 code") 80 | } else if (hmsScan.getScanType() == HmsScan.CODE93_SCAN_TYPE) { 81 | codeFormat?.setText("CODE93") 82 | } else if (hmsScan.getScanType() == HmsScan.CODE39_SCAN_TYPE) { 83 | codeFormat?.setText("CODE39") 84 | } else if (hmsScan.getScanType() == HmsScan.CODE128_SCAN_TYPE) { 85 | codeFormat?.setText("CODE128") 86 | } else if (hmsScan.getScanType() == HmsScan.EAN13_SCAN_TYPE) { 87 | codeFormat?.setText("EAN13 code") 88 | } else if (hmsScan.getScanType() == HmsScan.EAN8_SCAN_TYPE) { 89 | codeFormat?.setText("EAN8 code") 90 | } else if (hmsScan.getScanType() == HmsScan.ITF14_SCAN_TYPE) { 91 | codeFormat?.setText("ITF14 code") 92 | } else if (hmsScan.getScanType() == HmsScan.UPCCODE_A_SCAN_TYPE) { 93 | codeFormat?.setText("UPCCODE_A") 94 | } else if (hmsScan.getScanType() == HmsScan.UPCCODE_E_SCAN_TYPE) { 95 | codeFormat?.setText("UPCCODE_E") 96 | } else if (hmsScan.getScanType() == HmsScan.CODABAR_SCAN_TYPE) { 97 | codeFormat?.setText("CODABAR") 98 | } 99 | if (hmsScan.getScanType() == HmsScan.QRCODE_SCAN_TYPE) { 100 | if (hmsScan.getScanTypeForm() == HmsScan.PURE_TEXT_FORM) { 101 | resultType?.setText("Text") 102 | } else if (hmsScan.getScanTypeForm() == HmsScan.EVENT_INFO_FORM) { 103 | resultType?.setText("Event") 104 | } else if (hmsScan.getScanTypeForm() == HmsScan.CONTACT_DETAIL_FORM) { 105 | resultType?.setText("Contact") 106 | } else if (hmsScan.getScanTypeForm() == HmsScan.DRIVER_INFO_FORM) { 107 | resultType?.setText("License") 108 | } else if (hmsScan.getScanTypeForm() == HmsScan.EMAIL_CONTENT_FORM) { 109 | resultType?.setText("Email") 110 | } else if (hmsScan.getScanTypeForm() == HmsScan.TEL_PHONE_NUMBER_FORM) { 111 | resultType?.setText("Tel") 112 | } else if (hmsScan.getScanTypeForm() == HmsScan.SMS_FORM) { 113 | resultType?.setText("SMS") 114 | } else if (hmsScan.getScanTypeForm() == HmsScan.WIFI_CONNECT_INFO_FORM) { 115 | resultType?.setText("Wi-Fi") 116 | } else if (hmsScan.getScanTypeForm() == HmsScan.URL_FORM) { 117 | resultType?.setText("WebSite") 118 | } else if (hmsScan.getScanTypeForm() == HmsScan.ARTICLE_NUMBER_FORM) { 119 | resultType?.setText("Product") 120 | } else { 121 | resultType?.setText("Text") 122 | } 123 | } else if (hmsScan.getScanType() == HmsScan.EAN13_SCAN_TYPE) { 124 | if (hmsScan.getScanTypeForm() == HmsScan.ISBN_NUMBER_FORM) { 125 | resultType?.setText("ISBN") 126 | } else if (hmsScan.getScanTypeForm() == HmsScan.ARTICLE_NUMBER_FORM) { 127 | resultType?.setText("Product") 128 | } else { 129 | resultType?.setText("Text") 130 | } 131 | } else if (hmsScan.getScanType() == HmsScan.EAN8_SCAN_TYPE || hmsScan.getScanType() == HmsScan.UPCCODE_A_SCAN_TYPE || hmsScan.getScanType() == HmsScan.UPCCODE_E_SCAN_TYPE) { 132 | if (hmsScan.getScanTypeForm() == HmsScan.ARTICLE_NUMBER_FORM) { 133 | resultType?.setText("Product") 134 | } else { 135 | resultType?.setText("Text") 136 | } 137 | } else { 138 | resultType?.setText("Text") 139 | } 140 | } 141 | 142 | protected fun getStatusBarHeight(): Int { 143 | var result = 0 144 | // Obtain the ID. 145 | if (resources != null) { 146 | val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android") 147 | if (resourceId > 0) { 148 | result = resources.getDimensionPixelSize(resourceId) 149 | } 150 | } 151 | return result 152 | } 153 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemokotlin/GenerateCodeActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.scankitdemokotlin 2 | 3 | import android.app.Activity 4 | import android.content.Intent 5 | import android.graphics.Bitmap 6 | import android.graphics.Color 7 | import android.net.Uri 8 | import android.os.Build 9 | import android.os.Bundle 10 | import android.os.Environment 11 | import android.util.Log 12 | import android.view.View 13 | import android.view.Window 14 | import android.view.WindowManager 15 | import android.widget.* 16 | import android.widget.AdapterView.OnItemSelectedListener 17 | import com.example.scankitdemo.R 18 | import com.huawei.hms.hmsscankit.ScanUtil 19 | import com.huawei.hms.hmsscankit.WriterException 20 | import com.huawei.hms.ml.scan.HmsBuildBitmapOption 21 | import com.huawei.hms.ml.scan.HmsScan 22 | import java.io.File 23 | import java.io.FileOutputStream 24 | import java.util.* 25 | 26 | class GenerateCodeActivity:Activity() { 27 | 28 | private val TAG = "GenerateCodeActivity" 29 | private val BARCODE_TYPES = intArrayOf(HmsScan.QRCODE_SCAN_TYPE, HmsScan.DATAMATRIX_SCAN_TYPE, HmsScan.PDF417_SCAN_TYPE, HmsScan.AZTEC_SCAN_TYPE, 30 | HmsScan.EAN8_SCAN_TYPE, HmsScan.EAN13_SCAN_TYPE, HmsScan.UPCCODE_A_SCAN_TYPE, HmsScan.UPCCODE_E_SCAN_TYPE, HmsScan.CODABAR_SCAN_TYPE, 31 | HmsScan.CODE39_SCAN_TYPE, HmsScan.CODE93_SCAN_TYPE, HmsScan.CODE128_SCAN_TYPE, HmsScan.ITF14_SCAN_TYPE) 32 | private val COLOR = intArrayOf(Color.BLACK, Color.BLUE, Color.GRAY, Color.GREEN, Color.RED, Color.YELLOW) 33 | private val BACKGROUND = intArrayOf(Color.WHITE, Color.YELLOW, Color.RED, Color.GREEN, Color.GRAY, Color.BLUE, Color.BLACK) 34 | 35 | //Define a view. 36 | private var inputContent: EditText? = null 37 | private var generateType: Spinner? = null 38 | private var generateMargin: Spinner? = null 39 | private var generateColor: Spinner? = null 40 | private var generateBackground: Spinner? = null 41 | private var barcodeImage: ImageView? = null 42 | private var barcodeWidth: EditText? = null 43 | private var barcodeHeight:EditText? = null 44 | private var content: String? = null 45 | private var width = 0 46 | private var height:Int = 0 47 | private var resultImage: Bitmap? = null 48 | private var type = 0 49 | private var margin = 1 50 | private var color = Color.BLACK 51 | private var background = Color.WHITE 52 | 53 | override fun onCreate(savedInstanceState: Bundle?) { 54 | super.onCreate(savedInstanceState) 55 | requestWindowFeature(Window.FEATURE_NO_TITLE) 56 | setContentView(R.layout.activity_generate) 57 | this.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 59 | val window = window 60 | window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 61 | window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) 62 | } 63 | inputContent = findViewById(R.id.barcode_content) 64 | generateType = findViewById(R.id.generate_type) 65 | generateMargin = findViewById(R.id.generate_margin) 66 | generateColor = findViewById(R.id.generate_color) 67 | generateBackground = findViewById(R.id.generate_backgroundcolor) 68 | barcodeImage = findViewById(R.id.barcode_image) 69 | barcodeWidth = findViewById(R.id.barcode_width) 70 | barcodeHeight = findViewById(R.id.barcode_height) 71 | //Set the barcode type. 72 | generateType?.setOnItemSelectedListener(object : OnItemSelectedListener { 73 | override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { 74 | type = BARCODE_TYPES[position] 75 | } 76 | 77 | override fun onNothingSelected(parent: AdapterView<*>?) { 78 | type = BARCODE_TYPES[0] 79 | } 80 | }) 81 | 82 | //Set the barcode margin. 83 | generateMargin?.setOnItemSelectedListener(object : OnItemSelectedListener { 84 | override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { 85 | margin = position + 1 86 | } 87 | 88 | override fun onNothingSelected(parent: AdapterView<*>?) { 89 | margin = 1 90 | } 91 | }) 92 | 93 | //Set the barcode color. 94 | generateColor?.setOnItemSelectedListener(object : OnItemSelectedListener { 95 | override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { 96 | color = COLOR[position] 97 | } 98 | 99 | override fun onNothingSelected(parent: AdapterView<*>?) { 100 | color = COLOR[0] 101 | } 102 | }) 103 | 104 | //Set the barcode background color. 105 | generateBackground?.setOnItemSelectedListener(object : OnItemSelectedListener { 106 | override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { 107 | background = BACKGROUND[position] 108 | } 109 | 110 | override fun onNothingSelected(parent: AdapterView<*>?) { 111 | background = BACKGROUND[0] 112 | } 113 | }) 114 | } 115 | 116 | /** 117 | * Generate a barcode. 118 | */ 119 | fun generateCodeBtnClick(v: View?) { 120 | content = inputContent!!.text.toString() 121 | val inputWidth = barcodeWidth!!.text.toString() 122 | val inputHeight: String = barcodeHeight?.getText().toString() 123 | //Set the barcode width and height. 124 | if (inputWidth.length <= 0 || inputHeight.length <= 0) { 125 | width = 700 126 | height = 700 127 | } else { 128 | width = inputWidth.toInt() 129 | height = inputHeight.toInt() 130 | } 131 | //Set the barcode content. 132 | if (content!!.length <= 0) { 133 | Toast.makeText(this, "Please input content first!", Toast.LENGTH_SHORT).show() 134 | return 135 | } 136 | if (color == background) { 137 | Toast.makeText(this, "The color and background cannot be the same!", Toast.LENGTH_SHORT).show() 138 | return 139 | } 140 | try { 141 | //Generate the barcode. 142 | val options = HmsBuildBitmapOption.Creator().setBitmapMargin(margin).setBitmapColor(color).setBitmapBackgroundColor(background).create() 143 | resultImage = ScanUtil.buildBitmap(content, type, width, height, options) 144 | barcodeImage!!.setImageBitmap(resultImage) 145 | } catch (e: WriterException) { 146 | Toast.makeText(this, "Parameter Error!", Toast.LENGTH_SHORT).show() 147 | } 148 | } 149 | 150 | /** 151 | * Save the barcode. 152 | */ 153 | fun saveCodeBtnClick(v: View?) { 154 | if (resultImage == null) { 155 | Toast.makeText(this@GenerateCodeActivity, "Please generate barcode first!", Toast.LENGTH_LONG).show() 156 | return 157 | } 158 | try { 159 | val fileName = System.currentTimeMillis().toString() + ".jpg" 160 | val storePath: String 161 | storePath = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 162 | applicationContext.getExternalFilesDir(null)!!.absolutePath 163 | } else { 164 | Environment.getExternalStorageDirectory().absolutePath 165 | } 166 | val appDir = File(storePath) 167 | if (!appDir.exists()) { 168 | appDir.mkdir() 169 | } 170 | val file = File(appDir, fileName) 171 | val fileOutputStream = FileOutputStream(file) 172 | val isSuccess = resultImage!!.compress(Bitmap.CompressFormat.JPEG, 70, fileOutputStream) 173 | fileOutputStream.flush() 174 | fileOutputStream.close() 175 | val uri = Uri.fromFile(file) 176 | this@GenerateCodeActivity.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)) 177 | if (isSuccess) { 178 | Toast.makeText(this@GenerateCodeActivity, "Barcode has been saved locally", Toast.LENGTH_LONG).show() 179 | } else { 180 | Toast.makeText(this@GenerateCodeActivity, "Barcode save failed", Toast.LENGTH_SHORT).show() 181 | } 182 | } catch (e: Exception) { 183 | Log.w(TAG, Objects.requireNonNull(e.message)!!) 184 | Toast.makeText(this@GenerateCodeActivity, "Unkown Error", Toast.LENGTH_SHORT).show() 185 | } 186 | } 187 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/scankitdemokotlin/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.scankitdemokotlin 2 | 3 | import android.Manifest 4 | import android.app.Activity 5 | import android.content.Intent 6 | import android.content.pm.PackageManager 7 | import android.os.Build 8 | import android.os.Bundle 9 | import android.text.TextUtils 10 | import android.view.View 11 | import android.view.Window 12 | import android.view.WindowManager 13 | import androidx.annotation.RequiresApi 14 | import androidx.core.app.ActivityCompat 15 | import com.example.scankitdemo.R 16 | import com.example.scankitdemokotlin.DefinedActivity.Companion.SCAN_RESULT 17 | import com.huawei.hms.hmsscankit.ScanUtil 18 | import com.huawei.hms.ml.scan.HmsScan 19 | import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions 20 | 21 | class MainActivity: Activity(),ActivityCompat.OnRequestPermissionsResultCallback { 22 | 23 | companion object { 24 | const val CAMERA_REQ_CODE = 111 25 | const val DEFINED_CODE = 222 26 | const val BITMAP_CODE = 333 27 | const val MULTIPROCESSOR_SYN_CODE = 444 28 | const val MULTIPROCESSOR_ASYN_CODE = 555 29 | const val GENERATE_CODE = 666 30 | const val DECODE = 1 31 | const val GENERATE = 2 32 | const val REQUEST_CODE_SCAN_ONE = 0X01 33 | const val REQUEST_CODE_DEFINE = 0X0111 34 | const val REQUEST_CODE_SCAN_MULTI = 0X011 35 | const val DECODE_MODE = "decode_mode" 36 | const val RESULT = "SCAN_RESULT" 37 | } 38 | 39 | override fun onCreate(savedInstanceState: Bundle?) { 40 | super.onCreate(savedInstanceState) 41 | requestWindowFeature(Window.FEATURE_NO_TITLE) 42 | setContentView(R.layout.activity_mwcmain) 43 | this.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 44 | //Set noTitleBar. 45 | //Set noTitleBar. 46 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 47 | val window = window 48 | window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 49 | window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) 50 | } 51 | } 52 | 53 | fun loadScanKitBtnClick(view: View?) { 54 | requestPermission(CAMERA_REQ_CODE, DECODE) 55 | } 56 | 57 | /** 58 | * Call the customized view. 59 | */ 60 | fun newViewBtnClick(view: View?) { 61 | requestPermission(DEFINED_CODE, DECODE) 62 | } 63 | 64 | /** 65 | * Call the bitmap. 66 | */ 67 | fun bitmapBtnClick(view: View?) { 68 | requestPermission(BITMAP_CODE, DECODE) 69 | } 70 | 71 | /** 72 | * Call the MultiProcessor API in synchronous mode. 73 | */ 74 | fun multiProcessorSynBtnClick(view: View?) { 75 | requestPermission(MULTIPROCESSOR_SYN_CODE, DECODE) 76 | } 77 | 78 | /** 79 | * Call the MultiProcessor API in asynchronous mode. 80 | */ 81 | fun multiProcessorAsynBtnClick(view: View?) { 82 | requestPermission(MULTIPROCESSOR_ASYN_CODE, DECODE) 83 | } 84 | 85 | /** 86 | * Start generating the barcode. 87 | */ 88 | fun generateQRCodeBtnClick(view: View?) { 89 | requestPermission(GENERATE_CODE, GENERATE) 90 | } 91 | 92 | /** 93 | * Apply for permissions. 94 | */ 95 | private fun requestPermission(requestCode: Int, mode: Int) { 96 | if (mode == DECODE) { 97 | decodePermission(requestCode) 98 | } else if (mode == GENERATE) { 99 | generatePermission(requestCode) 100 | } 101 | } 102 | 103 | /** 104 | * Apply for permissions. 105 | */ 106 | private fun decodePermission(requestCode: Int) { 107 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 108 | ActivityCompat.requestPermissions( 109 | this, arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES), 110 | requestCode 111 | ) 112 | } else { 113 | ActivityCompat.requestPermissions( 114 | this, 115 | arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE), 116 | requestCode 117 | ) 118 | } 119 | } 120 | 121 | /** 122 | * Apply for permissions. 123 | */ 124 | private fun generatePermission(requestCode: Int) { 125 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 126 | ActivityCompat.requestPermissions( 127 | this, arrayOf(Manifest.permission.MANAGE_EXTERNAL_STORAGE), 128 | requestCode) 129 | } else { 130 | ActivityCompat.requestPermissions( 131 | this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 132 | requestCode) 133 | } 134 | } 135 | 136 | /** 137 | * Call back the permission application result. If the permission application is successful, the barcode scanning view will be displayed. 138 | * @param requestCode Permission application code. 139 | * @param permissions Permission array. 140 | * @param grantResults: Permission application result array. 141 | */ 142 | override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { 143 | super.onRequestPermissionsResult(requestCode, permissions, grantResults) 144 | if (permissions == null || grantResults == null) { 145 | return 146 | } 147 | if (grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == GENERATE_CODE) { 148 | val intent = Intent(this, GenerateCodeActivity::class.java) 149 | this.startActivity(intent) 150 | } 151 | if (grantResults.size < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) { 152 | return 153 | } 154 | //Default View Mode 155 | if (requestCode == CAMERA_REQ_CODE) { 156 | ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, HmsScanAnalyzerOptions.Creator().create()) 157 | } 158 | //Customized View Mode 159 | if (requestCode == DEFINED_CODE) { 160 | val intent = Intent(this, DefinedActivity::class.java) 161 | this.startActivityForResult(intent, REQUEST_CODE_DEFINE) 162 | } 163 | //Bitmap Mode 164 | if (requestCode == BITMAP_CODE) { 165 | val intent = Intent(this, CommonActivity::class.java) 166 | intent.putExtra(DECODE_MODE, BITMAP_CODE) 167 | this.startActivityForResult(intent, REQUEST_CODE_SCAN_MULTI) 168 | } 169 | //Multiprocessor Synchronous Mode 170 | if (requestCode == MULTIPROCESSOR_SYN_CODE) { 171 | val intent = Intent(this, CommonActivity::class.java) 172 | intent.putExtra(DECODE_MODE, MULTIPROCESSOR_SYN_CODE) 173 | this.startActivityForResult(intent, REQUEST_CODE_SCAN_MULTI) 174 | } 175 | //Multiprocessor Asynchronous Mode 176 | if (requestCode == MULTIPROCESSOR_ASYN_CODE) { 177 | val intent = Intent(this, CommonActivity::class.java) 178 | intent.putExtra(DECODE_MODE, MULTIPROCESSOR_ASYN_CODE) 179 | this.startActivityForResult(intent, REQUEST_CODE_SCAN_MULTI) 180 | } 181 | } 182 | 183 | /** 184 | * Event for receiving the activity result. 185 | * 186 | * @param requestCode Request code. 187 | * @param resultCode Result code. 188 | * @param data Result. 189 | */ 190 | @RequiresApi(api = Build.VERSION_CODES.N) 191 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 192 | super.onActivityResult(requestCode, resultCode, data) 193 | if (resultCode != RESULT_OK || data == null) { 194 | return 195 | } 196 | //Default View 197 | if (requestCode == REQUEST_CODE_SCAN_ONE) { 198 | val obj: HmsScan = data.getParcelableExtra(ScanUtil.RESULT)!! 199 | if (obj != null) { 200 | val intent = Intent(this, DisPlayActivity::class.java) 201 | intent.putExtra(RESULT, obj) 202 | startActivity(intent) 203 | } 204 | //MultiProcessor & Bitmap 205 | } else if (requestCode == REQUEST_CODE_SCAN_MULTI) { 206 | val obj = data.getParcelableArrayExtra(SCAN_RESULT) 207 | if (obj != null && obj.size > 0) { 208 | //Get one result. 209 | if (obj.size == 1) { 210 | if (obj[0] != null && !TextUtils.isEmpty((obj[0] as HmsScan).getOriginalValue())) { 211 | val intent = Intent(this, DisPlayActivity::class.java) 212 | intent.putExtra(RESULT, obj[0]) 213 | startActivity(intent) 214 | } 215 | } else { 216 | val intent = Intent(this, DisPlayMulActivity::class.java) 217 | intent.putExtra(RESULT, obj) 218 | startActivity(intent) 219 | } 220 | } 221 | //Customized View 222 | } else if (requestCode == REQUEST_CODE_DEFINE) { 223 | val obj: HmsScan = data.getParcelableExtra(DefinedActivity.SCAN_RESULT)!! 224 | if (obj != null) { 225 | val intent = Intent(this, DisPlayActivity::class.java) 226 | intent.putExtra(RESULT, obj) 227 | startActivity(intent) 228 | } 229 | } 230 | } 231 | 232 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cloors.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/clors_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | "/> 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/clors_dis.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/contact.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/dialog_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/email.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/event.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/flashlight_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/flashlight_off.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/flashlight_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/flashlight_on.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/ic_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/isbn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/isbn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/location.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/photo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/product.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/product.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/scan_kit_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/scan_kit_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/sms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/sms.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/tel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/tel.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/text.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/website.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HMS-Core/hms-scan-demo/e1faccc9e91cfbceec94939d418cf7c5c6999b88/app/src/main/res/drawable/wifi.png -------------------------------------------------------------------------------- /app/src/main/res/layout-land/activity_mwcmain_landscape.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 21 | 22 | 32 | 33 | 43 | 44 | 54 | 55 | 56 | 61 |