Communicating Between JavaScript and Java Through the Cordova Plugins - Huawei Developers

Background​Cordova is an open-source cross-platform development framework that allows you to use HTML and JavaScript to develop apps across multiple platforms, such as Android and iOS. So how exactly does Cordova enable apps to run on different platforms and implement the functions? The abundant plugins in Cordova are the main reason, and free you to focus solely on app functions, without having to interact with the APIs at the OS level. HMS Core provides a set of Cordova-related plugins, which enable you to integrate kits with greater ease and efficiency.
Introduction​Here, I'll use the Cordova plugin in HUAWEI Push Kit as an example to demonstrate how to call Java APIs in JavaScript through JavaScript-Java messaging. The following implementation principles can be applied to all other kits, except for Map Kit and Ads Kit (which will be detailed later), and help you master troubleshooting solutions.
Basic Structure of Cordova​When you call style='mso-bidi-font-weight:normal'>loadUrl in MainActivity, CordovaWebView will be initialized and Cordova starts up. In this case, style='mso-bidi-font-weight:normal'>CordovaWebView will create style='mso-bidi-font-weight:normal'>PluginManager, NativeToJsMessageQueue, as well as ExposedJsApi of JavascriptInterface. style='mso-bidi-font-weight:normal'>ExposedJsApi and NativeToJsMessageQueue will play a role in the subsequent communication.
During the plugin loading, all plugins in the configuration file will be read when the PluginManager object is created, and plugin mappings will be created. When the plugin is called for the first time, instantiation is conducted and related functions are executed.
A message can be returned from Java to JavaScript in synchronous or asynchronous mode. In Cordova, set async in the method to distinguish the two modes.
In synchronous mode, Cordova obtains data from the header of the NativeToJsMessageQueue queue, finds the message request based on callbackID, and returns the data to the success method of the request.
In asynchronous mode, Cordova calls the loop method to continuously obtain data from the NativeToJsMessageQueue queue, finds the message request, and returns the data to the success method of the request.
In the Cordova plugin of Push Kit, the synchronization mode is used.
Plugin Call
You may still be unclear on how the process works, based on the description above, so I've provided the following procedure:
1. Install the plugin.​Run the cordova plugin add @hmscore/cordova-plugin-hms-push command to install the latest plugin. After the command is executed, the plugin information is added to the plugins directory.
{
"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"
}
The plugin.xml file records all information to be used, such as JavaScript and Android classes. During the plugin initialization, the classes will be loaded to Cordova. If a method or API is not configured in the file, it is unable to be used.
2. Create a message mapping.​The plugin provides the methods for creating mappings for the following messages:
(1) HmsMessaging
In the HmsPush.js file, call the runHmsMessaging API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsPushMessaging class. The execute method in HmsPushMessaging can transfer the message to a method for processing based on the action type in the message.
Code:
public void execute(String action, final JSONArray args, final CallbackContext callbackContext)
throws JSONException {
hmsLogger.startMethodExecutionTimer(action);
switch (action) {
case "isAutoInitEnabled":
isAutoInitEnabled(callbackContext);
break;
case "setAutoInitEnabled":
setAutoInitEnabled(args.getBoolean(1), callbackContext);
break;
case "turnOffPush":
turnOffPush(callbackContext);
break;
case "turnOnPush":
turnOnPush(callbackContext);
break;
case "subscribe":
subscribe(args.getString(1), callbackContext);
break;
(2) HmsInstanceId
In the HmsPush.js file, call the runHmsInstance API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsPushInstanceId class. The execute method in HmsPushInstanceId can transfer the message to a method for processing based on the action type in the message.
Code:
public void execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
if (!action.equals("init"))
hmsLogger.startMethodExecutionTimer(action);
switch (action) {
case "init":
Log.i("HMSPush", "HMSPush initialized ");
break;
case "enableLogger":
enableLogger(callbackContext);
break;
case "disableLogger":
disableLogger(callbackContext);
break;
case "getToken":
getToken(args.length() > 1 ? args.getString(1) : Core.HCM, callbackContext);
break;
case "getAAID":
getAAID(callbackContext);
break;
case "getCreationTime":
getCreationTime(callbackContext);
break;
Similarly, the processing method returns the result to JavaScript. The result will be written to the nativeToJsMessageQueue queue.
Code:
callBack.sendPluginResult(new PluginResult(PluginResult.Status.OK,autoInit));
(3) localNotification
In the HmsLocalNotification.js file, call the run API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsLocalNotification class. The execute method in HmsLocalNotification can transfer the message to a method for processing based on the action type in the message.
Code:
public void execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
switch (action) {
case "localNotification":
localNotification(args, callbackContext);
break;
case "localNotificationSchedule":
localNotificationSchedule(args.getJSONObject(1), callbackContext);
break;
case "cancelAllNotifications":
cancelAllNotifications(callbackContext);
break;
case "cancelNotifications":
cancelNotifications(callbackContext);
break;
case "cancelScheduledNotifications":
cancelScheduledNotifications(callbackContext);
break;
case "cancelNotificationsWithId":
cancelNotificationsWithId(args.getJSONArray(1), callbackContext);
break;
Call sendPluginResult to return the result. However, for localNotification, the result will be returned after the notification is sent.
3. Perform message push event callback.​In addition to the method calling, message push involves listening for many events, for example, receiving common messages, data messages, and tokens.
The callback process starts from Android.
In Android, the callback method is defined in HmsPushMessageService.java.
Based on the SDK requirements, you can opt to redefine certain callback methods, such as onMessageReceived, onDeletedMessages, and onNewToken.
When an event is triggered, an event notification is sent to JavaScript.
Code:
public static void runJS(final CordovaPlugin plugin, final String jsCode) {
if (plugin == null)
return;
Log.d(TAG, "runJS()");
plugin.cordova.getActivity().runOnUiThread(() -> {
CordovaWebViewEngine engine = plugin.webView.getEngine();
if (engine == null) {
plugin.webView.loadUrl("javascript:" + jsCode);
} else {
engine.evaluateJavascript(jsCode, (result) -> {
});
}
});
}
Each event is defined and registered in HmsPushEvent.js.
Code:
exports.REMOTE_DATA_MESSAGE_RECEIVED = "REMOTE_DATA_MESSAGE_RECEIVED";
exports.TOKEN_RECEIVED_EVENT = "TOKEN_RECEIVED_EVENT";
exports.ON_TOKEN_ERROR_EVENT = "ON_TOKEN_ERROR_EVENT";
exports.NOTIFICATION_OPENED_EVENT = "NOTIFICATION_OPENED_EVENT";
exports.LOCAL_NOTIFICATION_ACTION_EVENT = "LOCAL_NOTIFICATION_ACTION_EVENT";
exports.ON_PUSH_MESSAGE_SENT = "ON_PUSH_MESSAGE_SENT";
exports.ON_PUSH_MESSAGE_SENT_ERROR = "ON_PUSH_MESSAGE_SENT_ERROR";
exports.ON_PUSH_MESSAGE_SENT_DELIVERED = "ON_PUSH_MESSAGE_SENT_DELIVERED";
Code:
function onPushMessageSentDelivered(result) {
window.registerHMSEvent(exports.ON_PUSH_MESSAGE_SENT_DELIVERED, result);
}
exports.onPushMessageSentDelivered = onPushMessageSentDelivered;
Please note that the event initialization needs to be performed during app development. Otherwise, the event listening will fail. For more details, please refer to eventListeners.js in the demo. If the callback has been triggered in Java, but is not received in JavaScript, check whether the event initialization is performed. In doing so, when an event is triggered in Android, JavaScript will be able to receive and process the message. You can also refer to this process to add an event.
Summary​The description above illustrates how the plugin implements the JavaScript-Java communications. The methods of most kits can be called in a similar manner. However, Map Kit, Ads Kit, and other kits that need to display images or videos (such as maps and native ads) require a different method, which will be introduced in a later article.
References​For more details, you can go to:
HMS Core official website
HMS Core Cordova Plugin Development Documentation page, to find the documents you need
Reddit to join our developer discussion
GitHub to download Cordova Plugins
Stack Overflow to solve any integration problems

Thanks for sharing

Related

Recipe To Integrate In-App Messaging In 10 Minutes

This article is originally from HUAWEI Developer Forum
Forum link: https://forums.developer.huawei.com/forumPortal/en/home
{
"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"
}
HMS In-App Messaging is a tool to send relevant messages to target users actively using our app to encourage them to use key app functions. For example, we can send in-app messages to encourage users to subscribe to certain products, provide tips on passing a game level, or recommend activities of a restaurant.
In-App Messaging also allow us to customize our messages, the way it will be sent and also define events for triggering message sending to our users at the right moment.
Today I am going to server you a recipe to integrate In-App Messaging in your apps within 10 minutes.
Key Ingredients Needed
· 1 Android App Project, which supports Android 4.2 and later version.
· 1 SHA Key
· 1 Huawei Developer Account
· 1 Huawei phone with HMS 4.0.0.300 or later
Preparation Needed
· First we need to create an app or project in the Huawei app gallery connect.
· Provide the SHA Key and App Package name of the android project in App Information Section.
· Provide storage location in convention section under project setting.
· Enable App Messaging setting in Manage APIs section.
· After completing all the above points we need to download the agconnect-services.json from App Information Section. Copy and paste the json file in the app folder of the android project.
· Copy and paste the below maven url inside the repositories of buildscript and allprojects respectively (project build.gradle file)
Code:
maven { url 'http://developer.huawei.com/repo/' }
· Copy and paste the below class path inside the dependency section of project build.gradle file.
Code:
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
· Copy and paste the below plugin in the app build.gradle file
Code:
apply plugin: 'com.huawei.agconnect'
· Copy and paste below library in the app build.gradle file dependencies section
Code:
implementation 'com.huawei.agconnect:agconnect-appmessaging:1.3.1.300'
· Put the below permission in AndroidManifest file.
  a) android.permission.INTERNET
  b) android.permission.ACCESS_NETWORK_STATE
· Now Sync the gradle.
Android Code
1. First we need AAID for later use in sending In-App Messages. To obtain AAID, we will use getAAID() method.
2. Add following code in your project to obtain AAID:
Code:
HmsInstanceId inst = HmsInstanceId.getInstance(this);
Task<AAIDResult> idResult = inst.getAAID();
idResult.addOnSuccessListener(new OnSuccessListener<AAIDResult>() {
@Override
public void onSuccess(AAIDResult aaidResult) {
String aaid = aaidResult.getId();
Log.d(TAG, "getAAID success:" + aaid );
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.d(TAG, "getAAID failure:" + e);
}
});
3. To initialize the AGConnectAppMessaging instance we will use.
Code:
AGConnectAppMessaging appMessaging = AGConnectAppMessaging.getInstance();
4. To allow data synchronization from the AppGallery Connect server we will use.
Code:
appMessaging.setFetchMessageEnable(true);
5. To enable message display.
Code:
appMessaging.setDisplayEnable(true);
6. To specify that the in-app message data must be obtained from the AppGallery Connect server by force we will use.
Code:
appMessaging.setForceFetch();
Since we are using a test device to demonstrate the use of In-App Messaging, so we use setForceFetch API. The setForceFetch API can be used only for message testing. Also In-app messages can only be displayed to users who have installed our officially released app version.
Till now we added libraries, wrote the code in android studio using java etc. in the heated pan and the result will look like this:
Code:
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
private AGConnectAppMessaging appMessaging;
private HiAnalyticsInstance instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HmsInstanceId inst = HmsInstanceId.getInstance(this);
Task<AAIDResult> idResult = inst.getAAID();
idResult.addOnSuccessListener(new OnSuccessListener<AAIDResult>() {
@Override
public void onSuccess(AAIDResult aaidResult) {
String aaid = aaidResult.getId();
Log.d(TAG, "getAAID success:" + aaid );
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.d(TAG, "getAAID failure:" + e);
}
});
HiAnalyticsTools.enableLog();
instance = HiAnalytics.getInstance(this);
instance.setAnalyticsEnabled(true);
instance.regHmsSvcEvent();
inAppMessaging();
}
private void inAppMessaging() {
appMessaging = AGConnectAppMessaging.getInstance();
appMessaging.setFetchMessageEnable(true);
appMessaging.setDisplayEnable(true);
appMessaging.setForceFetch();
}
}
App Gallery Connect
Before we start using one of our key ingredients i.e. Huawei App Gallery Connect using Huawei Developer Account to serve In-App Messages, I would like to inform you that we can server the main dish into three different flavour or types:
A. Pop-up Message Flavour
B. Banner Message Flavour
C. An Image Message Flavour
In-App Message Using Pop-up Flavour
Let’s serve the main dish using Pop-up Message Flavour.
Step 1: Go to Huawei App Gallery Connect
Step 2: Select My projects.
Step 3: After selecting my projects, select the project which we have create earlier. It will look like this:
Step 4: After selecting the project, we will select App Messaging from the menu. It will look like this:
Step 5: Select New button to create new In-App Message to send to the device.
Step 6: Provide the Name and Description. It will look like this:
Step 7: In the Set style and content section, we have to select the type (which is Pop-up), provide a title, a message body, and choose colour for title text, body text and the background of the message. It will look like this:
Step 8: After providing the details in set style and content section, we will move on to the Image section. We will provide two image here for portrait and landscape mode of the app. Remember for portrait the image aspect ratio should be 3:2 (300x200) and for landscape the image aspect ratio should be either 1:1 (100x100) or 3:2 (300x200). It will look like this:
https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200512212645.95630192255042904397797509198276:50510525101557:2800:FA1CFD7E5EA43100725399BB4787A4B9FB44B8E02776FF83D09816D732E0AA63.png​
Step 9: We can also provide a button in the Pop-up message using Button Section. The button contains an action. This Action contains two option. We can provide user with Disable Message action or redirect user to particular URL. The section will look like this:
Step 10: We will now move to the next section i.e Select Sending Target section. Here we can click New condition to add a condition for matching target users. Condition types include app version, OS version, language, country/region, audience, user attributes, last interaction, and initial startup.
Note: In this article, we didn’t used any condition. But you are free to use any condition to send targeted In-App Messages.
The section will look like this:
Step 11: The next section is the Set Sending Time section.
a) We can schedule a date and time to send message.
b) We can also provide an End date and time to stop sending message.
c) We can also display message on an events by using trigger event functionality. For example, we can display a discount of an item in a shopping app. A trigger event is required for each in-app message.
d) Also we can flexibly set the frequency for displaying the message.
This is how it will look:
Step 12: The last section is the Set Conversion Event section. As off now we will keep it as none. It will look like this:
Step 13: Click Save in the upper right corner to complete message creation. Also we can click Preview to preview the display effect of your message on a mobile phone or tablet.
Note: Do not hit the publish button yet. Just save it.
Step 14: In-app messages can only be displayed to users who have installed our officially released app version. App Messaging allows us to test an in-app message when our app is still under tests. To that we need to find the message that you need to test, and click Test in the Operation column as it is shown below:
Step 15: Click Add test user and enter the AAID of the test device in the text box. Also run the app in order to find AAID of the test device in the logcat of the Android Studio.
Step 16: Finally we will publish the message. We will select publish in the operation column. It will look like this:
The Dish

