More articles like this, visit HUAWEI Developer Forum and Medium.
About This Document
In the previous article, we have introduced the quick integration method of HMS Scan Kit and the competitiveness comparison between HMS Scan Kit and other open-source code scanning tools. If you do not find the method, you can click Previous Issue at the bottom of the article to find the method. We are now used to scanning the QR code to pay, scanning the QR code to follow social accounts, scanning the QR code to learn about product information, scanning the QR code to shop, and so on. Today, I'd like to introduce the development process of QR code purchase.
Scenario
The shopping app provides an entry for scanning the QR code of an offering. After the QR code is scanned, the offering information and purchase link are displayed, facilitating offering selection for customers.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Development Step
Open the project-level build.gradle file.
Choose allprojects > repositories and configure the Maven repository address of HMS SDK.
Code:
allprojects {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}
Configure the Maven repository address of HMS SDK in buildscript->repositories.
Code:
buildscript {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}
Adding Compilation Dependencies
Open the application levelbuild.gradle file.
SDK integration
Code:
dependencies{
implementation 'com.huawei.hms:scan:1.1.3.301'
}
Specifying Permissions and Features
Code:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
The QR code scanning page is declared in the AndroidManifest.xml file because the defaultview is used.
Code:
<activity android:name="com.huawei.hms.hmsscankit.ScanKitActivity" />
Scan to buy key Steps
There are two functions: adding products and querying products. You can scan the QR code and take a photo to bind a group of products. After saving the settings, you can scan the products.
Dynamic permission application
Code:
private static final int PERMISSION_REQUESTS = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
// Checking camera permission
if (!allPermissionsGranted()) {
getRuntimePermissions();
}
}
Page for adding a product
Click the add product button to trigger the offering adding page.
Code:
public void addProduct(View view) {
Intent intent = new Intent(MainActivity.this, AddProductActivity.class);
startActivityForResult(intent, REQUEST_ADD_PRODUCT);
}
Scan the barcode and enter the product barcode information.
Invoke the defaultview to scan the QR code.
Code:
private void scanBarcode(int requestCode) {
HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.ALL_SCAN_TYPE).create();
ScanUtil.startScan(this, requestCode, options);
}
Save the QR code scanning result in the callback function.
Code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null) {
return;
}
if ((requestCode == this.REQUEST_CODE_SCAN_ALL)
&& (resultCode == Activity.RESULT_OK)) {
HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT);
if (obj != null && obj.getOriginalValue() != null) {
this.barcode = obj.getOriginalValue();
}
} else if ((requestCode == this.REQUEST_TAKE_PHOTO)
&& (resultCode == Activity.RESULT_OK)) {
……
}
}
Searching for an Offering by Scanning the QR Code
The method of scanning the QR code is similar. You can directly perform the query on the home page and display the result in the callback function.
Code:
public void queryProduct(View view) {
HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.ALL_SCAN_TYPE).create();
ScanUtil.startScan(this, REQUEST_QUERY_PRODUCT, options);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null) {
return;
}
if ((requestCode == this.REQUEST_ADD_PRODUCT) && (resultCode == Activity.RESULT_OK)) {
barcodeToProduct.put(data.getStringExtra(Constant.BARCODE_VALUE), data.getStringExtra(Constant.IMAGE_PATH_VALUE));
} else if ((requestCode == this.REQUEST_QUERY_PRODUCT) && (resultCode == Activity.RESULT_OK)) {
HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT);
String path = "";
if (obj != null && obj.getOriginalValue() != null) {
path = barcodeToProduct.get(obj.getOriginalValue());
}
if (path != null && !path.equals("")) {
loadCameraImage(path);
showPictures();
}
}
}
Demo
Use the add product in the demo to enter the QR code information of the offering and take a photo. Then use the query product to scan the QR code of the offering. If the offering has been recorded in the system, the offering information is returned.
Any questions about the process, visit HUAWEI Developer Forum.
Related
More information like this, you can visit HUAWEI Developer Forum
Original link of this thread: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201320049432220250&fid=0101187876626530001
Huawei Map Kit, How to setup Huawei Map and add a marker? In JAVA
HUAWEI Map Kit is an SDK for map development. It covers map data of more than 200 countries and regions, and supports dozens of languages. With this SDK, you can easily integrate map-based functions into your apps.
In this article we will going to talk about How to setup Huawei Map and add a marker:
First you need to add Dependencies in root build.gradle:
Code:
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
}
}
Code:
buildscript {
repositories {
maven { url 'http://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.huawei.agconnect:agcp:1.2.0.300'
}
}
Then you need to add Dependencies in app build.gradle:
Code:
implementation 'com.huawei.hms:maps:5.0.1.300'
Make sure that you configure
Code:
apply plugin: 'com.huawei.agconnect'
after apply plugin: 'com.android.application'.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Also check on AppGallery Connect as picture below on Project Setting > Manage APIs. Map Kit switched on.
Also don’t forget on AppGallery Connect as picture below on Project Setting to add your SHA-256 certificate fingerprint for the project and download agconnect-services.json
Also don’t forget to add the permissions on AndroidManifest.xml
Code:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Remember that fingerprint for debugging is different than release so you need to use one for both so you can use this by this way. Add this code in app Gradle and change it to your keystore the released one.
Code:
android {
…
signingConfigs {
release {
storeFile file("../keystore/HMS_MY_TEST_KEYSTORE.jks") //keystore path
storePassword "@123456"
keyAlias "HMS_MY_TEST_KEYSTORE"
keyPassword "@123456"
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
…
}
and ofcourse don't forget to check permissions to let the user allow App to access user location from android 6.0
Code:
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
Log.i(TAG, "sdk > 23 M");
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] strings =
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
ActivityCompat.requestPermissions(this, strings, 882);
}
}
In you activity you need to handle the response by this way
Code:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults.length > 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION successful");
requestLocation();
} else {
Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSSION failed");
}
}
}
Now Let's start with a real work:
First you have to add MapView to the layout. \layout\activity_main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.huawei.hms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="51"
map:cameraTargetLng="10"
map:cameraZoom="8.5"
map:mapType="normal"
map:uiCompass="true"
map:uiZoomControls="true" />
</LinearLayout>
Now yon need to initialize MapView:
Code:
// get mapView by layout view
mMapView = findViewById(R.id.mapView);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
mMapView.onCreate(mapViewBundle);
// get map by async method
mMapView.getMapAsync(this);
Don't forget to integrate map with activity cycle:
Code:
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
Finally you have to create call back when map is ready
Code:
@Override
public void onMapReady(HuaweiMap huaweiMap) {
hmap = huaweiMap;
hmap.setMyLocationEnabled(true);
hmap.getUiSettings().setMyLocationButtonEnabled(true);
}
Inside it also you can add some settings and configrations for map.
Now we will talk about adding marker on map:
and it's so simple:
To add marker on map you can added by this way
Code:
public void addMarker() {
if (null != mMarker) {
mMarker.remove();
}
MarkerOptions options = new MarkerOptions()
.position(new LatLng(48.893478, 2.334595))
.title("Hello Huawei Map")
.snippet("This is a snippet!");
mMarker = hmap.addMarker(options);
}
and you can call this function from onMapReady.
Thanks a lot for reading.
Does Huawei map kit will support custom info window
Is there navigation system in HMS Map Kit?
More information like this, you can visit HUAWEI Developer Forum
Original link: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201334296322460044&fid=0101187876626530001
Introduction
Do you already know Image Kit? If you havent have the opportuniy to use it, Image Kit incorporates intelligent design and animation production functions in your App. Giving us the power of efficient image reproduction while providing image editing for our users.
For this example we will use the Image Render service. This service provides us with basic animation effects and nine advanced ones. In this example we will create an animated Splash Screen where we will apply the Waterfall effect. Without further ado let's see the steps to follow
Steps:
1. Download the Image Render Example code
2. Create an App in AGC
3. Connect our Android project with the App
4. Downloading the necessary repositories
5. Create our Splash Screen
6. Add the necessary assets manifest.xml for our animation
7. Obtain the instance
8. Initialize the Rendering service
9. Run the animation
10. After the execution we launch the Main Activity
Download the Image Render Example code
In order to implement this functionality we must download the source code provided by the developer Huawei, this is the link to the repository.
https://github.com/huaweicodelabs/ImageKit
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
You can git clone or download the zip to your computer. I recommend that you run the app. In my case there were some problems with my version of gradle. In case the same thing happens to you. What I did was download the Gradle version of my project, use the following one and you modify this in the gradle-wrapper.properties file
Code:
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
Run the app so that you know how the Image Render works.
Create an App in AGC
In order to use this service it will be necessary to have an App in AGC. I share a guide so that you can create an App and when creating an App and a project in AGC you will have the instructions to be able to add the necessary elements to your App.
https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#1
Connect our Android project with the App
To connect them we need to add the following lines
. Configure the Maven repository address and AppGallery Connect plug-in in the project's build.gradle file.
Go to allprojects> repositories and configure the Maven repository address for the HMS Core SDK
Code:
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
...
}
}
Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.
Code:
buildscript {
repositories {
maven {url 'https://developer.huawei.com/repo/'}
...
}
...
}
Go to buildscript > dependencies and add dependency configurations
Code:
Buildscript {
dependencies {
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}
}
Configure the dependency package in the app's build.gradle file.
Add a dependency package to the dependencies section in the build.gradle file.
Code:
dependencies {
...
implementation 'com.huawei.hms:image-render:1.0.2.302'
...
}
Downloading the necessary repositories
Configure the dependency package in the app's build.gradle file.
Add a dependency package to the dependencies section in the build.gradle file.
Code:
dependencies {
...
implementation 'com.huawei.hms:image-render:1.0.2.302'
...
}
Configure minSdkVersion
android {
...
defaultConfig {
...
minSdkVersion 26
...
}
...
}
Add the AppGallery Connect plug-in dependency to the file header.
Code:
apply plugin: 'com.huawei.agconnect'
Create our Splash Screen
Create our style
Code:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash_background</item>
</style>
Add our Activity to the manifest
Code:
<activity android:name="SplashActivity"
android:theme="@style/SplashTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"
/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
We also need to add these permissions
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Splash Activity
For the Splash we need to pause the main thread we declare a time in milliseconds
Code:
private final int DURACION_SPLASH = 8500;
private void onUIThread(){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
//SplashActivity.this.startActivity(intent);
}
},DURACION_SPLASH);
}
We get the instance
For this I have created a method we call initImageRender () and we call it from onCreate ()
Code:
private void initImageRender() {
// Obtain an ImageRender object.
ImageRender.getInstance(this, new ImageRender.RenderCallBack() {
@Override
public void onSuccess(ImageRenderImpl imageRender) {
Log.i(TAG, "getImageRenderAPI success");
imageRenderAPI = imageRender;
useImageRender();
}
@Override
public void onFailure(int i) {
Log.e(TAG, "getImageRenderAPI failure, errorCode = " + i);
}
});
}
Now we initialize the Service for this We will have to pass it the path of the file that we will use from splash
Code:
private void useImageRender() {
// Initialize the ImageRender object.
if (imageRenderAPI == null) {
Log.e(TAG, "initRemote fail, please check kit version");
return;
}
Log.d(TAG, sourcePath);
int initResult = imageRenderAPI.doInit(sourcePath, getAuthJson());
Log.i(TAG, "DoInit result == " + initResult);
if (initResult == 0) {
// Obtain the rendered view.
RenderView renderView = imageRenderAPI.getRenderView();
if (renderView.getResultCode() == ResultCode.SUCCEED) {
View view = renderView.getView();
if (null != view) {
// Add the rendered view to the layout.
contentView.addView(view);
int playResult = imageRenderAPI.playAnimation();
} else {
Log.w(TAG, "GetRenderView fail, view is null");
}
} else if (renderView.getResultCode() == ResultCode.ERROR_GET_RENDER_VIEW_FAILURE) {
Log.w(TAG, "GetRenderView fail");
} else if (renderView.getResultCode() == ResultCode.ERROR_XSD_CHECK_FAILURE) {
Log.w(TAG, "GetRenderView fail, resource file parameter error, please check resource file.");
} else if (renderView.getResultCode() == ResultCode.ERROR_VIEW_PARSE_FAILURE) {
Log.w(TAG, "GetRenderView fail, resource file parsing failed, please check resource file.");
} else if (renderView.getResultCode() == ResultCode.ERROR_REMOTE) {
Log.w(TAG, "GetRenderView fail, remote call failed, please check HMS service");
} else if (renderView.getResultCode() == ResultCode.ERROR_DOINIT) {
Log.w(TAG, "GetRenderView fail, init failed, please init again");
}
} else {
Log.w(TAG, "Do init fail, errorCode == " + initResult);
}
}
Add the necessary assets manifest.xml for our animation
We need to add to our folder assets manifest.xml file which is the animation.
Obtain the instance
Now we have to get the instance of the ImageRender
Code:
private void initImageRender() {
// Obtain an ImageRender object.
ImageRender.getInstance(this, new ImageRender.RenderCallBack() {
@Override
public void onSuccess(ImageRenderImpl imageRender) {
Log.i(TAG, "getImageRenderAPI success");
imageRenderAPI = imageRender;
useImageRender();
}
@Override
public void onFailure(int i) {
Log.e(TAG, "getImageRenderAPI failure, errorCode = " + i);
}
});
}
If everithing goes well we should get printed in the console the following message
Code:
getImageRenderAPI success
Initialize the Rendering service
Once that the instance has been initialized we can init the service by executing the doInit() method
Code:
Log.d(TAG, sourcePath);
int initResult = imageRenderAPI.doInit(sourcePath, getAuthJson());
Log.i(TAG, "DoInit result == " + initResult);
if (initResult == 0) {
// Obtain the rendered view.
RenderView renderView = imageRenderAPI.getRenderView();
if (renderView.getResultCode() == ResultCode.SUCCEED) {
View view = renderView.getView();
if (null != view) {
// Add the rendered view to the layout.
contentView.addView(view);
int playResult = imageRenderAPI.playAnimation();
} else {
Log.w(TAG, "GetRenderView fail, view is null");
}
} else if (renderView.getResultCode() == ResultCode.ERROR_GET_RENDER_VIEW_FAILURE) {
Log.w(TAG, "GetRenderView fail");
} else if (renderView.getResultCode() == ResultCode.ERROR_XSD_CHECK_FAILURE) {
Log.w(TAG, "GetRenderView fail, resource file parameter error, please check resource file.");
} else if (renderView.getResultCode() == ResultCode.ERROR_VIEW_PARSE_FAILURE) {
Log.w(TAG, "GetRenderView fail, resource file parsing failed, please check resource file.");
} else if (renderView.getResultCode() == ResultCode.ERROR_REMOTE) {
Log.w(TAG, "GetRenderView fail, remote call failed, please check HMS service");
} else if (renderView.getResultCode() == ResultCode.ERROR_DOINIT) {
Log.w(TAG, "GetRenderView fail, init failed, please init again");
}
} else {
Log.w(TAG, "Do init fail, errorCode == " + initResult);
}
Run the animation
Once that we have initialized and init the Image Render is time to play the animation
So Now we have to add a View to our Activity and play the animation
Code:
if (null != imageRenderAPI) {
int playResult = imageRenderAPI.playAnimation();
if (playResult == ResultCode.SUCCEED) {
Log.i(TAG, "Start animation success");
} else {
Log.i(TAG, "Start animation failure");
}
} else {
Log.w(TAG, "Start animation fail, please init first.");
}
Conclusion
With this little example we haver started with the implementation of Image Kit in one project. For further information here you have docs.
https://developer.huawei.com/consumer/en/hms/huawei-imagekit/
Can we do like gif animation using Image kit?
Introduction
In this article, we will learn how to implement Huawei HiAI kit using Text Recognition service into android application, this service helps us to extract the data from screen shots and photos.
Now a days everybody lazy to type the content, there are many reasons why we want to integrate this service into our apps. User can capture or pic image from gallery to retrieve the text, so that user can edit the content easily.
UseCase: Using this HiAI kit, user can extract the unreadble image content to make useful, let's start.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Any IDE with Android SDK installed (IntelliJ, Android Studio).
3. HiAI SDK.
4. Minimum API Level 23 is required.
5. Required EMUI 9.0.0 and later version devices.
6. Required process kirin 990/985/980/970/ 825Full/820Full/810Full/ 720Full/710Full
How to integrate HMS Dependencies
1. First of all, we need to create an app on AppGallery Connect and add related details about HMS Core to our project. For more information check this link
2. Download agconnect-services.json file from AGC and add into app’s root directory.
3 Add the required dependencies to the build.gradle file under root folder.
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
4. Add the App level dependencies to the build.gradle file under app folder.
Code:
apply plugin: 'com.huawei.agconnect'
5. Add the required permission to the Manifestfile.xml file.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.HARDWARE_TEST.camera.autofocus"/>
6. Now, sync your project.
How to apply for HiAI Engine Library
1. Navigate to this URL, choose App Service > Development and click HUAWEI HiAI.
2. Click Apply for HUAWEI HiAI kit.
3. Enter required information like product name and Package name, click Next button.
4. Verify the application details and click Submit button.
5. Click the Download SDK button to open the SDK list.
6. Unzip downloaded SDK and add into your android project under lib folder.
7. Add jar files dependences into app build.gradle file.
Code:
implementationfileTree(<b><span style="font-size: 10.0pt;font-family: Consolas;">include</span></b>: [<b><span style="font-size: 10.0pt;">'*.aar'</span></b>, <b><span style="font-size: 10.0pt;">'*.jar'</span></b>], <b><span style="font-size: 10.0pt;">dir</span></b>: <b><span style="font-size: 10.0pt;">'libs'</span></b>)
implementation <b><span style="font-size: 10.0pt;font-family: Consolas;">'com.google.code.gson:gson:2.8.6'
</span></b>repositories <b>{
</b>flatDir <b>{
</b>dirs <b><span style="font-size: 10.0pt;line-height: 115.0%;font-family: Consolas;color: green;">'libs'
}
}</span></b><b><span style="font-size: 10.0pt;font-family: Consolas;">
</span></b>
8. After completing this above setup, now Sync your gradle file.
Let’s do code
I have created a project on Android studio with empty activity let’s start coding.
In the MainActivity.java we can create the business logic.
Java:
public class MainActivity extends AppCompatActivity {
private boolean isConnection = false;
private int REQUEST_CODE = 101;
private int REQUEST_PHOTO = 100;
private Bitmap bitmap;
private Bitmap resultBitmap;
private Button btnImage;
private ImageView originalImage;
private ImageView conversionImage;
private TextView textView;
private TextView contentText;
private final String[] permission = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE};
private ImageSuperResolution resolution;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions(permission, REQUEST_CODE);
initHiAI();
originalImage = findViewById(R.id.super_origin);
conversionImage = findViewById(R.id.super_image);
textView = findViewById(R.id.text);
contentText = findViewById(R.id.content_text);
btnImage = findViewById(R.id.btn_album);
btnImage.setOnClickListener(v -> {
selectImage();
});
}
private void initHiAI() {
VisionBase.init(this, new ConnectionCallback() {
@Override
public void onServiceConnect() {
isConnection = true;
DeviceCompatibility();
}
@Override
public void onServiceDisconnect() {
}
});
}
private void DeviceCompatibility() {
resolution = new ImageSuperResolution(this);
int support = resolution.getAvailability();
if (support == 0) {
Toast.makeText(this, "Device supports HiAI Image super resolution service", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Device doesn't supports HiAI Image super resolution service", Toast.LENGTH_SHORT).show();
}
}
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (data != null && requestCode == REQUEST_PHOTO) {
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
setBitmap();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void setBitmap() {
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (width <= 1440 && height <= 15210) {
originalImage.setImageBitmap(bitmap);
setTextHiAI();
} else {
Toast.makeText(this, "Image size should be below 1440*15210 pixels", Toast.LENGTH_SHORT).show();
}
}
private void setTextHiAI() {
textView.setText("Extraction Text");
contentText.setVisibility(View.VISIBLE);
TextDetector detector = new TextDetector(this);
VisionImage image = VisionImage.fromBitmap(bitmap);
TextConfiguration config = new TextConfiguration();
config.setEngineType(TextConfiguration.AUTO);
config.setEngineType(TextDetectType.TYPE_TEXT_DETECT_FOCUS_SHOOT_EF);
detector.setTextConfiguration(config);
Text result = new Text();
int statusCode = detector.detect(image, result, null);
if (statusCode != 0) {
Log.e("TAG", "Failed to start engine, try restart app,");
}
if (result.getValue() != null) {
contentText.setText(result.getValue());
Log.d("TAG", result.getValue());
} else {
Log.e("TAG", "Result test value is null!");
}
}
}
Demo
Tips and Tricks
1. Download latest Huawei HiAI SDK.
2. Set minSDK version to 23 or later.
3. Do not forget to add jar files into gradle file.
4. Screenshots size should be 1440*15210 pixels.
5. Photos recommended size is 720p.
6. Refer this URL for supported Countries/Regions list.
Conclusion
In this article, we have learned how to implement HiAI Text Recognition service in android application to extract the content from screen shots and photos.
Thanks for reading! If you enjoyed this story, please click the Like button and Follow. Feel free to leave a Comment below.
Reference
Huawei HiAI Kit URL
Original Source
Let's be honest: We can't function without the Internet. No matter where we go, we're always looking for ways to hook up the net.
Although more and more public places are offering free Wi-Fi networks, connecting to them remains a tiresome process. Many free Wi-Fi networks require users to register on a web page, click on an ad, or download a certain app, before granting Internet access.
As a developer, I have been scratching my head over an easier way for connecting to Wi-Fi networks. And then I came across the barcode-scanning feature of Scan Kit, which allows business owner to create a QR code that customers can scan with their phones to quickly connect to a Wi-Fi network. What's more, customers can even share the QR code with people around them. This speeds up the Wi-Fi connection process with customers' personal data properly protected.
Technical PrinciplesThe barcode-scanning Wi-Fi connection solution requires only two capabilities: barcode generation and barcode scanning.
Using the codeBuilding Scanning Capabilities1. Configure the Huawei Maven repository address.
Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK. Repeat this step for allprojects > repositories.
Java:
buildscript {
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
}
allprojects {
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
}
In Gradle 7.0 or later, configuration under allprojects > repositories is migrated to the project-level settings.gradle file. The following is a configuration example of the settings.gradle file:
Java:
dependencyResolutionManagement {
...
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
2. Add build dependencies
Java:
dependencies{
// Scan SDK.
implementation 'com.huawei.hms:scan:2.3.0.300'
}
3. Configure obfuscation scripts
Open the obfuscation configuration file proguard-rules.pro in the app's root directory of the project, and add configurations to exclude the HMS Core SDK from obfuscation.
Java:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
4. Add permissions to the AndroidManifest.xml file
Java:
<!-- Camera permission -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- File read permission -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
5. Dynamically request the permissions
Java:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode);
6. Check the permission request result
Java:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (permissions == null || grantResults == null) {
return;
}
// The permissions are successfully requested or have been assigned.
if (requestCode == CAMERA_REQ_CODE) {
// Scan barcodes in Default View mode.
// Parameter description:
// activity: activity that requests barcode scanning.
// requestCode: request code, which is used to check whether the scanning result is obtained from Scan Kit.
ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, new HmsScanAnalyzerOptions.Creator().create());
}
}
7. Receive the barcode scanning result through the callback API, regardless of whether it is captured by the camera or from an image
Java:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK || data == null) {
return;
}
if (requestCode == REQUEST_CODE_SCAN_ONE) {
// Input an image for scanning and return the result.
HmsScan hmsScan = data.getParcelableExtra(ScanUtil.RESULT);
if (hmsScan != null) {
// Show the barcode parsing result.
showResult(hmsCan);
}
}
}
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
QR Code Scanner Demo
Building the Barcode Generation Function1. Repeat the first three steps for building scanning capabilities
2. Declare the necessary permission in the AndroidManifest.xml file
Java:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3. Dynamically request the permission
Java:
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
4. Check the permission request result
Java:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (permissions == null || grantResults == null) {
return;
}
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == GENERATE_CODE) {
Intent intent = new Intent(this, GenerateCodeActivity.class);
this.startActivity(intent);
}
}
5. Generate a QR code
Java:
public void generateCodeBtnClick(View v) {
try {
HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator()
.setBitmapMargin(margin)
.setBitmapColor(color)
.setBitmapBackgroundColor(background)
.create();
resultImage = ScanUtil.buildBitmap(content, type, width, height, options);
barcodeImage.setImageBitmap(resultImage);
} catch (WriterException e) {
Toast.makeText(this, "Parameter Error!", Toast.LENGTH_SHORT).show();
}
}
6. Save the QR code
INI:
public void saveCodeBtnClick(View v) {
if (resultImage == null) {
Toast.makeText(GenerateCodeActivity.this, "Please generate barcode first!", Toast.LENGTH_LONG).show();
return;
}
try {
String fileName = System.currentTimeMillis() + ".jpg";
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath();
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
File file = new File(appDir, fileName);
FileOutputStream fileOutputStream = new FileOutputStream(file);
boolean isSuccess = resultImage.compress(Bitmap.CompressFormat.JPEG, 70, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
Uri uri = Uri.fromFile(file);
GenerateCodeActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
if (isSuccess) {
Toast.makeText(GenerateCodeActivity.this, "Barcode has been saved locally", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(GenerateCodeActivity.this, "Barcode save failed", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(GenerateCodeActivity.this, "Unknown Error", Toast.LENGTH_SHORT).show();
}
}
QR Code generator Demo
Wi-Fi QR code demoWi-Fi QR Code Demo is a test program showing how to generate QR Code that contains Wi-Fi information and scan the QR Code for connecting to Wi-Fi networks.
Click "Default View Mode" button to open the QR Code Scanner
Click "Connect to network" to join
Type in Wifi Name and Wifi Password
Type in Barcode width and height
Click "Generate Barcode" button to get a new QR Code
Click "Save Barcode" button to save the QR Code as an image file.
References>> HMS Core Scan Kit
>> HMS Core
>> Reddit for discussion with other developers
>> GitHub for demos and sample codes
>> Stack Overflow for solutions to integration issues
Filling in addresses is a task that users of lifestyle apps and mini programs that provide services such as group buying, takeout, package delivery, housekeeping, logistics, and moving services often have to perform. Generally, this requires users to manually fill in their address information, for example, selecting California, Los Angeles, and Hollywood Blvd in sequence using several drop-down list boxes and then manually entering their names and phone numbers. This process usually takes some time and is prone to input error.
Wouldn't it be handy if there was an automatic way for users to fill in addresses quickly and accurately? With HMS Core Location Kit's fused location and geocoding capabilities, a lifestyle app can automatically pinpoint the current location of a user or obtain the street address of a map location, and fill that information in the address box. Thanks to this, users are freed from the hassle of having to manually enter addresses, as well preventing human error. In this article, I will explain how you can easily integrate this feature into your app and provide you with sample code.
Demo
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Development ProcedurePrepare for the development1. Sign in to AppGallery Connect and click My projects. Find your project, go to Project settings > Manage APIs, and toggle on the Location Kit switch. Then, click the app for which you need to configure the signing certificate fingerprint, and go to Project settings > General information. In the App information area, click Add next to SHA-256 certificate fingerprint, and enter the SHA-256 certificate fingerprint.
2. Go to Project settings > General information. In the App information area, click agconnect-services.json to download the configuration file. Then, copy the configuration file to the app's root directory.
3. Configure the project-level build.gradle file.
Java:
buildscript {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
}
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
mavenCentral()
}
}
Configure the app-level build.gradle file.
Java:
plugins {
id 'com.android.application'
id 'com.huawei.agconnect'
}
Add the following build dependency in the dependencies block in the app-level build.gradle file:
Java:
implementation 'com.huawei.hms:location:6.3.0.300'
Check permissions1. Declare the ACCESS_COARSE_LOCATION (approximate location permission), ACCESS_FINE_LOCATION (precise location permission), and ACCESS_BACKGROUND_LOCATION permissions in the AndroidManifest.xml file.
Java:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
2. Dynamically apply for related location permissions (according to requirements for dangerous permissions in Android 6.0 or later).
Java:
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
Log.i(TAG, "android sdk < 28 Q");
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] strings =
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
ActivityCompat.requestPermissions(this, strings, 1);
}
} else {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
"android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
String[] strings = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
"android.permission.ACCESS_BACKGROUND_LOCATION"};
ActivityCompat.requestPermissions(this, strings, 2);
}
}
Obtain the location result1. Set location parameters, including the location update interval and location type
Java:
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationRequest = new LocationRequest();
// Set the location update interval, in milliseconds.
mLocationRequest.setInterval(5000);
// Set the priority.
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
2. Call the getSettingsClient() method to obtain a SettingsClient instance, and call checkLocationSettings() to check the device location settings.
Java:
LocationSettingsRequest locationSettingsRequest = builder.build();
// Before requesting location updates, call checkLocationSettings to check the device location settings.
Task<LocationSettingsResponse> locationSettingsResponseTask =
mSettingsClient.checkLocationSettings(locationSettingsRequest);
After checking that the device location function is enabled, call requestLocationUpdates() to request location updates.
Java:
locationSettingsResponseTask.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "check location settings success");
mFusedLocationProviderClient
.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.i(TAG, "requestLocationUpdatesWithCallback onSuccess");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.e(TAG, "requestLocationUpdatesWithCallback onFailure:" + e.getMessage());
}
});
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.e(TAG, "checkLocationSetting onFailure:" + e.getMessage());
int statusCode = 0;
if (e instanceof ApiException) {
statusCode = ((ApiException) e).getStatusCode();
}
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
// When startResolutionForResult is called, a popup will
// appear, asking the user to grant relevant permissions.
if (e instanceof ResolvableApiException) {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(MainActivity.this, 0);
}
} catch (IntentSender.SendIntentException sie) {
Log.e(TAG, "PendingIntent unable to execute request.");
}
break;
default:
break;
}
}
});
Obtain the address of the current location through reverse geocodingAfter obtaining the longitude and latitude of a location, pass them to the geocoding service (GeocoderService) to obtain a geocoding request object. Then, call the getFromLocation method and set request (GetFromLocationRequest) parameters to obtain the address of the location.
Java:
if (null == mLocationCallback) {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult != null) {
List<Location> locations = locationResult.getLocations();
if (!locations.isEmpty()) {
ExecutorUtil.getInstance().execute(new Runnable() {
@Override
public void run() {
Locale locale = new Locale("zh", "CN");
GeocoderService geocoderService = LocationServices.getGeocoderService(MainActivity.this, locale);
GetFromLocationRequest getFromLocationRequest = new GetFromLocationRequest(locations.get(0).getLatitude(), locations.get(0).getLongitude(), 1);
geocoderService.getFromLocation(getFromLocationRequest)
.addOnSuccessListener(new OnSuccessListener<List<HWLocation>>() {
@Override
public void onSuccess(List<HWLocation> hwLocation) {
printGeocoderResult(hwLocation);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.i(TAG, e.getMessage());
}
});
}
});
}
}
}
@Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
if (locationAvailability != null) {
boolean flag = locationAvailability.isLocationAvailable();
Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag);
}
}
};
}
Finally, display the obtained address on the screen to complete the implementation.
References>> Location Kit official website
>> Location Kit Development Guide
>> Reddit to join developer discussions
>> GitHub to download the sample code
>> Stack Overflow to solve integration problems