Assigning App Permissions
The Android OS provides two location permissions: ACCESS_COARSE_LOCATION (approximate location permission) and ACCESS_FINE_LOCATION (precise location permission). These permissions are already defined in plugin.xml as follows:
Code:
<!--Fused Location-->
<config-file target="AndroidManifest.xml" parent="/*">
<!--...-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--...-->
</config-file>
In Android Q, if your app needs to continuously locate the device location when it runs in the background, you need to apply for the ACCESS_BACKGROUND_LOCATION permission. This permission is already defined in plugin.xml as follows:
Code:
<!--Fused Location-->
<config-file target="AndroidManifest.xml" parent="/*">
<!--...-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!--...-->
</config-file>
Using the Location Service Class
The Java class defined for Fused Location service of Location Kit is HMSFusedLocation.
To use it on Cordova, you should initilize Fused Location service of Location Kit with HMSFusedLocation.init() method before using other methods of HMSFusedLocation.
Code:
// Initialize
LocationKitHMSLocationKit.init();
HMSFusedLocation.init();
Checking the Device Location Settings
Device location settings will affect the location result of HUAWEI Location Kit. For example, if the location function is disabled on a device, the device location cannot be obtained. Therefore, you are advised to check whether the device settings meet the location requirements before continuously obtaining location information. HUAWEI Location Kit provides the capability of checking device location settings.
If the location settings do not meet the location requirements, your app can prompt users to enable related permissions. (The location permission must be enabled for HMS Core (APK). In Android Q, Location must be set to Always for HMS Core.)
You can obtain the location settings using the checkLocationSettings(locationSettingsRequest) method.
The locationSettingsRequest object is an input parameter of the method and has three attributes: locationRequest, alwaysShow, and needBle.
The following is the sample code for creating a locationRequest object:
Code:
const locationRequest = () => { return {
id: 'locationRequest' + Math.random() * 10000,
priority: HMSFusedLocation.PriorityConstants.PRIORITY_HIGH_ACCURACY,
interval: 3,
numUpdates: 10,
fastestInterval: 1000.0,
expirationTime: 200000.0,
expirationTimeDuration: 200000.0,
smallestDisplacement: 0.0,
maxWaitTime: 2000000.0,
needAddress: true,
language: 'en',
countryCode: 'en',
}};
Then, following code can be used to create a locationSettingsRequest object:
Code:
const locationSettingsRequest = () => { return {
alwaysShow: true,
needBle: true,
locationRequests: [locationRequest()]
}};
The needBle attribute indicates whether BLE scanning needs to be enabled. The options are true (yes) and false (no).
The alwaysShow attribute indicates whether a location is required for the app to continue. The options are true (yes) and false (no).
Finally, call the checkLocationSettings() method to obtain the location settings. The method returns a response containing the result.
Code:
const locationSettingsResult = await HMSFusedLocation.checkLocationSettings(locationSettingsRequest());
Obtaining the Last Known Location
An app can use the HUAWEI Location Kit service API to obtain the last known location of a device. In most cases, the last known location is the current location of the device. The following is the sample code for calling the getLastLocation() method to obtain the last known location.
The method has no input parameter and returns a response containing the location data.
Code:
const lastLocation = await HMSFusedLocation.getLastLocation();
Continuously Obtaining the Location Information
To enable your app to continuously obtain the device location, you can use the requestLocationUpdates() and registerHMSEvent(eventName, handler) methods provided by HUAWEI Location Kit.
First, you need to create a locationRequest object as in the example of checking the device location settings. Then, you need to call the requestLocationUpdates() method.
This method is used to request location updates using the callback on the specified Looper thread, and then returns the location request ID, if the request was successful.
Code:
const requestLocationUpdatesResult = await HMSFusedLocation.requestLocationUpdates(locationRequest());
console.log({requestLocationUpdatesResult});
Then, call the method registerHMSEvent(eventName, handler) that handles the HMS update events.
Code:
registerHMSEvent(HMSFusedLocation.Events.SCANNING_RESULT, (result) => {
console.log('new location update');
})
Using the Mock Location
Note:
To use the mock location function, go to Settings > System & updates > Developer options > Select mock location app and select the app for using the mock location function.
(If Developer options is unavailable, go to Settings > About phone and tap Build number for seven consecutive times. Then, Developer options will be displayed on System & updates.)
Mock location feature can be enabled or disabled with the following method: setMockMode( boolean ).
This takes a boolean as argument, which indicates whether mock mode should be enabled or disabled.
The method returns a promise with the result, which should be resolved.
Code:
const setMockModeResult = await HMSFusedLocation.setMockMode(true);//or "false" to disable
Coordinates of the mock location can be set with the following method: setMockLocation({ latitude, longitude })
The method takes a single object as an argument, which contains the properties latitude and longitude.
Then the method returns the result with a promise, which should be resolved.
Code:
const setMockLocationResult = await HMSFusedLocation.setMockLocation({
latitude: parseFloat(latitude),
longitude: parseFloat(longitude)
});
console.log({setMockLocationResult});
Once the mock location function is enabled and set, your app will return the specified location data when trying to obtain the last location information.
Related
Today we're going to go through getting started with Huawei's Safety Detect SDK. We'll talk about how to get set up, as well as some basic examples of how to use it.
What is Huawei Safety Detect?
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.
Preparation
First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.
Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.
On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:
Code:
C:\Program Files\Java\jdk1.8.0_231\bin\
Once you find the directory, "cd" into it:
Code:
C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\
Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:
Code:
E:\AndroidSDK\.android\debug.keystore
(Keytool also supports JKS-format keystores.)
Now you're ready to run the command. On Windows, it'll look something like this:
Code:
keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore
On Linux, the command should be similar, just using UNIX-style paths instead.
Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:
{
"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"
}
Make note of the SHA256 field.
SDK Setup
Now we're ready to add the Safety Detect SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.
Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.
Now, you should be on a screen that looks something like the following:
Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.
Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project. You'll also need to add the following to the "dependencies" section of your app-level build.gradle file:
Code:
implementation 'com.huawei.hms:safetydetect:4.0.3.300'
If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.
Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.
Now, go to the Manage APIs tab on the "Project setting" page. Scroll down until you find "Safety Detect" and make sure it's enabled.
Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.
For ProGuard:
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
For AndResGuard:
Code:
"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*
That's it! The Safety Detect SDK should now be available in your project.
Basic Usage
Now that the SDK is set up, it's time to actually use it. Safety Detect currently has 5 APIs you can use: SysIntegrity, AppsCheck, URLCheck, UserDetect, and WifiDetect.
The first thing you'll want to do when using any of these APIs is to check whether HMS is actually available:
Code:
if (HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context) == ConnectionResult.SUCCESS) {
//HMS is available
} else {
//HMS isn't available. Act accordingly
}
Without HMS, these APIs won't work. Prompt the user to update/install HMS, or simply silently fail, depending on your needs.
SysIntegrity
The SysIntegrity API is similar to Google's SafetyNet. You can use it to check if the current device is insecure (e.g. is rooted). If your app relies heavily on running in a secure environment, you can use this check and refuse to run if it fails.
To use SysIntegrity, you need a few things: a nonce value, your app ID, and an active internet connection. The nonce value should be a secret, needs to be at least 16 bytes long, and can only be used once. It'll be contained in the SysIntegrity check result, so you can verify that the result is genuine.
You can find your app ID under the "App information" section on the "Project Setting" page.
Here's a quick example in Kotlin of how to set up the integrity check request:
Code:
fun checkSysIntegrity() {
val client = SafetyDetect.getClient(context)
//Ideally, you'd use a better nonce generation method, either from your own server
//or some other secure environment.
val nonce = "NONCE_${System.currentTimeMillis()}".toByteArray()
//You can find your APP_ID under "App information" in your project's settings on the AppGallery Developer Console.
val task = client.sysIntegrity(nonce, "APP_ID")
task.addOnSuccessListener {
val result = it.result
//Process the result. It will be in the JWS (JSON Web Signature) format, containing a header, payload, and signature.
//The header contains a certificate chain that should be verified against the HUAWEI CGB Root CA.
//Make sure the domain name of the leaf certificate in the certificate chain is `sysintegrity.platform.hicloud.com`.
//Verify the signature.
//Next, check the payload for the nonce and result. The payload format is something like the following:
/*
{
"advice":"RESTORE_TO_FACTORY_ROM",
"apkCertificateDigestSha256":[
"yT5JtXRgeIgXssx1gQTsMA9GzM9ER4xAgCsCC69Fz3I="
],
"apkDigestSha256":"6Ihk8Wcv1MLm0O5KUCEVYCI/0KWzAHn9DyN38R3WYu8=",
"apkPackageName":"com.huawei.hms.safetydetectsample",
"basicIntegrity":false,
"nonce":"R2Rra24fVm5xa2Mg",
"timestampMs":1571708929141
}
*/
//If basicIntegrity is false, then the check failed and you should handle it appropriately.
//You can use the following library to parse the JWS string: https://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt
}
task.addOnFailureListener {
//The request failed. If `it is ApiException`, you might be able to get more details about why the failure occurred.
//Note that this doesn't imply that the device has failed an integrity check. It merely means the check itself has failed.
//You can choose to retry, or simply ignore the error.
}
}
Put that code in a helper Class, and call it as needed. It is an asynchronous API, so make sure you account for that.
AppsCheck
The functionality of AppsCheck is pretty simple. It'll return a list of apps installed on the current device that are potentially malicious. You can use the result to decide on whether or not you want to restrict features, or prevent your app from running.
To get you up and running, a basic example is provided below. You can use it as the base for your implementation.
Code:
fun checkApps() {
val client = SafetyDetect.getClient(context)
val task = client.maliciousAppsList
task.addOnSuccessListener {
if (it.rtnCode == CommonCode.OK) {
//The request truly succeeded
//An ArrayList<MaliciousAppsData>
val apps = it.maliciousAppsList
if (apps.isEmpty()) {
//No malicious apps were found
} else {
//HMS found at least one potentially malicious app
apps.forEach {
//The package name of the potentially malicious app
val packageName = it.apkPackageName
//The SHA-256 of the potentially malicious app
val sha256 = it.apkSha256
//The category of the potentially malicious app
//Constants are defined in the AppsCheckConstants class
//Currently, this can return either VIRUS_LEVEL_RISK (1)
//or VIRUS_LEVEL_VIRUS (2)
val category = it.apkCategory
}
}
} else {
//Something went wrong with the request
//Use `it.getErrorReason()` to see why
}
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
URLCheck
If your app allows users to visit URLs you aren't able to verify (forum app, social media app, etc), URLCheck can help you screen links that users click. If the URL is detected as malicious, you can prompt the user.
If you want to implement this for yourself, start with the example code below:
Code:
fun checkUrl(url: String) {
val client = SafetyDetect.getClient(context)
//Ensure the URLCheck API is initialized
val initTask = client.initUrlCheck()
initTask.addOnSuccessListener {
//Initialization was successful.
//Make sure to remove any query parameters from the URL before checking it.
//For example, if the full URL is https://google.com/home?someKey=true, you need to pass
//https://google.com/home.
//...
//UrlCheckThreat can either be MALWARE or PHISHING.
//Each category is fairly self-explanatory.
//The threat argument is a vararg, so you can pass one or both.
//...
//You can find your APP_ID under "App information" in your project's settings on the AppGallery Developer Console.
val task = client.urlCheck(url, "APP_ID", UrlCheckThreat.MALWARE, UrlCheckThreat.PHISHING)
task.addOnSuccessListener {
//API call succeeded.
if (it.urlCheckResponse.isEmpty()) {
//URL is safe, continue
} else {
//URL matches either MALWARE or PHISHING category or both. Notify user or refuse to visit
//as is appropriate.
//Get the first threat type. Will match one of the UrlCheckThreat values you pass to
//the urlCheck() method.
val type = it.urlCheckResponse[0].urlCheckResult
}
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
initTask.addOnFailureListener {
//Initialization failed.
}
}
UserDetect
UserDetect is essentially a realtime Captcha service. If there are parts of your app that you don't want to be used by bots (i.e. a clicker game), you can trigger a detection request to determine if the user is a bot or a person.
This one is a bit more complicated to implement, as it requires that you use HMS' cloud API to make the final request (i.e. a web server).
An example implementation in Kotlin is shown below:
Code:
fun checkUser() {
val client = SafetyDetect.getClient(context)
val initTask = client.initUserDetect()
initTask.addOnSuccessListener {
//Initialization was successful
//You can find your APP_ID under "App information" in your project's settings on the AppGallery Developer Console.
val task = client.userDetection("APP_ID")
task.addOnSuccessListener {
val responseToken = it.responseToken
if (responseToken.isNotEmpty()) {
//Pass this token to your server, and have it call HMS' cloud API to do the actual verification.
}
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
initTask.addOnFailureListener {
//Initialization failed.
}
}
WifiDetect
If your app relies on a secure WiFi connection, this API may be helpful to you. You can use it to check whether the user's WiFI connection is actually secure.
Here's a quick example stub in Kotlin:
Code:
fun checkWifi() {
val client = SafetyDetect.getClient(context)
val task = client.wifiDetectStatus
task.addOnSuccessListener {
//The status will either be 0, 1, or 2, depending on the WiFi network state.
//0 means WiFi is disconnected.
//1 means WiFi is secure.
//2 means WiFi is insecure.
val status = it.wifiDetectStatus
}
task.addOnFailureListener {
//A communication error occurred.
//If `it is ApiException`, you may be able to get more details about why
//the failure occurred.
}
}
Conclusion
That's all for the SafetyDetect SDK! If you're using HMS, or you're planning to use HMS, and you want to make sure your app is properly secured, the various included APIs are sure to be helpful.
You can find more details, including the full API reference for the Safety Detect SDK, on Huawei's developer website.
Have you ever wanted to be able to scan and create 13+ different types of barcodes from your app? Hopefully you have, otherwise I'm not sure why you're reading this. If you do, then Huawei has an SDK for you: Scan Kit.
Scan Kit allows you to scan and generate various different one-dimensional and two-dimensional barcodes with ease, and you don't even need a Huawei device to use it.
Interested? No? Well, get interested. Now? Good. Let's get started.
Preparation
First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.
Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.
On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:
Code:
C:\Program Files\Java\jdk1.8.0_231\bin\
Once you find the directory, "cd" into it:
Code:
C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\
Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:
Code:
E:\AndroidSDK\.android\debug.keystore
(Keytool also supports JKS-format keystores.)
Now you're ready to run the command. On Windows, it'll look something like this:
Code:
keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore
On Linux, the command should be similar, just using UNIX-style paths instead.
Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:
{
"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"
}
Make note of the SHA256 field.
SDK Setup
Now we're ready to add the Scan Kit SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.
Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.
Now, you should be on a screen that looks something like the following:
Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.
Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project.
You'll also need to add one of the following to the "dependencies" section of your app-level build.gradle file:
Code:
implementation 'com.huawei.hms:scan:1.2.0.301'
implementation 'com.huawei.hms:scanplus:1.2.0.301'
The difference between these dependencies is fairly simple. The basic Scan Kit SDK is only about 0.8MB in size, while the Scan Kit Plus SDK is about 3.3MB. The basic SDK will function identically to the Plus SDK on Huawei devices. On non-Huawei devices, you'll lose the enhanced recognition capabilities with the basic SDK.
If your app has size restrictions, and you only need basic QR code recognition, then the basic SDK is the best choice. Otherwise, pick the Plus SDK.
If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.
Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.
Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.
For ProGuard:
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
For AndResGuard:
Code:
"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*
That's it! The Scan Kit SDK should now be available in your project.
Basic Usage
In order to properly use Scan Kit, you'll need to declare some permissions in your app:
XML:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
These are both dangerous-level permissions, so make sure you request access to them at runtime on Marshmallow and later.
You should also declare a couple required device features, to make sure distribution platforms can hide your app on incompatible devices:
XML:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Now that you've got the permissions and features declared, it's time to start scanning. There are four modes you can use: Default View, Customized View, Bitmap, and MultiProcessor.
Default View
The Default View is the quickest way to get set up and running. Scan Kit provides the UI and does all the scanning work for you. This mode is able to scan barcodes live through the camera viewfinder, or by scanning existing images.
The first thing you'll need to do to use this is to declare the Scan Kit's scanner Activity in your Manifest:
XML:
<activity android:name="com.huawei.hms.hmsscankit.ScanKitActivity" />
Next, simply call the appropriate method to start the Activity. This must be done from an Activity context, since it makes use of Android's onActivityResult() API.
Code:
//The options here are optional. You can simply pass null
//to the startScan() method below.
//This is useful if you're only looking to scan certain
//types of codes. Scan Kit currently supports 13. You can
//see the list here: https://developer.huawei.com/consumer/en/doc/HMSCore-Guides-V5/barcode-formats-supported-0000001050043981-V5
val options = HmsScanAnalyzerOptions.Creator()
.setHmsScanTypes(
HmsScan.QRCODE_SCAN_TYPE,
HmsScan.DATAMATRIX_SCAN_TYPE
)
.create()
ScanUtil.startScan(activity, REQUEST_CODE, options)
Now you just need to handle the result:
Code:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != Activity.RESULT_OK || data == null) {
//Scanning wasn't successful. Nothing to handle.
return
}
if (requestCode == REQUEST_CODE) {
//Scan succeeded. Let's get the data.
val hmsScan = data.getParcelableExtra<HmsScan>(ScanUtil.RESULT)
if (hmsScan != null) {
//Handle appropriately.
}
}
}
We'll talk more about handling the result later.
Customized View
Customized View is similar to Default View in that Scan Kit will handle the scanning logic for you. The difference is that this mode lets you create your own UI. You're also limited to using the live viewfinder.
The following code should be placed inside your Activity's onCreate() method:
Code:
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scan)
//A ViewGroup to hold the scanning View that HMS will create
val container = findViewById<FrameLayout>(R.id.scanning_container)
//The position/size of the scanning area inside the scanning
//View itself. This is optional.
val scanBounds = Rect()
//The scanning View itself.
val scanView = RemoteView.Builder()
.setContext(this)
.setBoundingBox(scanBounds) //optional
.setFormat(HmsScan.QR_SCAN_TYPE) //optional, accepts a vararg of formats
.build()
//Initialize the scanning View.
scanView.onCreate(savedInstanceState)
container.addView(scanView)
scanView.setOnResultCallback { result ->
//`result` is an Array<HmsScan>
//Handle accordingly.
}
}
We'll talk about how to handle the HmsScan object later.
In a real application, the "scanView" variable should be a global variable. It's lifecycle-aware, so it has all the lifecycle methods, which you should probably call:
Code:
override fun onStart() {
super.onStart()
scanView.onStart()
}
//etc
Bitmap
This mode is useful if you have a Bitmap and you want to decode it. You can get that Bitmap however you want. All that matters is that you have one.
The example below shows how to obtain a Bitmap either from a camera capture frame or from an existing image in internal storage, and how to pass that Bitmap to Scan Kit for processing.
Code:
val img = YuvImage(
//A byte array representation of an image.
data,
//Depends on your image type: https://developer.android.com/reference/android/graphics/ImageFormat
ImageFormat.NV21,
//The width of the image data.
width,
//The height of the image data.
height
)
val stream = ByteArrayOutputStream()
//Copy the data to an output stream.
img.compressToJpeg(
//Size of the JPEG, in a Rect representation.
Rect(0, 0, width, height),
//Quality.
100,
//Output stream.
stream
)
//Create a Bitmap
val bmp = BitmapFactory.decodeByteArray(
stream.asByteArray(),
0,
stream.asByteArray().size
)
//If you want to use a pre-existing image, just obtain
//a Bitmap for that. This example would be placed in
//onActivityResult() after using ACTION_GET_CONTENT for an image.
val bmp = MediaStore.Images.Media.getBitmap(contentResolver, data.data)
//Set up the options.
val options = HmsScanAnalyzerOptions.Creator()
//Scan types are optional.
.setHmsScanTypes(
HmsScan.QRCODE_SCAN_TYPE,
HmsScan.DATAMATRIX_SCAN_TYPE
)
//If you're retrieving a Bitmap from an existing photo,
//set this to `true`.
.setPhotoMode(false)
.create()
//Send the scanning request and get the result.
val scans: Array<HmsScan> = ScanUtil.decodeWithBitmap(context, bmp, options)
if (!scans.isNullOrEmpty()) {
//Scanning was successful.
//Check individual scanning results.
scans.forEach {
//Handle.
//If zoomValue != 1.0, make sure you update
//the focal length of your camera interface,
//if you're using a camera. See Huawei's
//documentation for details on this.
//https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-bitmap-camera-0000001050042014
val zoomValue = it.zoomValue
}
}
We'll go over how to handle the HmsScan later on.
MultiProccessor
The MultiProcessor mode supports both existing images and using a viewfinder. It can take image frames and analyze them using machine learning to simultaneously detect multiple barcodes, along with other objects, like faces.
There are two ways to implement this mode: synchronously, and asychronously.
Here's an example showing how to implement it synchronously.
Code:
//Create the options (optional).
val options = HmsScanAnalyzerOptions.Creator()
.setHmsScanTypes(
HmsScan.QRCODE_SCAN_TYPE,
HmsScan.DATAMATRIX_SCAN_TYPE
)
.create()
//Set up the barcode detector.
val barcodeDetector = HmsScanAnalyzer(options /* or null */)
//You'll need some sort of Bitmap reference.
val bmp = /* However you want to obtain it */
//Convert that Bitmap to an MLFrame.
val frame = MLFrame.fromBitmap(bmp)
//Analyze and handle result(s).
val results: SparseArray<HmsScan> = barcodeDetector.analyseFrame(frame)
results.forEach {
//Handle accordingly.
}
To analyze asynchronously, just change the method called on "barcodeDetector":
Code:
barcodeDetector.analyzInAsyn(frame)
.addOnSuccessListener { scans ->
//`scans` is a List<HmsScan>
scans?.forEach {
//Handle accordingly.
}
}
.addOnFailureListener { error ->
//Scanning failed. Check Exception.
}
Parsing Barcodes
It's finally time to talk about parsing the barcodes! Yay!
The HmsScan object has a bunch of methods you can use to retrieve information about barcodes scanned by each method.
Code:
val scan: HmsScan = /* some HmsScan instance */
//The value contained in the code. For instance,
//if it's a QR code for an SMS, this value will be
//something like: "smsto:1234567890:Hi!".
val originalValue = scan.originalValue
//The type of code. For example, SMS_FORM, URL_FORM,
//or WIFI_CONNTENT_INFO_FORM. You can find all the forms
//here: https://developer.huawei.com/consumer/en/doc/development/HMSCore-References-V5/scan-hms-scan4-0000001050167739-V5.
val scanTypeForm = scan.scanTypeForm
//If it's a call or SMS, you can retrieve the
//destination phone number. This will be something
//like "1234567890".
val destPhoneNumber = scan.destPhoneNumber
//If it's an SMS, you can retrieve the message
//content. This will be something like "Hi!".
val smsContent = scan.smsContent
There are plenty more methods in the HmsScan class to help you parse various barcodes. You can see them all in Huawei's API reference.
Barcode Generation
Finally, let's talk about how to make your own barcodes using Scan Kit. This example will show you how to make a QR code, although you should be able to create any of the formats supported by Scan Kit.
Code:
//The code's content.
val content = "Some Content"
//Can be any supported type.
val type = HmsScan.QRCODE_SCAN_TYPE
//Output dimensions.
val width = 400
val height = 400
//Create the options.
val options = HmsBuildBitmapOption.Creator()
//The background of the barcode image. White is the default.
.setBitmapBackgroundColor(Color.RED)
//The color of the barcode itself. Black is the default
.setBitmapColor(Color.BLUE)
//Margins around the barcode. 1 is the default.
.setBitmapMargin(3)
.create()
try {
//Build the output Bitmap.
val output = ScanUtil.buildBitmap(content, type, width, height, options)
//Save it to internal storage, upload it somewhere, etc.
} catch (e: WriterException) {
//Creation failed. This can happen if one of the arguments for `buildBitmap()` is invalid.
}
Conclusion
And that's it!
Scan Kit is a powerful SDK that doesn't even require a Huawei device to work. Hopefully, this guide helped you get up and running. For more details on implementation, along with the API reference, be sure to check out Huawei's full documentation.
The HMS Site Kit SDK is a handy set of APIs to help you implement location and address-based searching in your app with ease. If you want to target Huawei devices with your app, and you're looking for a simple way to find and show results to your user, you've come to the right place.
This guide will get you started with the Site Kit SDK, and give you some basic implementation examples. Let's get started.
Preparation
First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.
Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.
On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:
Code:
C:\Program Files\Java\jdk1.8.0_231\bin\
Once you find the directory, "cd" into it:
Code:
C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\
Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:
Code:
E:\AndroidSDK\.android\debug.keystore
(Keytool also supports JKS-format keystores.)
Now you're ready to run the command. On Windows, it'll look something like this:
Code:
keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore
On Linux, the command should be similar, just using UNIX-style paths instead.
Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:
{
"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"
}
Make note of the SHA256 field.
SDK Setup
Now we're ready to add the Site Kit SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.
Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.
Now, you should be on a screen that looks something like the following:
Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.
Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project. You'll also need to add the following to the "dependencies" section of your app-level build.gradle file:
Code:
implementation 'com.huawei.hms:site:5.0.0.300'
If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.
Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.
Now, go to the Manage APIs tab on the "Project setting" page. Scroll down until you find "Site Kit" and make sure it's enabled.
Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.
For ProGuard:
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
For AndResGuard:
Code:
"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*"
That's it! The Site Kit SDK should now be available in your project.
Basic Usage
Huawei's Site Kit SDK gives you quite a few useful features.
There's Keyword Search, which lets the user type in a search query, along with other options, and see relevant results.
There's Nearby Place Search, which returns points of interest close to the user. There's a Place Details API, to let the user find out more about a specific place.
There's the Place Search Suggestion feature, which adds autofill-like search suggestions in real-time.
And finally, there's the Widget component, which implements Place Search Suggestion in a search bar for you.
We'll go over each feature one by one.
Keyword Search
Below is an example of how you might implement a keyword search.
Code:
//Create the search service. It's recommended you use an Activity
//Context, although it's not required.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
val searchService = SearchServiceFactory.create(context, "API_KEY")
//Create a request. For this example, we're going to be
//using dummy inputs, but in a real app, these would
//be provided by the user.
val request = TextSearchRequest()
//This can be any keyword, like "McDonald's" or
//"Washington".
request.setQuery("London")
//Define a location (optional). This could be the user's
//current location, or some other area.
val location = Coordinate(48.893478, 2.334595)
request.setLocation(location)
//Set a radius in meters (optional). The default is 50,000.
location.setRadius(1000)
//Set the type of location (optional, but recommended).
//Values can be found in the HwLocationType class.
request.setHwPoiType(HwLocationType.ENTERTAINMENT_PLACE)
//Set the country code to where these results should be
//confined (optional). Uses the ISO-3166-1 alpha-2 standard.
request.setCountryCode("FR")
//Set the language for results to appear in (optional).
request.setLanguage("fr")
//Set the current page (from 1-60). Default is 1.
request.setPageIndex(1)
//Set how many results should appear per-page (from 1-20).
//Default is 20.
request.setPageSize(5)
//Create a result listener for handling search results.
val resultListener = object : SearchResultListener<TextSearchResponse>() {
override fun onSearchResult(result: TextSearchResponse?) {
//We've got results.
if (result == null || result.totalCount <= 0) {
//We actually don't have results. Return.
return
}
val sites: List<Site>? = result.sites
if (sites.isNullOrEmpty()) {
//Couldn't find any sites. Return.
return
}
//Handle results.
sites.forEach { site ->
val id = site.siteId
val name = site.name
}
}
override fun onSearchError(state: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
}
//Finally, initiate the search.
searchService.textSearch(request, resultListener)
Nearby Place Search
A Nearby Place Search is practically identical to a Keyword Search in terms of implementation. Simply replace the textSearch() call with a nearbySearch() call. Almost everything else is identical.
Code:
//Use this instead of `textSearch()`.
//One notable difference is that the default radius
//for a nearby search is 1,000 meters instead of 50,000.
searchService.nearbySearch(request, resultListener)
Place Details
Creating a Place Details request is similar to the previous two, although there are some differences in implementation. For one, you should know the site ID of the place whose details you're querying, which you can get using one of the above methods.
Code:
/Create the search service. It's recommended you use an Activity
//Context, although it's not required.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
val searchService = SearchServiceFactory.create(context, "API_KEY")
//Create the details request.
val request = DetailSearchRequest()
//Set the site ID. You can retrieve this from a keyword or
//nearby place search result.
request.setSiteId("THE_SIDE_ID")
//Set the language (optional).
request.setLanguage("fr")
//Create a results listener.
val resultListener = object : SearchResultListener<DetailSearchResponse>() {
override fun onSearchResult(result: DetailSearchResponse?) {
//Detail search succeeded.
if (result == null) {
//Something weird happened. Return.
return
}
//Retrieve the site. Return if null.
val site = result.site ?: return
//Retrieve various details about the site and display
//for the user.
}
override fun onSearchError(status: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
}
//Initiate the request.
searchService.detailSearch(request, resultListener)
Place Search Suggestion
This feature is similar to the Keyword and Nearby Search features, except that it returns a limited set of results. It's more suitable for rapid-fire requests, such as real-time search suggestions.
Here's an example for how to implement it.
Code:
/Create the search service. It's recommended you use an Activity
//Context, although it's not required.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
val searchService = SearchServiceFactory.create(context, "API_KEY")
//Create the request.
val request = QuerySuggestionRequest()
//Set the user's current query.
request.setQuery("Pari")
//Set a location (optional).
val location = Coordinate(48.893478, 2.334595)
request.setLocation(location)
//Set a radius in meters (optional) (from 1-50,000).
//Default is 50,000.
request.setRadius(50)
//Set the search country (optional).
request.setCountryCode("FR")
//Set the language results should appear in
//(optional).
request.setLanguage("fr")
//Set a specific POI type (optional). Should
//be a subset of the values found in LocationType.
request.setPoiTypes(LocationType.ADDRESS)
//Create a results listener.
val resultListener = object : SearchResultListener<QuerySuggestionResponse>() {
override fun onSearchResult(result: QuerySuggestionResponse?) {
if (result == null) {
//No results. Return.
return
}
val sites: List<Site>? = result.sites
if (sites.isNullOrEmpty()) {
//No sites. Return.
return
}
//Handle results.
sites.forEach { site ->
val id = site.sideId
val name = site.name
}
}
override fun onSearchError(status: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
}
//Initiate the search request.
searchServie.querySuggestion(request, resultListener)
Widget
The Site Kit can take care of search logic for you, including suggestions. Here's how.
The first thing you need to do is implement the Fragment in your layout.
XML:
<fragment
android:id="@+id/search_fragment"
android_name="com.huawei.hms.site.widget.SearchFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
You can also create a reference in code and use a FragmentManager to add and remove it as needed.
Next, you need to implement the search functionality.
Code:
//Get a reference to the Fragment. This example assumes it's
//in your layout XML.
val searchFragment = supportFragmentManager.findFragmentById(R.id.search_fragment) as SearchFragment
//Set the API key.
//You can find your API key on the Project Setting page for your
//project in AppGallery Connect, under App Information.
searchFragment.setApiKey("API_KEY")
//Set a selection listener.
searchFragment.setOnSiteSelectedListener(object : SiteSelectionListener() {
override fun onSiteSelected(site: Site) {
//The user has selected a site returned by HMS.
//Handle as applicable.
}
override fun onError(status: SearchStatus) {
//There was an error retrieving results.
val code = status.errorCode
val message = status.errorMessage
}
})
Conclusion
That's it! As you can probably see, HMS Site Kit makes it pretty easy to implement location searching in your app.
This is only for devices that come with HMS pre-installed, but it's certainly a useful set of tools. Be sure to check out Huawei's full documentation for more details.
If we briefly talk about what HMS Site Kit is, you can provide users to explore the world faster with Site Kit. You can search for locations by keywords, find places which are close to the specified coordinate point, get detailed information about a place and get suggestions for places by keyword.
We can get detailed information about a place with Place Detail Search, another feature of Site Kit. The only condition for this, we need to know Site model’s id value that belongs to the place we want to search.
Before I explain the use of Place Detail Search, I would like to share with you a function that we can use this feature.
Code:
fun placeDetail(siteId: String){
val searchService = SearchServiceFactory.create(context,
URLEncoder.encode(
"Your-API-KEY",
"utf-8"))
var request = DetailSearchRequest()
request.siteId = siteId
request.language = Locale.getDefault().language // Getting system language
searchService.detailSearch(request, object: SearchResultListener<DetailSearchResponse>{
override fun onSearchError(searchStatus: SearchStatus?) {
Log.e("SITE_KIT","${searchStatus?.errorCode} - ${searchStatus?.errorMessage}")
}
override fun onSearchResult(detailSearchResponse: DetailSearchResponse?) {
var site = detailSearchResponse?.site
site?.let {
Log.i("SITE_KIT", "Name => ${it.name}," +
"Format address => ${it.formatAddress}, " +
"Coordinate => ${it.location.lat} - ${it.location.lng}, " +
"Phone => ${it.poi.phone}, " +
"Photo URLS => ${it.poi.photoUrls}, " +
"Rating => ${it.poi.rating}, " +
"Address Detail => ${it.address.thoroughfare}, ${it.address.subLocality}, " +
"${it.address.locality}, ${it.address.adminArea}, ${it.address.country}")
} ?: kotlin.run {
Log.e("SITE_KIT","Site Place couldn't find with the given site ID")
}
}
})
}
First, we need to create a SearchService object from the SearchServiceFactory class. For this, we can use the create() method of the SearchServiceFactory class. We need to declare two parameters in create() method.
The first of these parameters is context value. It is recommended that Context value should be in Activity type. Otherwise, when HMS Core(APK) needs to be updated, we can not receive any notification about it.
The second parameter is API Key value that we can access via AppGallery Connect. This value is generated automatically by AppGallery Connect when a new app is created. We need to encode API parameter as encodeURI.
After creating our SearchService object as I described above, we can create a DetailSearchRequest object. We will specify the necessary parameters on this object related to the place which we want want to get information.
After creating our DetailSearchRequest object, we can determine parameters for a place that we want to get information. Two parameters are specified here:
SiteId: There is a unique id value for each Site in Site Kit. This parameter is used to specify the id value of the place whose information is to be obtained.
Language: It is used to specify the language that search results have to be returned. If this parameter is not specified, language of the query field we have specified in the query field is accepted by default. In example code snippet in above, language of device has been added automatically in order to get a healthy result.
After entering the id value and language parameter of the place that we want to learn in detail, we can start learning the details. For this, we will use detailSearch() method of the SearchService object. This method takes two parameters.
For the first parameter, we must specify DetailSearchRequest object we have defined above.
For the second parameter, we have to implement SearchResultListener interface. Since this interface has a generic structure, we need to specify class belonging to the values to be returned. We can get the incoming values by specifying DetailSearchResponse object. Two methods should be override with this interface. onSearchError() method is executed if operation fails, and onSearchResult() method is executed if operations is successful. There is one value in DetailSearchResponse. This value is Site object that belongs to the id value. With the Site variable of DetailSearchResponse object, we can access information belong to place we have searched.
sujith.e said:
Hi,Why API key is required?
Click to expand...
Click to collapse
API key is a simple credential for accessing Huawei services. Your API key is creating automatically on the AppGallery Connect when you create an application, and then your app can use the key to call public APIs provided by Huawei.
When an app calls a public API provided by Huawei, we should give this information to API to help Huawei to identify our application.
More information like this, you can visit HUAWEI Developer Forum
What is SafetyDetect?
SafetyDetect is an API or Kits that provide security checks to your application. This will help to protect your app against security threats or malicious programs.
The kits consists of 5 main APIs:
SysIntegrity API: Checks whether the device running your app is secure, for example, whether it is rooted.
AppsCheck API: Obtains a list of malicious apps.
URLCheck API: Determines the threat type of a specific URL.
UserDetect API: Checks whether your app is interacting with a fake user.
WifiDetect API: Checks whether the Wi-Fi to be connected is secure.
Why SafetyDetect?
Why do you want to use safetydetect?
Imagine that if your app deals with sensitive data and/or provide transactional capabilities, you would not want your app security to be compromised.
SafetyDetect will provide the security (device, url, apps, wifi) to your app so that you can ensure that your app and data is not compromised when infected device access your apps.
Using SysIntegrity API
To use SysIntegrity API, there are only a few simple steps.
First, add the required app gallery plugin and safety detect dependency to your build.gradle
Project build.gradle:
Code:
dependencies {
implementation 'com.huawei.hms:safetydetect:{version}'
}
Module build.gradle:
Code:
implementation 'com.huawei.hms:safetydetect:5.0.1.300'
Next, to call the API you will need to generate a nonce value, this value must be at least 16 bytes and is only valid once. This value will be returned also within the SafetyDetect response, so you can use this value to check the validity of the Response.
A nonce can be the app username appended with the timestamp of the request, or any unique value of the application.
Code:
fun invokeSysIntegrityCheck() {
val mClient = SafetyDetect.getClient(this)
val nonce = "This Is Just A Test Nonce".toByteArray(Charsets.UTF_8)
val task = mClient.sysIntegrity(nonce, "your app id")
task.addOnSuccessListener {res ->
// sys integrity call success, result is returned
val result = res.result
}.addOnFailureListener {
// something went wrong, please check your app id and if you have enabled the safety detect api in developer console
it.printStackTrace()
}
}
The result of the check is returned in a json format, sample is below:
Code:
{
"advice":"RESTORE_TO_FACTORY_ROM",
"apkCertificateDigestSha256":[
"yT5JtXRgeIgXssx1gQTsMA9GzM9ER4xAgCsCC69Fz3I="
],
"apkDigestSha256":"6Ihk8Wcv1MLm0O5KUCEVYCI/0KWzAHn9DyN38R3WYu8=",
"apkPackageName":"com.huawei.hms.safetydetectsample",
"basicIntegrity":false,
"nonce":"R2Rra24fVm5xa2Mg",
"timestampMs":1571708929141
}
If the basicIntegrity parameter is false, the user device is at risk. You can choose to notify the user or block the access of the app if you think it’s necessary.
Using AppsCheck API
AppsCheck api is a service where it will detect if any malicious apps are installed on the device. The signature of this malicious apps is stored in the cloud and is periodically updated.
Code:
fun invokeAppsCheck() {
val mClient = SafetyDetect.getClient(this)
val task = mClient.maliciousAppsList
task.addOnSuccessListener {
// service call is successful. we will need to check the app lsit response to see if there is any malicious app installed
val appDataList = it.maliciousAppsList
if (it.rtnCode == CommonCode.OK) {
if (appDataList.isEmpty()){
// malicious apps list is empty, device is safe.
}
else {
// malicious apps is detected on the device
appDataList.forEach {
Log.w("warn", "Malicious app detected: ${it.apkCategory}, ${it.apkPackageName}, ${it.apkSha256}")
}
}
}
}.addOnFailureListener {
// something went wrong
}
}
Using URLCheck API
URLCheck is a service which allows the app to check a particular URL for malicious URL. This is very useful for app that re-directs the user to a lot of other 3rd party URL, such as barcode scanner.
To use URL Check Api:
Code:
fun doUrlCheck(url: String) {
val mClient = SafetyDetect.getClient(this)
// Check the URL
// Param1: URL To be checked
// Param2: your Huawei App ID
// Param3&4: Types of threat to be checked
mClient.urlCheck(url, "your app id here",
UrlCheckThreat.MALWARE,
UrlCheckThreat.PHISHING)
.addOnSuccessListener {
if (it.urlCheckResponse.isEmpty()) {
// No threat or phishing detected
} else {
// Threat detected
}
}
}
So there we have it. Safety Detect is really useful to secure your apps from threats when user is using the app.
For more information, please see the developer link:
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050156325