Implementing Message Push for Your Quick App Rapidly

Now you have a quick app released on HUAWEI AppGallery. Do you want to attract more users and win more traffic for it? HUAWEI Push Kit can help you with that. You can push messages at the right moment to users for them to open your quick app to view more details. This better engages your users and improves activity.
Typical scenarios of push messages are as follows:
l Shopping quick apps can push information about new products and discounts to users to attract more customers for merchants.
l Reading quick apps can push information such as popular books and chapter updates to users, providing up-to-date information that users concern about.
l Food & drink quick apps can push information about food and good restaurants to users, facilitating user's life and bringing more users for the catering industry.
Follow instructions in this document to integrate HUAWEI Push Kit to your quick app to get all these benefits.
Getting Started
The hardware requirements are as follows:
l A computer with Node.js 10 or later and HUAWEI Quick App IDE of the latest version installed
l A Huawei mobile phone running EMUI 8.0 or later (with a USB cable)
Development Guide
Enabling HUAWEI Push Kit
1. Sign in to AppGallery Connect and click My projects.
2. Click the card of the project for which you need to enable the service. Click the Manage APIs tab, and toggle the Push Kit switch.
{
"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"
}
3. Click the General information tab. In the App information area, set SHA-256 certificate fingerprint to the SHA-256 fingerprint.
Subscribing to Push Messages
The service process is as follows.
1. Call the push.getProvider API to check whether the current device supports HUAWEI Push Kit. If huawei is returned, the device supports HUAWEI Push Kit. You can call other relevant APIs only when the device supports HUAWEI Push Kit.
2. Call the push.subscribe API to obtain regId (registered ID). The ID is also called a token or push token, which identifies messages sent by HUAWEI Push Kit.
Notice: It is recommended that the preceding APIs be called in app.ux that takes effect globally.
Code:
checkPushIsSupported(){
let provider= push.getProvider();
console.log("checkPush provider= "+provider);
if(provider==='huawei'){
this.pushsubscribe();
}
},
pushsubscribe() {
console.log("pushsubscribe start");
var that=this;
push.subscribe({
success: function (data) {
console.log("push.subscribe succeeded, result data=" + JSON.stringify(data));
that.dataApp.pushtoken=data.regId;
},
fail: function (data, code) {
console.log("push.subscribe failed, result data=" + JSON.stringify(data) + ", code=" + code);
},
complete: function () {
console.log("push.subscribe completed");
}
})
},
3. Report the obtained regId to the server of your quick app through the Fetch Data API, so the server can push messages to the device based on regId. Generally, the value of regId does not change and does not need to be reported to the server each time after it is obtained.
You are advised to call the Data Storage API to store the regId locally. Each time the regId is obtained, compare the regId with that stored locally. If they are the same, the regId does not need to be reported to the server. Otherwise, report the regId to the server.
The service process is as follows.
The sample code for comparing the obtained regId with that stored locally is as follows:
Code:
checkToken() {
var subscribeToken=this.$app.$def.dataApp.pushtoken;
console.log("checkToken subscribeToken= "+subscribeToken);
var storage = require("@system.storage");
var that=this;
storage.get({
key: 'token',
success: function (data) {
console.log("checkToken handling success data= "+data);
if (subscribeToken != data) {
// Report regId to your service server.
that.uploadToken(subscribeToken);
that.saveToken(subscribeToken);
}
},
fail: function (data, code) {
console.log("handling fail, code = " + code);
}
})
},
The sample code for saving regId locally is as follows:
Code:
saveToken(subscribeToken){
console.log("saveToken");
var storage = require("@system.storage");
storage.set({
key: 'token',
value: subscribeToken,
success: function (data) {
console.log("saveToken handling success");
},
fail: function (data, code) {
console.log("saveToken handling fail, code = " + code);
}
})
},
Testing Push Message Sending
You can test the push function by sending a push message to your test device. In this case, regId (push token) uniquely identifies your device. With it, your service server can accurately identify your device and push the message to your quick app on the device. Your device can receive the pushed message in any of the following conditions:
l The quick app has been added to the home screen.
l The quick app has been added to MY QUICK APP.
l The quick app has been used before.
l The quick app is running.
You can use either of the following methods to send a push message to a quick app that has been released on AppGallery or run by Huawei Quick App Loader.
l Select some target users in AppGallery Connect and send the push message.
l Call the specific server API to send the push message to users in batches.
Sending a Push Message Through AppGallery Connect
This method is simple. You only need to configure the recipients in AppGallery Connect. However, the target user scope is smaller than that through the API.
1. Sign in to AppGallery Connect and click My apps.
2. Find your app from the list and click the version that you want to test.
3. Go to Operate > Promotion > Push Kit. Click Add notification and configure the push message to be sent.
Sending a Push Message by Calling the API
1. Call the accessToken API to obtain the access token, which will be used in the push message sending API.
2. Call the push message sending API. The sample code of the push message body is as follows:
Code:
var mData = {
"pushtype": 0, // The value 0 indicates a notification message.
"pushbody": {
"title": "How can young people make a living? ",
"description": "Why did he choose to be a security guard after college graduation? ",
"page": "/", // Path of the quick app page that is displayed when a user taps a notification message. This parameter is valid only when pushtype is set to 0. /" Go to the app home page.
"params": {
"key1": "test1",
"key2": "test2"
},
"ringtone": {
"vibration": "true",
"breathLight": "true"
}
}
};
var formatJsonString = JSON.stringify(mData);
var messbody = {
"validate_only": false,
"message": {
"data": formatJsonString, // The data type is JsonString, not a JSON object.
"android": {
"fast_app_target": 1, // The value 1 indicates that a push message is sent to a quick app running by Huawei Quick App Loader. To send a push message to a quick app from AppGallery, set this parameter to 2.
"collapse_key": -1,
"delivery_priority": "HIGH",
"ttl": "1448s",
"bi_tag": "Trump",
},
"token": ['pushtoken1','pushtoken2'], // Target users of message pushing.
}
};
For details, please refer to Accessing HUAWEI Push Kit.
How much time it will take to integrate push kit into Quick App ?

