Connecting to Wifi with Huawei Scan Kit
{
"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"
}
This article is about connecting to the wireless network with the Huawei scan kit.
Huawei Scan Kit Integration
Configure app information in AppGallery Connect
Integrate the HMS Core SDK
Assign permissions
Connecting to Wifi with Huawei Scan Kit
Code:
<!--Camera permission-->
<uses-permission android:name="android.permission.CAMERA" />
<!--Network permission-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Dynamically request the permissions in the MainActivity.java file
Code:
private fun requestPermission(requestCode: Int) {
ActivityCompat.requestPermissions (
this,
arrayOf(Manifest.permission.CAMERA, Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.CHANGE_NETWORK_STATE),
requestCode)
}
Code:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray){
if (grantResults.size < 5 || permissions == null || grantResults == null || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "missing permission", Toast.LENGTH_LONG).show()
return
}
if (requestCode == REQUEST_WIFI) {
val options = HmsScanAnalyzerOptions
.Creator()
.setHmsScanTypes(HmsScan.WIFI_CONNECT_INFO_FORM, HmsScan.DATAMATRIX_SCAN_TYPE)
.create()
ScanUtil.startScan(this,
REQUEST_CODE_WIFI_INFORMATION, options)
}
}
You can use the link for more detail about required permissions.
In line 12, scan process starts. HmsScanType value must set WIFI_CONNECT_INFO_FORM for getting information of wifi.
HmsScan.WiFiConnectionInfo
Sample barcode value is as follows.
Original value : WIFI:S:WIFI_123;T:WPA;P:12345678;;
Wi-Fi SSID : WIFI_123
Wi-Fi Password : 12345678
Wi-Fi encryption type : WPA
Data need to be parsed in onActivityResult to get password and ssid.
Code:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (data != null) {
when (resultCode) {
Activity.RESULT_OK -> {
if (requestCode == REQUEST_CODE_WIFI_INFORMATION) {
val result : HmsScan? = data.getParcelableExtra(ScanUtil.RESULT)
val wifiConnectionInfo = result?.let { getWifiInformation(it) }
wifiConnectionInfo?.let { connectToWifi(it) }
}
}
}
}
}
Code:
private fun getWifiInformation(result : HmsScan): HmsScan.WiFiConnectionInfo? {
return when(null == result || null == result.wiFiConnectionInfo == null) {
true -> null
false -> {
result.wiFiConnectionInfo
}
}
}
You can use the android.net library to connect to wifi using the password and ssid.
Code:
private fun connectToWifi(wifiConnectionInfo : HmsScan.WiFiConnectionInfo) {
if(wifiConnectionInfo == null){
Toast.makeText(this, "wifi information could not found", Toast.LENGTH_LONG).show()
return
}
if(wifiConnectionInfo.password.isBlank() || wifiConnectionInfo.password.isBlank()) {
Toast.makeText(this, "incorrect password or connection name", Toast.LENGTH_LONG).show()
return
}
val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val wifiNetworkSpecifier = createWifiNetworkSpecifier(wifiConnectionInfo)
val networkRequest = createNetworkRequest(wifiNetworkSpecifier)
val networkCallback = createNetworkCallback()
networkRequest?.let { connectivityManager.requestNetwork(it, networkCallback) }
}
The first step is to create a WifiNetworkSpecifier with the ssid and password obtained from the barcode.
Code:
private fun createWifiNetworkSpecifier(wifiConnectionInfo: HmsScan.WiFiConnectionInfo): WifiNetworkSpecifier {
return WifiNetworkSpecifier
.Builder()
.setSsid(wifiConnectionInfo.ssidNumber)
.setWpa2Passphrase(wifiConnectionInfo.password)
.build()
}
The second step is to create a NetworkRequest with the wifiNetworkSpecifier created in the previous step.
Code:
private fun createNetworkRequest(wifiNetworkSpecifier : WifiNetworkSpecifier): NetworkRequest? {
return NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build()
}
NetworkCallback is base class for NetworkRequest. Used for notifications about network changes. Should be extended by applications wanting notifications.
Code:
private fun createNetworkCallback(): ConnectivityManager.NetworkCallback {
return object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.i("ConnectToNetwork", "network is available")
}
override fun onUnavailable() {
Log.e("ConnectToNetwork", "network is unavailable")
}
}
}
If a network matching the ssid is found, the connect to wireless network option will be shown. After clicking connect button, If the password is correct, it will be successfully connected to the network.
Following alert will be shown, if a network matching the ssid cannot be found.
Use Cases
Sharing wifi with customers in the cafe and restaurant.
Sharing wifi with passengers in public transportation
Conclusion
I hope this article helps you better understand the usage scenarios of the Huawei scanning kit.
Thanks for reading. If you have question, don’t hesitate to contact me.
References:https://github.com/HMS-Core/hms-scan-demo
https://developer.android.com/reference/android/net/package-summary
developer.huawei.com
Click to expand...
Click to collapse
Its very interesting, Thanks for sharing.
sujith.e said:
Its very interesting, Thanks for sharing
Click to expand...
Click to collapse
thanks for your feedback, wish you pleasant reading
can we share files as well?
shikkerimath said:
can we share files as well?
Click to expand...
Click to collapse
codes of the project?
Which API is used for discovering the WIFI device?
does it support wifi direct?
ask011 said:
Which API is used for discovering the WIFI device?
Click to expand...
Click to collapse
android.net library is used at the project.
android.net | Android Developers
developer.android.com
ProManojKumar said:
does it support wifi direct?
Click to expand...
Click to collapse
Scan Kit supports extracting wifi information and returns the information to you but doesn't support discovering wifi direct. Android.net library can be used for it.
Does it detect passwords as well?
if Qr code contains passwords
Basavaraj.navi said:
Does it detect passwords as well?
Click to expand...
Click to collapse
If the QR code contains the password of wifi, the password is detected by the app. Otherwise, the password cannot be detected.
Related
More information like this, you can visit HUAWEI Developer Forum
Introduction
Customers of Huawei maps are people who use maps API like Ecommerce, real estate portals, travel portals etc. and end users who use the Huawei maps application through different devices. End users also experience the maps interface through different search experiences like the local business searches, hotel searches, flight searches.
Let’s Start how to Integrate Map:
Step1: create a new project in Android studio.
Step 2: Configure your app into AGC.
Step 3: Enable required Api & add SHA-256.
Step 4: Download the agconnect-services.json from AGC. Paste into app directory.
Step 5: Add the below dependency in app.gradle file.
Code:
implementation 'com.huawei.hms:maps:4.0.0.301'
implementation 'com.huawei.hms:site:4.0.3.300'
Step 6: Add the below dependency in root.gradle file
Code:
maven { url 'http://developer.huawei.com/repo/' }
Step 7: Add appId & permissions in AndoridManifest.xml file
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="appid=*********" />
Step 8: Sync your Project
Use Cases:
Huawei site kit supports below capabilities.
· Keyword Search: It will display list based on user input.
· Nearby Place Search: It will display nearby places based on the current location of the user's device.
· Place Detail Search: Searches for details about a place.
· Place Search Suggestion: Returns a list of suggested places.
Let’s Discuss how to integrate Site Kit:
Declare SearchService create Instance for SearchService.
Code:
SearchService searchService = SearchServiceFactory.create(this,URLEncoder.encode("API_KEY", "utf-8"));
Create TextSearchRequest, which is the place to search request. below are the parameters.
query: search keyword.
location: longitude and latitude to which search results need to be biased.
radius: search radius, in meters. The value ranges from 1 to 50000. The default value is 50000.
poiType: POI type. The value range is the same as that of LocationType.
HwPoiType: Huawei POI type. his parameter is recommended. The value range is the same as that of HwLocationType.
countrycode: code of the country where places are searched. The country code must comply with the ISO 3166-1 alpha-2 standard.
language: language in which search results are displayed. For details about the value range, please refer to language codes in LanguageMapping
If this parameter is not passed, the language of the query field is used in priority. If the field language is unavailable, the local language will be used.
pageSize: number of records on each page. The value ranges from 1 to 20. The default value is 20.
pageIndex: current page number. The value ranges from 1 to 60. The default value is 1.
Code:
autoCompleteTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (timer != null) {
timer.cancel();
}
}
@Override
public void afterTextChanged(final Editable text) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (text.length() > 3) {
list.clear();
final TextSearchRequest textSearchRequest = new TextSearchRequest();
textSearchRequest.setQuery(text.toString());
searchService.textSearch(textSearchRequest, new SearchResultListener<TextSearchResponse>() {
@Override
public void onSearchResult(TextSearchResponse response) {
for (Site site : response.getSites()) {
LatLng latLng = new LatLng(site.getLocation().getLat(), site.getLocation().getLng());
SearchResult searchResult = new SearchResult(latLng, site.getAddress().getLocality(), site.getName());
String result = site.getName() + "," + site.getAddress().getSubAdminArea() + "\n" +
site.getAddress().getAdminArea() + "," +
site.getAddress().getLocality() + "\n" +
site.getAddress().getCountry() + "\n" +
site.getAddress().getPostalCode() + "\n";
list.add(result);
searchList.add(searchResult);
}
mAutoCompleteAdapter.clear();
mAutoCompleteAdapter.addAll(list);
mAutoCompleteAdapter.notifyDataSetChanged();
autoCompleteTextView.setAdapter(mAutoCompleteAdapter);
Toast.makeText(MainActivity.this, String.valueOf(response.getTotalCount()), Toast.LENGTH_SHORT).show();
}
@Override
public void onSearchError(SearchStatus searchStatus) {
Toast.makeText(MainActivity.this, searchStatus.getErrorCode(), Toast.LENGTH_SHORT).show();
}
});
}
}
}, 200);
autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mAutoCompleteAdapter.getItem(position);
selectedPostion = searchList.get(position);
try {
createMarker(new LatLng(selectedPostion.latLng.latitude, selectedPostion.latLng.longitude));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
});
Output:
{
"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"
}
Reference:
https://developer.huawei.com/consumer/en/doc/development/HMS-References/hms-map-cameraupdate
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-introduction-0000001050158571
Introduction
Sound detection service can detect sound events. Automatic environmental sound classification is a growing area of research with real world applications.
Steps
1. Create App in Android
2. Configure App in AGC
3. Integrate the SDK in our new Android project
4. Integrate the dependencies
5. Sync project
Use case
This service we will use in day to day life, it will detect different types of sounds such as Baby crying, laugher, snoring, running water, alarm sounds, doorbell, etc.! Currently this service will detect only one sound at a time, so multiple sound detection is not supporting this service. Default interval at least 2 seconds for each sound detection.
ML Kit Configuration.
1. Login into AppGallery Connect, select MlKitSample in My Project list.
2. Enable Ml Kit, Choose My Projects > Project settings > Manage APIs
Integration
Create Application in Android Studio.
App level gradle dependencies.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Gradle dependencies
Code:
implementation 'com.huawei.hms:ml-speech-semantics-sounddect-sdk:2.0.3.300'
implementation 'com.huawei.hms:ml-speech-semantics-sounddect-model:2.0.3.300'
Root level gradle dependencies
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
Add the below permissions in Android Manifest file
Code:
<manifest xlmns:android...>
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
</manifest>
1. Create Instance for Sound Detection in onCreate.
Code:
MLSoundDector soundDector = MLSoundDector.createSoundDector();
2. Check Run time permissions.
Code:
private void getRuntimePermissions() {
List<String> allNeededPermissions = new ArrayList<>();
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
allNeededPermissions.add(permission);
}
}
if (!allNeededPermissions.isEmpty()) {
ActivityCompat.requestPermissions(
this, allNeededPermissions.toArray(new String[0]), PERMISSION_REQUESTS);
}
}
private boolean allPermissionsGranted() {
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
return false;
}
}
return true;
}
private static boolean isPermissionGranted(Context context, String permission) {
if (ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted: " + permission);
return true;
}
Log.i(TAG, "Permission NOT granted: " + permission);
return false;
}
private String[] getRequiredPermissions() {
try {
PackageInfo info = this.getPackageManager().getPackageInfo(this.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] ps = info.requestedPermissions;
if (ps != null && ps.length > 0) {
return ps;
} else {
return new String[0];
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
return new String[0];
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode != PERMISSION_REQUESTS) {
return;
}
boolean isNeedShowDiag = false;
for (int i = 0; i < permissions.length; i++) {
if ((permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE)
&& grantResults[i] != PackageManager.PERMISSION_GRANTED)
|| (permissions[i].equals(Manifest.permission.CAMERA)
&& permissions[i].equals(Manifest.permission.RECORD_AUDIO)
&& grantResults[i] != PackageManager.PERMISSION_GRANTED)) {
isNeedShowDiag = true;
}
}
if (isNeedShowDiag && !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
AlertDialog dialog = new AlertDialog.Builder(this)
.setMessage(getString(R.string.camera_permission_rationale))
.setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 200);
startActivity(intent);
}
})
.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).create();
dialog.show();
}
}
3. Create sound detection result callback, this callback will detect the sound results.
Code:
MLSoundDectListener listener = new MLSoundDectListener() {
@Override
public void onSoundSuccessResult(Bundle result) {
int soundType = result.getInt(MLSoundDector.RESULTS_RECOGNIZED);
String soundName = hmap.get(soundType);
textView.setText("Successfully sound has been detected : " + soundName);
}
@Override
public void onSoundFailResult(int errCode) {
textView.setText("Failure" + errCode);
}
};
soundDector.setSoundDectListener(listener);
soundDector.start(this);
4. Once sound detection obtained call notification service.
Code:
serviceIntent = new Intent(MainActivity.this, NotificationService.class);
serviceIntent.putExtra("response", soundName);
ContextCompat.startForegroundService(MainActivity.this, serviceIntent);
5. If you want to stop sound detection call onStop()
Code:
soundDector.stop();
6. Below are the sound type results.
{
"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"
}
Result
Conclusion
This article will help you to detect Real time streaming sounds, sound detection service will help you to notify sounds to users in daily life.
Thank you for reading and if you have enjoyed this article, I would suggest you implement this and provide your experience.
Reference
ML Kit – Sound Detection
Refer the URL
Hello everyone, in this story, I will try to show you basic usage of HMS Cloud Db executeUpsert() and executeDelete() functions.
First, please be sure that having a project on cloud db up and running. If it is your first Cloud Db project and don’t know what to do, feel free to visit here.
For our scenario, we will have two tables named BookmarkStatus and LikeStatus. BookmarkStatus and LikeStatus tables holds a record for each user’s bookmark/like for the specified object and deletes the record when user remove his/her like or bookmark.
Let’s start with initializing our cloud db object. I will initialize cloud db object once when application started (in SplashScreen) and use it through the application.
Note : Make sure you have initialized your cloud db object before any of your cloud db operations.
Click to expand...
Click to collapse
Code:
companion object {
fun initDb() {
AGConnectCloudDB.initialize(ContextProvider.getApplicationContext())
}
}
fun dbGetInstance(){
mCloudDb = AGConnectCloudDB.getInstance()
}
Then, create a base viewModel to call certain functions of cloud db instead of calling them in every viewModel.
Code:
open class BaseViewModel : ViewModel() {
var mCloudDbZoneWrapper: CloudDbRepository =
CloudDbRepository()
init {
mCloudDbZoneWrapper.createObjectType()
mCloudDbZoneWrapper.openCloudDbZone()
}
}
Here is what createObjectType() and openCloudDbZone() functions do.
Code:
/*
Create object type
*/
fun createObjectType() {
dbGetInstance()
try {
mCloudDb!!.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())
} catch (exception: AGConnectCloudDBException) {
Log.w("CloudDbRepository", exception.errMsg)
}
}
/*
Following method opens cloud db zone with given configs.
*/
fun openCloudDbZone() {
val mConfig: CloudDBZoneConfig = CloudDBZoneConfig(
"YOUR_CLOUD_DB_NAME", CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC
)
mConfig.persistenceEnabled = true
try {
mCloudDbZone = mCloudDb!!.openCloudDBZone(mConfig, true)
} catch (exception: AGConnectCloudDBException) {
Log.w("CloudDbRepository", exception.errMsg)
}
}
Now we have all settings done. All we need to do is calling executeUpsert() and executeDelete() functions properly in related repositories.
Note: Please make sure that all needed permissions are granted to add or delete to/from table.
Click to expand...
Click to collapse
Code:
private fun bookmarkResult(
snapshot: CloudDBZoneSnapshot<BookmarkStatus>,
bookmark: BookmarkStatus,
triggered: Boolean
) {
val bookmarkStatsCursor: CloudDBZoneObjectList<BookmarkStatus> = snapshot.snapshotObjects
try {
if (bookmarkStatsCursor.hasNext()) {
val bookmarkStats = bookmarkStatsCursor.next()
if (bookmarkStats != null && bookmarkStats.object != null) {
if (triggered) {
//deleteBookmark
val deleteTask = mCloudDBZone.executeDelete(bookmarkStats)
deleteTask.addOnSuccessListener {
Log.w(TAG, "BookmarkDelete success")
bookmarkStatus.postValue(false)
}.addOnFailureListener {
Log.w(TAG, "BookmarkDelete fail" + it.message)
}
} else {
bookmarkStatus.postValue(true)
}
}
} else {
if (triggered) {
//add bookmark
val upsertTask = mCloudDBZone.executeUpsert(bookmark)
upsertTask.addOnSuccessListener {
Log.w(TAG, "BookmarkAdd success")
bookmarkStatus.postValue(true)
}.addOnFailureListener {
Log.w(TAG, "BookmarkDelete fail" + it.message)
}
} else {
bookmarkStatus.postValue(false)
}
}
} catch (exception: Exception) {
}
snapshot.release()
}
In this function, triggered parameter is for if user clicked bookmark button or not if clicked then value is true.
Here is the logic;
If user bookmarked the given object (which is queried in another method and passed as a parameter to this method as snapshot) then bookmarkStatsCursor.hasNext() returns true and if not triggered , this means user bookmarked the object and is trying to display bookmark status and all we need to do is using postValue() of the observable property bookmarkStatus and pass the value as true. Let’s say user has a record on BookmarkStatus table and triggered is true then we can say user is trying to remove bookmark of the object. So we need to use executeDelete(bookmark) to delete bookmark from table. With the help of addOnSuccessListener we will post value as false which means user does not have a bookmark on the given object anymore.
If user does not have a bookmark in given object and triggered is false, this means user did not bookmark object and trying to display bookmark status. We will post value as false. If triggered is true then, user is trying to add bookmark to that object. In this situation, we will add a record to the bookmark table using executeUpsert(bookmark) method.
{
"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"
}
Note that you can use addOnFailureListener to catch errors occurred during adding or deleting functions.
To add or delete records to/from LikeStatus table, you can use same logic with BookmarkStatus table given above.
So, as you can see, it is very simple to implement cloud db in your project and you can apply all CRUD functions simply as demonstrated above
References
https://developer.huawei.com/consum...llery-connect-Guides/agc-clouddb-introduction
Sending SMS with Huawei Scan Kit
{
"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"
}
This article is about sending sms with the Huawei scan kit.
Huawei Scan Kit Integration
Configure app information in AppGallery Connect
Integrate the HMS Core SDK
Assign permissions
Sending SMS with Huawei Scan Kit
Add Required Permissions for Barcode Scanning and sms sending to AndroidManifest.xml
Code:
<!--Camera permission-->
<uses-permission android:name="android.permission.CAMERA"/>
<!--Sms permission-->
<uses-permission android:name="android.permission.SEND_SMS" />
Dynamically request the permissions in the MainActivity.java file
Code:
private fun requestPermission(requestCode: Int) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA, Manifest.permission.SEND_SMS),
requestCode)
}
Code:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray){
if (grantResults.size < 2 || permissions == null || grantResults == null || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "missing permission", Toast.LENGTH_LONG).show()
return
}
if (requestCode == REQUEST_SMS) {
val options = HmsScanAnalyzerOptions
.Creator()
.setHmsScanTypes(HmsScan.SMS_FORM, HmsScan.DATAMATRIX_SCAN_TYPE)
.create()
ScanUtil.startScan(this,
REQUEST_CODE_SMS , options)
}
}
You can use the link for more detail about required permissions.
In line 12, scan process starts. HmsScanType value must set SMS_FORM for sending sms.
Sample barcode value is as follows.
Original value : smsto:18300000000 : Hello World!
Mobile number of an SMS message : 18300000000
SMS message content : Hello World!
Data need to be parsed in onActivityResult to get mobile number and message content.
Code:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (data != null) {
when(resultCode){
Activity.RESULT_OK ->{
if(requestCode == REQUEST_CODE_SMS) {
val result : HmsScan? = data.getParcelableExtra(ScanUtil.RESULT)
val sms = result?.let { getMessage(it) }
sms?.let { sendMessage(it) }
}
}
}
}
}
Code:
private fun getMessage(result : HmsScan): HmsScan.SmsContent? {
return when(result?.smsContent == null) {
true -> null
false -> {
result.smsContent
}
}
}
You can use URI schemes for composing and sending messages.
Code:
private fun sendMessage (smsInfo: HmsScan.SmsContent) {
if(smsInfo == null){
Toast.makeText(this, "sms information could not found", Toast.LENGTH_LONG).show()
return
}
if(smsInfo.getDestPhoneNumber().isBlank() || smsInfo.getMsgContent().isBlank()) {
Toast.makeText(this, "incorrect phone number or message content", Toast.LENGTH_LONG).show()
return
}
val intent = Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", smsInfo.destPhoneNumber, null))
intent.putExtra("sms_body", smsInfo.msgContent)
startActivity(intent)
}
Create an message intent with the sms content and mobile number obtained from the barcode. The correct scheme is “sms” for messaging.
Use Cases
Contact potential customers : You can add a QR code to the your card with the note “Scan this to contact us”. When the QR code is scaned, a pre-written message “I want to get information about your product” may appear.
Subscribe or purchase digital products : You can add a QR code to your web site so that the your product can be purchased using the QR code. When the QR code is scanned, a message that says “I want to buy discount coupon or subscribe your channel” may appear.
Conclusion
I hope this article helps you better understand the Huawei scan kit and its use cases.
Thanks for reading. If you have question, don’t hesitate to contact me.
References:
Scan Kit - Code Scanning Service - HUAWEI Developer
Scan Kit scans and parses all major 1D and 2D barcodes and generates QR codes, helping you quickly build barcode scanning functions into your apps.
developer.huawei.com
List of URI schemes - Wikipedia
en.wikipedia.org
https://github.com/HMS-Core/hms-scan-demo
What is the benefit of this over sending message through device Message app?
ask011 said:
What is the benefit of this over sending message through device Message app?
Click to expand...
Click to collapse
For same operation, message can be sent through device message app or the code can be scaned to automatically open local SMS app and pre-fill the number and message fields.
Since the second method is faster, it is a preferred method today as an SMS marketing strategy.
Currently, AppGallery Connect Auth Service also supports web apps. I have integrated the service by referring to the official documentation. You can also download the sample code for reference. I’ll show you the simple procedure in this post.
Integration Procedure1.Enabling the Service
a) Create a web app in AppGallery Connect.
{
"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) Enable Auth Service.
c) Enable the Anonymous account, Mobile number, and Email address authentication modes.
2. Integrating the AppGallery Connect SDK
a) Add the configuration code to the login.vue file.
b) In Huawei Quick App IDE, open your quick app project, integrate the AppGallery Connect JavaScript SDK to your project, and import the module for Auth Service.
3. Implementing Functions
a) For anonymous accounts:
Add a button for anonymous sign-in to your test app and click the button. The sample code is as follows:
JavaScript:
loginAnonymously() {
console.log("JS-SDK login anonymously!");
agconnect.auth().signInAnonymously().then(user => {
// Sign-in successful.
alert("loginAnonymously successfully");
this.getUserInfo();
}).catch(error => {
// Sign-in error.
alert(error)
});
},
When the anonymous sign-in is successful, a UID is displayed.
b) For mobile phone numbers or email addresses (password mode):
Add a text box for users to input the mobile phone number or email address and a text box for the password input to your test app. Input required information to sign in to the app. The sample code is as follows:
JavaScript:
loginByPwd() {
console.log("JS-SDK auth(): login...")
let credential = null;
if (this.dataForm_sdk.password == '') {
alert("Please typein password!");
return;
}
switch (this.provider) {
case 'phone':
credential = agconnect.auth.PhoneAuthProvider.credentialWithPassword('86', this.dataForm_sdk.account, this.dataForm_sdk.password);
break;
case 'email':
credential = agconnect.auth.EmailAuthProvider.credentialWithVerifyCode(this.dataForm_sdk.account, this.dataForm_sdk.password);
break;
default:
break;
}
if (credential == null) {
console.log("credential null!");
return;
}
agconnect.auth().signIn(credential).then(res => {
alert("Sign-in successful.");
this.getUserInfo();
}).catch(err => {
alert(err);
});
},
c) For mobile phone numbers or email addresses (verification code mode):
Add a text box for users to input the mobile phone number or email address and a button for obtaining a verification code to your test app. Input required information and click the button to obtain the verification code. The sample code is as follows:
JavaScript:
getVerifyCode() {
console.log("request for email verifycode...")
this.dataForm_sdk.verifyCode = '';
switch (this.provider) {
case 'phone':
// Obtain a verification code.
agconnect.auth.PhoneAuthProvider.requestVerifyCode('86', this.dataForm_sdk.account,agconnect.auth.Action.ACTION_REGISTER_LOGIN, 'zh_CN', 90).then(ret => {
alert("Request sent.");
}).catch(error => {
alert("Request failed.");
});
break;
case 'email':
agconnect.auth.EmailAuthProvider.requestVerifyCode(this.dataForm_sdk.account, agconnect.auth.Action.ACTION_REGISTER_LOGIN, 'zh_CN', 120).then(ret => {
// Request sent.
alert("Request successful.");
}).catch(error => {
// Request failed.
alert(error)
});
break;
default:
break;
}
},
Add a button for sign-in using a verification code. The sample code is as follows:
JavaScript:
loginByVerifyCode() {
if (this.dataForm_sdk.verifyCode == '') {
alert("Enter the verification code.");
return;
}
let credential = null;
switch (this.provider) {
case 'phone':
credential = agconnect.auth.PhoneAuthProvider.credentialWithVerifyCode('86', this.dataForm_sdk.account, this.dataForm_sdk.password, this.dataForm_sdk.verifyCode);
break;
case 'email':
credential = agconnect.auth.EmailAuthProvider.credentialWithVerifyCode(this.dataForm_sdk.account, this.dataForm_sdk.password, this.dataForm_sdk.verifyCode);
break;
case 'QQ':
break;
case 'weChat':
break;
default:
break;
}
if (credential == null) {
console.log("credential null!")
return;
}
agconnect.auth().signIn(credential).then(res => {
alert("Sign-in successful.");
this.getUserInfo();
}).catch(err => {
alert(err);
});
},
Summary
AppGallery Connect Auth Service provides quite a lot of authentication modes and the integration is simple to complete.
If you have any other questions, please check the official demo.