Building a Custom Model for Image Classification with ML Kit

1. Intro
If you're looking to develop a customized and cost-effective deep learning model, you'd be remiss not to try the recently released custom model service in HUAWEI ML Kit. This service gives you the tools to manage the size of your model, and provides simple APIs for you to perform inference. The following is a demonstration of how you can run your model on a device at a minimal cost.
The service allows you to pre-train image classification models, and the steps below show you the process for training and using a custom model.
2. Implementation
a. Install HMS Toolkit from Android Studio Marketplace. After the installation, restart Android Studio.
{
"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"
}
b. Transfer learning by using AI Create.
Basic configuration
* Note: First install a Python IDE.
AI Create uses MindSpore as the training framework and MindSpore Lite as the inference framework. Follows the steps below to complete the basic configuration.
i) In Coding Assistant, go to AI > AI Create.
ii) Select Image or Text, and click on Confirm.
iii) Restart the IDE. Select Image or Text, and click on Confirm. The MindSpore tool will be automatically installed.
HMS Toolkit allows you to generate an API or demo project in one click, enabling you to quickly verify and call the image classification model in your app.
Before using the transfer learning function for image classification, prepare image resources for training as needed.
*Note: The images should be clear and placed in different folders by category.
Model training
Train the image classification model pre-trained in ML Kit to learn hundreds of images in specific fields (such as vehicles and animals) in a matter of minutes. A new model will then be generated, which will be capable of automatically classifying images. Follow the steps below for model training.
i) In Coding Assistant, go to AI > AI Create > Image.
ii) Set the following parameters and click on Confirm.
Operation type: Select New Model.
Model Deployment Location: Select Deployment Cloud.
iii) Drag or add the image folders to the Please select train image folder area.
iv) Set Output model file path and train parameters.
v) Retain the default values of the train parameters as shown below:
Iteration count: 100
Learning rate: 0.01
vi) Click on Create Model to start training and to generate an image classification model.
After the model is generated, view the model learning results (training precision and verification precision), corresponding learning parameters, and training data.
Model verification
After the model training is complete, you can verify the model by adding the image folders in the Please select test image folder area under Add test image. The tool will automatically use the trained model to perform the test and display the test results.
Click on Generate Demo to have HMS Toolkit generate a demo project, which automatically integrates the trained model. You can directly run and build the demo project to generate an APK file, and run the file on a simulator or real device to verify image classification performance.
c. Use the model.
Upload the model
The image classification service classifies elements in images into logical categories, such as people, objects, environments, activities, or artwork, to define image themes and application scenarios. The service supports both on-device and on-cloud recognition modes, and offers the pre-trained model capability.
To upload your model to the cloud, perform the following steps:
i) Sign in to AppGallery Connect and click on My projects.
ii) Go to ML Kit > Custom ML, to have the model upload page display. On this page, you can also upgrade existing models.
Load the remote model
Before loading a remote model, check whether the remote model has been downloaded. Load the local model if the remote model has not been downloaded.
Code:
localModel = new MLCustomLocalModel.Factory("localModelName")
.setAssetPathFile("assetpathname")
.create();
remoteModel =new MLCustomRemoteModel.Factory("yourremotemodelname").create();
MLLocalModelManager.getInstance()
// Check whether the remote model exists.
.isModelExist(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
MLModelExecutorSettings settings;
// If the remote model exists, load it first. Otherwise, load the existing local model.
if (isDownloaded) {
settings = new MLModelExecutorSettings.Factory(remoteModel).create();
} else {
settings = new MLModelExecutorSettings.Factory(localModel).create();
}
final MLModelExecutor modelExecutor = MLModelExecutor.getInstance(settings);
executorImpl(modelExecutor, bitmap);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// Exception handling.
}
});
Perform inference using the model inference engine
Set the input and output formats, input image data to the inference engine, and use the loaded modelExecutor(MLModelExecutor) to perform the inference.
Code:
private void executorImpl(final MLModelExecutor modelExecutor, Bitmap bitmap){
// Prepare input data.
final Bitmap inputBitmap = Bitmap.createScaledBitmap(srcBitmap, 224, 224, true);
final float[][][][] input = new float[1][224][224][3];
for (int i = 0; i < 224; i++) {
for (int j = 0; j < 224; j++) {
int pixel = inputBitmap.getPixel(i, j);
input[batchNum][j][i][0] = (Color.red(pixel) - 127) / 128.0f;
input[batchNum][j][i][1] = (Color.green(pixel) - 127) / 128.0f;
input[batchNum][j][i][2] = (Color.blue(pixel) - 127) / 128.0f;
}
}
MLModelInputs inputs = null;
try {
inputs = new MLModelInputs.Factory().add(input).create();
// If the model requires multiple inputs, you need to call add() for multiple times so that image data can be input to the inference engine at a time.
} catch (MLException e) {
// Handle the input data formatting exception.
}
// Perform inference. You can use addOnSuccessListener to listen for successful inference which is processed in the onSuccess callback. In addition, you can use addOnFailureListener to listen for inference failure which is processed in the onFailure callback.
modelExecutor.exec(inputs, inOutSettings).addOnSuccessListener(new OnSuccessListener<MLModelOutputs>() {
@Override
public void onSuccess(MLModelOutputs mlModelOutputs) {
float[][] output = mlModelOutputs.getOutput(0);
// The inference result is in the output array and can be further processed.
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// Inference exception.
}
});
}
3. Summary
By utilizing Huawei's deep learning framework, you'll be able to create and use a deep learning model for your app by following just a few steps!
Furthermore, the custom model service for ML Kit is compatible with all mainstream model inference platforms and frameworks on the market, including MindSpore, TensorFlow Lite, Caffe, and Onnx. Different models can be converted into .ms format, and run perfectly within the on-device inference framework.
Custom models can be deployed to the device in a smaller size after being quantized and compressed. To further reduce the APK size, you can host your models on the cloud. With this service, even a novice in the field of deep learning is able to quickly develop an AI-driven app which serves a specific purpose.
Learn More
For more information, please visit HUAWEI Developers.
For detailed instructions, please visit Development Guide.
You can join the HMS Core developer discussion on Reddit.
You can download the demo and sample code from GitHub.
To solve integration problems, please go to Stack Overflow.
It seems there are many new fuctions on ML Kit. Wonderful!
Hi, have you tried searching for public APIs?

Intermediate: Mobile App Security Using Huawei Safety detect Kit (Flutter)

Introduction
In this article, we will learn how to implement Huawei Safety detect kit in to mobile applications. Mobile devices have become more popular than laptops. Now a days users engage in nearly all activities on mobile devices, right from watching the news, checking emails, online shopping, doing bank transactions. Through these apps, business can gather usable information, which can help business to take precise decisions for better services.
{
"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"
}
What is Huawei Safety Detect Service?
Safety Detect builds robust security capabilities, including system integrity check (SysIntegrity), app security check (AppsCheck), malicious URL check (URLCheck), fake user detection (UserDetect), and malicious Wi-Fi detection (WifiDetect), into your app, effectively protecting it against security threats.
1. SysIntegrity API: Checks whether the device running your app is secure, for example, whether it is rooted.
2. AppsCheck API: Checks for malicious apps and provides you with a list of malicious apps.
3. URLCheck API: Determines the threat type of a specific URL.
4. UserDetect API: Checks whether your app is interacting with a fake user.
5. WifiDetect API: Checks whether the Wi-Fi to be connected is secure.
Why Security is required for Apps
Mobile app security is a measure to secure application from threats like malware and other digital frauds that risk critical personal and financial information from hackers to avoid all of these we need to integrate the safety detect.
What are all the restrictions exists?
Currently two restrictions are there WifiDetect and UserDetect.
1. WifiDetect function available only in Chinese mainland.
2. UserDetect function not available in Chinese mainland.
Advantages
1. Provides a Trusted Execution Environment (TEE) to check system integrity.
2. Makes building security into your app easy with a rapid integration wizard.
3. Checks security for a diversity of apps: e-commerce, finance, multimedia, and news.
Requirements
1. Any operating system(i.e. MacOS, Linux and Windows)
2. Any IDE with Flutter SDK installed (i.e. IntelliJ, Android Studio and VsCode etc.)
3. A little knowledge of Dart and Flutter.
4. A Brain to think
Setting up the project
1. Before start creating application we have to make sure we connect our project to AppGallery. For more information check this link
2. After that follow the URL for cross-platform plugins. Download required plugins.
3. Enable the Safety Detect in the Manage API section and add the plugin.
4. After completing all the above steps, you need to add the required kits’ Flutter plugins as dependencies to pubspec.yaml file. You can find all the plugins in pub.dev with the latest versions.
Code:
huawei_safetydetect:
path: ../huawei_safetydetect/
After adding them, run flutter pub get command. Now all the plugins are ready to use.
Note: Set multiDexEnabled to true in the android/app directory, so the app will not crash.
Why we need SysIntegrity API and How to Use?
The SysIntegrity API is called to check the system integrity of a device. If the device is not safe, appropriate measures are taken.
Before implementing this API we need to check device have latest version of HMS core must be installed on users device.
Obtain a nonce value will be used to determine whether the returned result corresponds to the request and did not encounter and replay attacks. The nonce value must contain a minimum of 16 bytes and is intended to be used only once. Request for the AppId as input parameters.
Code:
getAppId() async {
String appID = await SafetyDetect.getAppID;
setState(() {
appId = appID;
});
}
checkSysIntegrity() async {
Random secureRandom = Random.secure();
List randomIntegers = List<int>();
for (var i = 0; i < 24; i++) {
randomIntegers.add(secureRandom.nextInt(255));
}
Uint8List nonce = Uint8List.fromList(randomIntegers);
try {
String result = await SafetyDetect.sysIntegrity(nonce, appId);
List<String> jwsSplit = result.split(".");
String decodedText = utf8.decode(base64Url.decode(jwsSplit[1]));
showToast("SysIntegrityCheck result is: $decodedText");
} on PlatformException catch (e) {
showToast("Error occured while getting SysIntegrityResult. Error is : $e");
}
}
}
Why we need AppsCheck API and How to Use?
You can obtain all malicious applications and evaluate whether you can restrict the behaviour of your application based on the risk.
You can directly call the getMaliciousAppsList() method to get all the malicious apps.
Code:
void getMaliciousAppsList() async {
List<MaliciousAppData> maliciousApps = List();
maliciousApps = await SafetyDetect.getMaliciousAppsList();
setState(() {
showToast("malicious apps: ${maliciousApps.toString()}");
});
}
In the return from task, you will get a list of malicious applications. You can find out the package name, SHA256 value and category of an application in this list.
Why we need User Detect API and How to Use?
This API can help your app prevent batch registration, credential stuffing attacks, activity bonus hunting, and content crawling. If a user is a suspicious one or risky one, a verification code is sent to the user for secondary verification. If the detection result indicates that the user is a real one, the user can sign in to my app. Otherwise, the user is not allowed to MainPage.
Code:
void _signInHuawei() async {
final helper = new HmsAuthParamHelper();
helper
..setAccessToken()
..setIdToken()
..setProfile()
..setEmail()
..setAuthorizationCode();
try {
HmsAuthHuaweiId authHuaweiId =
await HmsAuthService.signIn(authParamHelper: helper);
StorageUtil.putString("Token", authHuaweiId.accessToken);
} on Exception catch (e) {}
}
userDetection() async {
try {
String token = await SafetyDetect.userDetection(appId);
print("User verification succeded, user token: $token");
if(token!=null){
userDetection();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePageScreen()),
);
}
} on PlatformException catch (e) {
print(
"Error occurred: " + e.code + ":" + SafetyDetectStatusCodes[e.code]);
}
}
Why we need URLCheck API and How to Use?
You can determine the dangerous urls using URL Check API. Currently UrlSafety API provide determinate MALWARE and PHISHING threats. When you visit a URL, this API checks whether the URL is a malicious one. If so, you can evaluate the risk and alert the user about the risk or block the URL.
Code:
InkWell(
onTap: () {
loadUrl();
},
child: Text(
'Visit: $url',
style:
TextStyle(color: textColor),
))
void loadUrl() async {
Future.delayed(const Duration(seconds: 5), () async {
urlCheck();
});
}
void urlCheck() async {
List<UrlThreatType> threatTypes = [
UrlThreatType.malware,
UrlThreatType.phishing
];
List<UrlCheckThreat> urlCheckResults =
await SafetyDetect.urlCheck(url, appId, threatTypes);
if (urlCheckResults.length == 0) {
showToast("No threat is detected for the URL");
} else {
urlCheckResults.forEach((element) {
print("${element.getUrlThreatType} is detected on the URL");
});
}
}
Why we need WifiDetect API and How to Use?
This API checks characteristics of the Wi-Fi and router to be connected, analyzes the Wi-Fi information, and returns the Wi-Fi detection results after classification, helping you prevent possible attacks to your app from malicious Wi-Fi. If attacks are detected app can interrupt the user operation or it will asks user permission.
Code:
@override
void initState() {
getWifiDetectStatus();
super.initState();
}
getWifiDetectStatus() async {
try {
WifiDetectResponse wifiDetectStatus =
await SafetyDetect.getWifiDetectStatus();
ApplicationUtils.displayToast(
'Wifi detect status is: ${wifiDetectStatus.getWifiDetectType.toString()}');
} on PlatformException catch (e) {
if (e.code.toString() == "19003") {
ApplicationUtils.displayToast(' The WifiDetect API is unavailable in this region');
}
}
}
Note: Currently this API supports Chinese mainland.
Demo
Tips & Tricks
1. Download latest HMS Flutter plugin.
2. Set minSDK version to 19 or later.
3. Do not forget to click pug get after adding dependencies.
4. Latest HMS Core APK is required.
Conclusion
These were some of the best practices that a mobile app developer must follow in order to have a fully secure and difficult-to-crack application.
In the near future, security will act as one of the differentiating and competing innovations in the app world, with customers preferring secure apps to maintain the privacy of their data over other mobile applications.
Thanks for reading! If you enjoyed this story, please click the Like button and Follow. Feel free to leave a Comment below.
Reference
Safety detect Kit URL
Checkout in forum

Communicating Between JavaScript and Java Through the Cordova Plugins in HMS Core Kit

1. Background
Cordova is an open-source cross-platform development framework that allows you to use HTML and JavaScript to develop apps across multiple platforms, such as Android and iOS. So how exactly does Cordova enable apps to run on different platforms and implement the functions? The abundant plugins in Cordova are the main reason, and free you to focus solely on app functions, without having to interact with the APIs at the OS level.
HMS Core provides a set of Cordova-related plugins, which enable you to integrate kits with greater ease and efficiency.
2. Introduction
Here, I'll use the Cordova plugin in HUAWEI Push Kit as an example to demonstrate how to call Java APIs in JavaScript through JavaScript-Java messaging.
The following implementation principles can be applied to all other kits, except for Map Kit and Ads Kit (which will be detailed later), and help you master troubleshooting solutions.
3. Basic Structure of Cordova
When you call loadUrl in MainActivity, CordovaWebView will be initialized and Cordova starts up. In this case, CordovaWebView will create PluginManager, NativeToJsMessageQueue, as well as ExposedJsApi of JavascriptInterface. ExposedJsApi and NativeToJsMessageQueue will play a role in the subsequent communication.
During the plugin loading, all plugins in the configuration file will be read when the PluginManager object is created, and plugin mappings will be created. When the plugin is called for the first time, instantiation is conducted and related functions are executed.
A message can be returned from Java to JavaScript in synchronous or asynchronous mode. In Cordova, set async in the method to distinguish the two modes.
In synchronous mode, Cordova obtains data from the header of the NativeToJsMessageQueue queue, finds the message request based on callbackID, and returns the data to the success method of the request.
In asynchronous mode, Cordova calls the loop method to continuously obtain data from the NativeToJsMessageQueue queue, finds the message request, and returns the data to the success method of the request.
In the Cordova plugin of Push Kit, the synchronization mode is used.
4. Plugin Call​You may still be unclear on how the process works, based on the description above, so I've provided the following procedure:
1. Install the plugin.
Run the cordova plugin add u/hmscore/cordova-plugin-hms-push command to install the latest plugin. After the command is executed, the plugin information is added to the plugins directory.
{
"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"
}
The plugin.xml file records all information to be used, such as JavaScript and Android classes. During the plugin initialization, the classes will be loaded to Cordova. If a method or API is not configured in the file, it is unable to be used.
2. Create a message mapping.
The plugin provides the methods for creating mappings for the following messages:
1) HmsMessaging
In the HmsPush.js file, call the runHmsMessaging API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsPushMessaging class. The execute method in HmsPushMessaging can transfer the message to a method for processing based on the action type in the message.
Code:
public void execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { hmsLogger.startMethodExecutionTimer(action); switch (action) { case "isAutoInitEnabled": isAutoInitEnabled(callbackContext); break; case "setAutoInitEnabled": setAutoInitEnabled(args.getBoolean(1), callbackContext); break; case "turnOffPush": turnOffPush(callbackContext); break; case "turnOnPush": turnOnPush(callbackContext); break; case "subscribe": subscribe(args.getString(1), callbackContext); break;
The processing method returns the result to JavaScript. The result will be written to the nativeToJsMessageQueue queue.
Code:
callBack.sendPluginResult(new PluginResult(PluginResult.Status.OK,autoInit));
2) HmsInstanceId
In the HmsPush.js file, call the runHmsInstance API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsPushInstanceId class. The execute method in HmsPushInstanceId can transfer the message to a method for processing based on the action type in the message.
Code:
public void execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { if (!action.equals("init")) hmsLogger.startMethodExecutionTimer(action);
switch (action) { case "init": Log.i("HMSPush", "HMSPush initialized "); break; case "enableLogger": enableLogger(callbackContext); break; case "disableLogger": disableLogger(callbackContext); break; case "getToken": getToken(args.length() > 1 ? args.getString(1) : Core.HCM, callbackContext); break; case "getAAID": getAAID(callbackContext); break; case "getCreationTime": getCreationTime(callbackContext); break;
Similarly, the processing method returns the result to JavaScript. The result will be written to the nativeToJsMessageQueue queue.
Code:
callBack.sendPluginResult(new PluginResult(PluginResult.Status.OK,autoInit));
This process is similar to that for HmsPushMessaging. The main difference is that HmsInstanceId is used for HmsPushInstanceId-related APIs, and HmsMessaging is used for HmsPushMessaging-related APIs.
3) localNotification
In the HmsLocalNotification.js file, call the run API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsLocalNotification class. The execute method in HmsLocalNotification can transfer the message to a method for processing based on the action type in the message.
Code:
public void execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { switch (action) { case "localNotification": localNotification(args, callbackContext); break; case "localNotificationSchedule": localNotificationSchedule(args.getJSONObject(1), callbackContext); break; case "cancelAllNotifications": cancelAllNotifications(callbackContext); break; case "cancelNotifications": cancelNotifications(callbackContext); break; case "cancelScheduledNotifications": cancelScheduledNotifications(callbackContext); break; case "cancelNotificationsWithId": cancelNotificationsWithId(args.getJSONArray(1), callbackContext); break;
Call sendPluginResult to return the result. However, for localNotification, the result will be returned after the notification is sent.
3. Perform message push event callback.
In addition to the method calling, message push involves listening for many events, for example, receiving common messages, data messages, and tokens.
The callback process starts from Android.
In Android, the callback method is defined in HmsPushMessageService.java.
Based on the SDK requirements, you can opt to redefine certain callback methods, such as onMessageReceived, onDeletedMessages, and onNewToken.
When an event is triggered, an event notification is sent to JavaScript.
Code:
public static void runJS(final CordovaPlugin plugin, final String jsCode) { if (plugin == null) return; Log.d(TAG, "runJS()");
plugin.cordova.getActivity().runOnUiThread(() -> { CordovaWebViewEngine engine = plugin.webView.getEngine(); if (engine == null) { plugin.webView.loadUrl("javascript:" + jsCode);
} else { engine.evaluateJavascript(jsCode, (result) -> {
}); } }); }
Each event is defined and registered in HmsPushEvent.js.
exports.REMOTE_DATA_MESSAGE_RECEIVED = "REMOTE_DATA_MESSAGE_RECEIVED"; exports.TOKEN_RECEIVED_EVENT = "TOKEN_RECEIVED_EVENT"; exports.ON_TOKEN_ERROR_EVENT = "ON_TOKEN_ERROR_EVENT"; exports.NOTIFICATION_OPENED_EVENT = "NOTIFICATION_OPENED_EVENT"; exports.LOCAL_NOTIFICATION_ACTION_EVENT = "LOCAL_NOTIFICATION_ACTION_EVENT"; exports.ON_PUSH_MESSAGE_SENT = "ON_PUSH_MESSAGE_SENT"; exports.ON_PUSH_MESSAGE_SENT_ERROR = "ON_PUSH_MESSAGE_SENT_ERROR"; exports.ON_PUSH_MESSAGE_SENT_DELIVERED = "ON_PUSH_MESSAGE_SENT_DELIVERED";
Java:
function onPushMessageSentDelivered(result) { window.registerHMSEvent(exports.ON_PUSH_MESSAGE_SENT_DELIVERED, result); } exports.onPushMessageSentDelivered = onPushMessageSentDelivered;
Please note that the event initialization needs to be performed during app development. Otherwise, the event listening will fail. For more details, please refer to eventListeners.js in the demo.
If the callback has been triggered in Java, but is not received in JavaScript, check whether the event initialization is performed.
In doing so, when an event is triggered in Android, JavaScript will be able to receive and process the message. You can also refer to this process to add an event.
5. Summary
The description above illustrates how the plugin implements the JavaScript-Java communications. The methods of most kits can be called in a similar manner. However, Map Kit, Ads Kit, and other kits that need to display images or videos (such as maps and native ads) require a different method, which will be introduced in a later article.
To learn more, please visit:
HUAWEI Developers official website
Development Guide
Reddit to join developer discussions
GitHub or Gitee to download the demo and sample code
Stack Overflow to solve integration problems
Follow our official account for the latest HMS Core-related news and updates.
Original Source

Categories

Resources