Cordova HMS Location Kit | Installation and Example - Huawei Developers

More information like this, you can visit HUAWEI Developer Forum​
Introduction
This article covers, how to integrate Cordova Hms Location Kit to a Cordova application.
Cordova Hms Location Kit supports services listed below
"); background-size: 1px 1px; background-position: 0px calc(1em + 1px);">Fused Location Service
"); background-size: 1px 1px; background-position: 0px calc(1em + 1px);">Activity Identification Service
"); background-size: 1px 1px; background-position: 0px calc(1em + 1px);">Geofence Service
There are several number of uses cases of these services, you can combine them or just use them to create different functionalities in your app. For basic understanding, please read uses cases from "); background-size: 1px 1px; background-position: 0px calc(1em + 1px); box-sizing: inherit; font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif; font-weight: 700; font-size: 18px; text-decoration: underline;">here.
Prerequisites
Step 1
Prepare your development environment using this "); background-size: 1px 1px; background-position: 0px calc(1em + 1px); box-sizing: inherit; font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif; font-weight: 700; font-size: 18px; text-decoration: underline;">guide.
After reading this guide you should have Cordova Development Environment setted up, Hms Core (APK) installed and Android Sdk installed.
Step 2
Configure your app information in App Gallery by following "); background-size: 1px 1px; background-position: 0px calc(1em + 1px); box-sizing: inherit; font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif; font-weight: 700; font-size: 18px; text-decoration: underline;">this guide.
After reading this guide you should have a Huawei Developer Account, an App Gallery app, a keystore file and enabled Location kit service from AppGallery.
Integrating Cordova Hms Location Kit
To download or use HUAWEI Location Kit, you must agree to "); background-size: 1px 1px; background-position: 0px calc(1em + 1px); font-size: 18px; text-decoration: underline;">Huawei Developer Service Agreement, "); background-size: 1px 1px; background-position: 0px calc(1em + 1px); font-size: 18px; text-decoration: underline;">HUAWEI APIs Use Agreement, and "); background-size: 1px 1px; background-position: 0px calc(1em + 1px); font-size: 18px; text-decoration: underline;">AppGallery Connect Data Processing Addendum. You understand and undertake that downloading or using said HUAWEI Location Kit shall be deemed that you have agreed to all the preceding agreements, and you will fulfill and assume the legal responsibilities and obligations in accordance with said agreements.
Warning : Please make sure that, prerequisites part successfully completed.
Step 1
Add Android platform to your project if you haven’t yet.
Code:
cordova platform add android
Step 2
Check Cordova requirements with following command.
Code:
cordova requirements
Step 3
You can either install the plugin thorough npm or by downloading from downloads page, "); background-size: 1px 1px; background-position: 0px calc(1em + 1px);">Cordova Location Plugin.
Run the following command in the root directory of your Cordova project to install it through npm.
Code:
cordova plugin add @hms-core/cordova-plugin-hms-location
Run the following command in the root directory of your Cordova project to install it manually after downloading the plugin.
Step 4
Check whether the Cordova Location Plugin is successfully added to “plugins” folder in the root directory of the Cordova project.
{
"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"
}
Step 5
Open build.gradle file in project-dir > android folder.
Go to buildscript > repositories and allprojects > repositories, and configure the Maven repository address.
Code:
buildscript {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
Go to buildscript > dependencies and add dependency configurations.
Code:
buildscript {
dependencies {
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
}
Step 6
Open build.gradle file which is located under project.dir > android > app directory.
Add the AppGallery Connect plug-in dependency to the file header.
Code:
apply plugin: 'com.huawei.agconnect'
The apply plugin: ‘com.huawei.agconnect’ configuration must be added after the apply plugin: ‘com.android.application’ configuration.
The minimum Android API level (minSdkVersion) required for Location Kit is 19.
Configure build dependencies of your project.
Code:
dependencies {
...
implementation 'com.huawei.agconnect:agconnect-core:1.0.0.301'
}
Create An Application for Cordova Location Kit
In the application we will do, the user will be able to view his/him last location and receive a notification when he/she leaves the area he/she has determined.
So, we need to initialize HMSFusedLocation, HMSLocationKit, HMSGeofence services in onCreate method.
Step 1
Code:
function onDeviceReady() {
// Initialize LocationKit
HMSLocationKit.init();
HMSFusedLocation.init();
HMSGeofence.init();
// Device ready effect
var parentElement = $('deviceready');
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
};
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.
Note That : Before running this code snippet please check for your app permissions.
Step 2
Code:
$('requestPermission').onclick = async () => {
try {
const permissionResult = await HMSFusedLocation.requestPermission();
console.log({permissionResult});
$('requestPermissionResult').innerHTML = JSON.stringify(permissionResult, null, 1);
} catch (ex) {
$('requestPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('hasPermission').onclick = async () => {
try {
const hasPermissionResult = await HMSFusedLocation.hasPermission();
console.log({hasPermissionResult});
$('hasPermissionResult').innerHTML = JSON.stringify(hasPermissionResult, null, 1);
} catch (ex) {
$('hasPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
Step 3
Code:
const $ = (x) => document.getElementById(x);
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
// Initialize LocationKit
HMSLocationKit.init();
HMSFusedLocation.init();
HMSGeofence.init();
// Device ready effect
var parentElement = $('deviceready');
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
};
const newLocationRequest = () => { return {
id: "locationRequest" + Math.random() * 10000,
priority:
HMSFusedLocation.PriorityConstants.PRIORITY_HIGH_ACCURACY,
interval: 3,
numUpdates: 1,
fastestInterval: 1000.0,
expirationTime: 1000.0,
expirationTimeDuration: 1000.0,
smallestDisplacement: 0.0,
maxWaitTime: 1000.0,
needAddress: false,
language: "en",
countryCode: "en",
}};
$('getLastLocation').onclick = async () => {
try {
const lastLocation = await HMSFusedLocation.getLastLocation();
console.log({lastLocation});
$('getLastLocationResult').innerHTML = JSON.stringify(lastLocation, null, 1);
} catch (ex) {
$('getLastLocationResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('requestPermission').onclick = async () => {
try {
const permissionResult = await HMSFusedLocation.requestPermission();
console.log({permissionResult});
$('requestPermissionResult').innerHTML = JSON.stringify(permissionResult, null, 1);
} catch (ex) {
$('requestPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('hasPermission').onclick = async () => {
try {
const hasPermissionResult = await HMSFusedLocation.hasPermission();
console.log({hasPermissionResult});
$('hasPermissionResult').innerHTML = JSON.stringify(hasPermissionResult, null, 1);
} catch (ex) {
$('hasPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('getLocationAvailability').onclick = async () => {
try {
const locationAvailability = await HMSFusedLocation.getLocationAvailability();
console.log({locationAvailability});
$('getLocationAvailabilityResult').innerHTML = JSON.stringify(locationAvailability, null, 1);
} catch (ex) {
$('getLocationAvailabilityResult').innerHTML = JSON.stringify(locationAvailability, null, 1);
}
};
$('getLastLocationWithAddress').onclick = async () => {
try {
const getLastLocationWithAddressResult = await HMSFusedLocation.getLastLocationWithAddress(newLocationRequest());
console.log({getLastLocationWithAddressResult});
$('getLastLocationWithAddressResult').innerHTML = JSON.stringify(getLastLocationWithAddressResult, null, 1);
} catch (ex) {
$('getLastLocationWithAddressResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('createGeofenceList').onclick = async () => {
const geofence1 = {
longitude: 29.117645,
latitude: 41.012429,
radius: 2.0,
uniqueId: 'geofence' + Math.random() * 10000,
conversions: 1,
validContinueTime: 10000.0,
dwellDelayTime: 10,
notificationInterval: 1,
};
const geofence2 = {
longitude: 41.0,
latitude: 27.0,
radius: 340.0,
uniqueId: 'geofence' + Math.random() * 10000,
conversions: 2,
validContinueTime: 1000.0,
dwellDelayTime: 10,
notificationInterval: 1,
};
try {
const createGeofenceListResult = await HMSGeofence.createGeofenceList(
[geofence1],
HMSGeofence.GeofenceRequestConstants.ENTER_INIT_CONVERSION,
HMSGeofence.GeofenceRequestConstants.COORDINATE_TYPE_WGS_84
);
console.log({createGeofenceListResult});
$('createGeofenceListResult').innerHTML = JSON.stringify(createGeofenceListResult, null, 1);
} catch (ex) {
$('createGeofenceListResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('registerGeofenceUpdates').onclick = async () => {
registerHMSEvent(HMSGeofence.Events.GEOFENCE_RESULT, (result) => {
console.log('new geofence update');
$('geofenceUpdateResult').innerHTML = JSON.stringify(result, null, 1);
});
};
Test the Location Kit App
Run the application.
Code:
cordova run android
Press “Get Last Location” button.
Wait for the result.
Here it comes. You will see your last location on screen.
Conclusion
In this article, we integrated and used Cordova Hms Location Kit to our application. You can enrich your application by integrating this useful and simple to use kit into your applications.
Leave your comment if you have any question about this.

Related

Cordova HMS Location Kit | Installation and Example

{
"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"
}
Introduction
This article covers, how to integrate Cordova Hms Location Kit to a Cordova application.
Cordova Hms Location Kit supports services listed below
Fused Location Service
Activity Identification Service
Geofence Service
There are several number of uses cases of these services, you can combine them or just use them to create different functionalities in your app. For basic understanding, please read uses cases from here.
Prerequisites
Step 1
Prepare your development environment using this guide.
After reading this guide you should have Cordova Development Environment setted up, Hms Core (APK) installed and Android Sdk installed.
Step 2
Configure your app information in App Gallery by following this guide.
After reading this guide you should have a Huawei Developer Account, an App Gallery app, a keystore file and enabled Location kit service from AppGallery.
Integrating Cordova Hms Location Kit
To download or use HUAWEI Location Kit, you must agree to Huawei Developer Service Agreement, HUAWEI APIs Use Agreement, and AppGallery Connect Data Processing Addendum. You understand and undertake that downloading or using said HUAWEI Location Kit shall be deemed that you have agreed to all the preceding agreements, and you will fulfill and assume the legal responsibilities and obligations in accordance with said agreements.
Warning : Please make sure that, prerequisites part successfully completed.
Step 1
Add Android platform to your project if you haven’t yet.
Code:
cordova platform add android
Step 2
Check Cordova requirements with following command.
Code:
cordova requirements
Step 3
You can either install the plugin thorough npm or by downloading from downloads page, Cordova Location Plugin. Run the following command in the root directory of your Cordova project to install it through npm.
Code:
cordova plugin add @hms-core/cordova-plugin-hms-location
Run the following command in the root directory of your Cordova project to install it manually after downloading the plugin.
Code:
cordova plugin add <CORDOVA_PLUGIN_PATH>
Step 4
Check whether the Cordova Location Plugin is successfully added to “plugins” folder in the root directory of the Cordova project.
Step 5
Open build.gradle file in project-dir > android folder.
Go to buildscript > repositories and allprojects > repositories, and configure the Maven repository address.
Code:
buildscript {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
Go to buildscript > dependencies and add dependency configurations.
Code:
buildscript {
dependencies {
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
}
Step 6
Open build.gradle file which is located under project.dir > android > app directory.
Add the AppGallery Connect plug-in dependency to the file header.
The apply plugin: ‘com.huawei.agconnect’ configuration must be added after the apply plugin: ‘com.android.application’ configuration.
The minimum Android API level (minSdkVersion) required for Location Kit is 19.
Configure build dependencies of your project.
Code:
dependencies {
...
implementation 'com.huawei.agconnect:agconnect-core:1.0.0.301'
}
Create An Application for Cordova Location Kit
In the application we will do, the user will be able to view his/him last location and receive a notification when he/she leaves the area he/she has determined.
So, we need to initialize HMSFusedLocation, HMSLocationKit, HMSGeofence services in onCreate method.
Step 1
Code:
function onDeviceReady() {
// Initialize LocationKit
HMSLocationKit.init();
HMSFusedLocation.init();
HMSGeofence.init();
// Device ready effect
var parentElement = $('deviceready');
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
};
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.
Note That : Before running this code snippet please check for your app permissions.
Step 2
Code:
$('requestPermission').onclick = async () => {
try {
const permissionResult = await HMSFusedLocation.requestPermission();
console.log({permissionResult});
$('requestPermissionResult').innerHTML = JSON.stringify(permissionResult, null, 1);
} catch (ex) {
$('requestPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('hasPermission').onclick = async () => {
try {
const hasPermissionResult = await HMSFusedLocation.hasPermission();
console.log({hasPermissionResult});
$('hasPermissionResult').innerHTML = JSON.stringify(hasPermissionResult, null, 1);
} catch (ex) {
$('hasPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
Step 3
Code:
const $ = (x) => document.getElementById(x);
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
// Initialize LocationKit
HMSLocationKit.init();
HMSFusedLocation.init();
HMSGeofence.init();
// Device ready effect
var parentElement = $('deviceready');
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
};
const newLocationRequest = () => { return {
id: "locationRequest" + Math.random() * 10000,
priority:
HMSFusedLocation.PriorityConstants.PRIORITY_HIGH_ACCURACY,
interval: 3,
numUpdates: 1,
fastestInterval: 1000.0,
expirationTime: 1000.0,
expirationTimeDuration: 1000.0,
smallestDisplacement: 0.0,
maxWaitTime: 1000.0,
needAddress: false,
language: "en",
countryCode: "en",
}};
$('getLastLocation').onclick = async () => {
try {
const lastLocation = await HMSFusedLocation.getLastLocation();
console.log({lastLocation});
$('getLastLocationResult').innerHTML = JSON.stringify(lastLocation, null, 1);
} catch (ex) {
$('getLastLocationResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('requestPermission').onclick = async () => {
try {
const permissionResult = await HMSFusedLocation.requestPermission();
console.log({permissionResult});
$('requestPermissionResult').innerHTML = JSON.stringify(permissionResult, null, 1);
} catch (ex) {
$('requestPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('hasPermission').onclick = async () => {
try {
const hasPermissionResult = await HMSFusedLocation.hasPermission();
console.log({hasPermissionResult});
$('hasPermissionResult').innerHTML = JSON.stringify(hasPermissionResult, null, 1);
} catch (ex) {
$('hasPermissionResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('getLocationAvailability').onclick = async () => {
try {
const locationAvailability = await HMSFusedLocation.getLocationAvailability();
console.log({locationAvailability});
$('getLocationAvailabilityResult').innerHTML = JSON.stringify(locationAvailability, null, 1);
} catch (ex) {
$('getLocationAvailabilityResult').innerHTML = JSON.stringify(locationAvailability, null, 1);
}
};
$('getLastLocationWithAddress').onclick = async () => {
try {
const getLastLocationWithAddressResult = await HMSFusedLocation.getLastLocationWithAddress(newLocationRequest());
console.log({getLastLocationWithAddressResult});
$('getLastLocationWithAddressResult').innerHTML = JSON.stringify(getLastLocationWithAddressResult, null, 1);
} catch (ex) {
$('getLastLocationWithAddressResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('createGeofenceList').onclick = async () => {
const geofence1 = {
longitude: 29.117645,
latitude: 41.012429,
radius: 2.0,
uniqueId: 'geofence' + Math.random() * 10000,
conversions: 1,
validContinueTime: 10000.0,
dwellDelayTime: 10,
notificationInterval: 1,
};
const geofence2 = {
longitude: 41.0,
latitude: 27.0,
radius: 340.0,
uniqueId: 'geofence' + Math.random() * 10000,
conversions: 2,
validContinueTime: 1000.0,
dwellDelayTime: 10,
notificationInterval: 1,
};
try {
const createGeofenceListResult = await HMSGeofence.createGeofenceList(
[geofence1],
HMSGeofence.GeofenceRequestConstants.ENTER_INIT_CONVERSION,
HMSGeofence.GeofenceRequestConstants.COORDINATE_TYPE_WGS_84
);
console.log({createGeofenceListResult});
$('createGeofenceListResult').innerHTML = JSON.stringify(createGeofenceListResult, null, 1);
} catch (ex) {
$('createGeofenceListResult').innerHTML = JSON.stringify(ex, null, 1);
}
};
$('registerGeofenceUpdates').onclick = async () => {
registerHMSEvent(HMSGeofence.Events.GEOFENCE_RESULT, (result) => {
console.log('new geofence update');
$('geofenceUpdateResult').innerHTML = JSON.stringify(result, null, 1);
});
};
Test the Location Kit App
Run the application.
Code:
cordova run android
Press “Get Last Location” button.
Wait for the result.
Here it comes. You will see your last location on screen.
Conclusion
In this article, we integrated and used Cordova Hms Location Kit to our application. You can enrich your application by integrating this useful and simple to use kit into your applications.
You can write comments for your questions.
Related Links
Thanks to Furkan Aybastı for this article.

Geofencing using Huawei Map, Location and Site Kits for Flutter

In this article, I am going to use 3 Huawei kits in one project:
· Map Kit, for personalizing how your map displays and interact with your users, also making location-based services work better for your users.
· Location Kit, for getting the user’s current location with fused location function, also creating geofences.
· Site Kit, for searching and exploring the nearby places with their addresses.
What is a Geo-fence?
Geofence literally means a virtual border around a geographic area. Geofencing technology is the name of the technology used to trigger an automatic alert when an active device enters a defined geographic area (geofence).
As technology developed, brands started to reach customers. Of course, at this point, with digital developments, multiple new marketing terms started to emerge. Geofencing, a new term that emerged with this development, entered the lives of marketers.
Project Setup
HMS Integration
Firstly, you need a Huawei Developer account and add an app in Projects in AppGallery Connect console. So that you can activate the Map, Location and Site kits and use them in your app. If you don’t have an Huawei Developer account and don’t know the steps please follow the links below.
· Register Huawei developer website
· Configuring app information in AppGallery Connect
· Integrating Map Kit Flutter Plugin
· Integrating Location Kit Flutter Plugin
· Integrating Site Kit Flutter Plugin
Important: While adding app, the package name you enter should be the same as your Flutter project’s package name.
Note: Before you install agconnect-services.json file, make sure the required kits are enabled.
Permissions
In order to make your kits work perfectly, you need to add the permissions below in AndroidManifest.xml file.
Code:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Creating Flutter Application
Add Dependencies to ‘pubspec.yaml’
After completing all the steps above, 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. You can follow the steps in installing section of the following links.
· Map Kit Plugin for Flutter
· Location Kit Plugin for Flutter
· Site Kit Plugin for Flutter
Code:
dependencies:
flutter:
sdk: flutter
huawei_location: ^5.0.0+301
huawei_site: ^5.0.1+300
huawei_map: ^4.0.4+300
After adding them, run flutter pub get command.
All the plugins are ready to use!
Request Location Permission and Get Current Location
Create a PermissionHandler instance and initialize it in initState to ask for permission. Also, follow the same steps for FusedLocationProviderClient. With locationService object, we can get the user’s current location by calling getLastLocation() method.
Code:
LatLng center;
PermissionHandler permissionHandler;
FusedLocationProviderClient locationService;
@override
void initState() {
permissionHandler = PermissionHandler();
locationService = FusedLocationProviderClient();
getCurrentLatLng();
super.initState();
}
getCurrentLatLng() async {
await requestPermission();
Location currentLocation = await locationService.getLastLocation();
LatLng latLng = LatLng(currentLocation.latitude, currentLocation.longitude);
setState(() {
center = latLng;
});
}
In requestPermission() method, you can find both Location Permission and Background Location Permission.
Code:
requestPermission() async {
bool hasPermission = await permissionHandler.hasLocationPermission();
if (!hasPermission) {
try {
bool status = await permissionHandler.requestLocationPermission();
print("Is permission granted $status");
} catch (e) {
print(e.toString());
}
}
bool backgroundPermission =
await permissionHandler.hasBackgroundLocationPermission();
if (!backgroundPermission) {
try {
bool backStatus =
await permissionHandler.requestBackgroundLocationPermission();
print("Is background permission granted $backStatus");
} catch (e) {
print(e.toString);
}
}
}
When you launch the app for the first time, the location permission screen will appear.
{
"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"
}
Add HuaweiMap
Huawei Map is the main layout of this project. It will cover all the screen and also we will add some buttons on it, so we should put HuaweiMap and other widgets into a Stack widget. Do not forget to create a Huawei map controller.
Code:
static const double _zoom = 16;
Set<Marker> _markers = {};
int _markerId = 1;
Set<Circle> _circles = {};
int _circleId = 1;
_onMapCreated(HuaweiMapController controller) {
mapController = controller;
}
Stack(
fit: StackFit.expand,
children: <Widget>[
HuaweiMap(
onMapCreated: _onMapCreated,
initialCameraPosition:
CameraPosition(target: center, zoom: _zoom),
mapType: MapType.normal,
onClick: (LatLng latLng) {
placeSearch(latLng);
selectedCoordinates = latLng;
_getScreenCoordinates(latLng);
setState(() {
clicked = true;
addMarker(latLng);
addCircle(latLng);
});
},
markers: _markers,
circles: _circles,
tiltGesturesEnabled: true,
buildingsEnabled: true,
compassEnabled: true,
zoomControlsEnabled: true,
rotateGesturesEnabled: true,
myLocationButtonEnabled: true,
myLocationEnabled: true,
trafficEnabled: false,
),
],
)
We have got the current location with Location service’s getLastLocation() method and assigned it to center variables as longitude and latitude. While creating the HuaweiMap widget, assign that center variable to HuaweiMap’s target property, so that the app opens with a map showing the user’s current location.
Code:
placeSearch(LatLng latLng) async {
NearbySearchRequest request = NearbySearchRequest();
request.location = Coordinate(lat: latLng.lat, lng: latLng.lng);
request.language = "en";
request.poiType = LocationType.ADDRESS;
request.pageIndex = 1;
request.pageSize = 1;
request.radius = 100;
NearbySearchResponse response = await searchService.nearbySearch(request);
try {
print(response.sites);
site = response.sites[0];
} catch (e) {
print(e.toString());
}
}
When onClick method of HuaweiMap is triggered, call placeSearch using the Site Kit’s nearbySearch method. Thus, you will get a Site object to assign to the new geofence you will add.
Create Geofence
When the user touch somewhere on the map; a marker, a circle around the marker, a Slider widget to adjust the radius of the circle, and a button named “Add Geofence” will show up on the screen. So we will use a boolean variable called clicked and if it’s true, the widgets I have mentioned in the last sentence will be shown.
Code:
addMarker(LatLng latLng) {
if (marker != null) marker = null;
marker = Marker(
markerId: MarkerId(_markerId.toString()), //_markerId is set to 1
position: latLng,
clickable: true,
icon: BitmapDescriptor.defaultMarker,
);
setState(() {
_markers.add(marker);
});
selectedCoordinates = latLng;
_markerId++; //after a new marker is added, increase _markerId for the next marker
}
_drawCircle(Geofence geofence) {
this.geofence = geofence;
if (circle != null) circle = null;
circle = Circle(
circleId: CircleId(_circleId.toString()),
fillColor: Colors.grey[400],
strokeColor: Colors.red,
center: selectedCoordinates,
clickable: false,
radius: radius,
);
setState(() {
_circles.add(circle);
});
_circleId++;
}
Create a Slider widget wrapped with a Positioned widget and put them into Stack widget as shown below.
Code:
if (clicked)
Positioned(
bottom: 10,
right: 10,
left: 10,
child: Slider(
min: 50,
max: 200,
value: radius,
onChanged: (newValue) {
setState(() {
radius = newValue;
_drawCircle(geofence);
});
},
),
),
After implementing addMarker and drawCircle methods and adding Slider widget, now we will create AddGeofence Screen and it will appear as a ModalBottomSheet when AddGeofence button is clicked.
Code:
RaisedButton(
child: Text("Add Geofence"),
onPressed: () async {
geofence.uniqueId = _fenceId.toString();
geofence.radius = radius;
geofence.latitude = selectedCoordinates.lat;
geofence.longitude = selectedCoordinates.lng;
_fenceId++;
final clickValue = await showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: AddGeofenceScreen(
geofence: geofence,
site: site,
),
),
),
);
updateClicked(clickValue);
//When ModalBottomSheet is closed, pass a bool value in Navigator
//like Navigator.pop(context, false) so that clicked variable will be
//updated in home screen with updateClicked method.
},
),
void updateClicked(bool newValue) {
setState(() {
clicked = newValue;
});
}
In the new stateful AddGeofenceScreen widget’s state class, create GeofenceService and SearchService instances and initialize them in initState.
Code:
GeofenceService geofenceService;
int selectedConType = Geofence.GEOFENCE_NEVER_EXPIRE;
SearchService searchService;
@override
void initState() {
geofenceService = GeofenceService();
searchService = SearchService();
super.initState();
}
To monitor address, radius and also to select conversion type of the geofence, we will show a ModalBottomSheet with the widgets shown below.
Code:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
"Address",
style: boldStyle,
),
Text(site.formatAddress),
Text(
"\nRadius",
style: boldStyle,
),
Text(geofence.radius.toInt().toString()),
Text(
"\nSelect Conversion Type",
style: boldStyle,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
RadioListTile<int>(
dense: true,
title: Text(
"Enter",
style: TextStyle(fontSize: 14),
),
value: Geofence.ENTER_GEOFENCE_CONVERSION,
groupValue: selectedConType,
onChanged: (int value) {
setState(() {
selectedConType = value;
});
},
),
RadioListTile<int>(
dense: true,
title: Text("Exit"),
value: Geofence.EXIT_GEOFENCE_CONVERSION,
groupValue: selectedConType,
onChanged: (int value) {
setState(() {
selectedConType = value;
});
},
),
RadioListTile<int>(
dense: true,
title: Text("Stay"),
value: Geofence.DWELL_GEOFENCE_CONVERSION,
groupValue: selectedConType,
onChanged: (int value) {
setState(() {
selectedConType = value;
});
},
),
RadioListTile<int>(
dense: true,
title: Text("Never Expire"),
value: Geofence.GEOFENCE_NEVER_EXPIRE,
groupValue: selectedConType,
onChanged: (int value) {
setState(() {
selectedConType = value;
});
},
),
],
),
Align(
alignment: Alignment.bottomRight,
child: FlatButton(
child: Text(
"SAVE",
style: TextStyle(
color: Colors.blue, fontWeight: FontWeight.bold),
),
onPressed: () {
geofence.conversions = selectedConType;
addGeofence(geofence);
Navigator.pop(context, false);
},
),
)
],
),
For each conversion type, add a RadioListTile widget.
When you click SAVE button, addGeofence method will be called to add new Geofence to the list of Geofences, then return to the Home screen with false value to update clicked variable.
In addGeofence, do not forget to call createGeofenceList method with the list you have just added the geofence in.
Code:
void addGeofence(Geofence geofence) {
geofence.dwellDelayTime = 10000;
geofence.notificationInterval = 100;
geofenceList.add(geofence);
GeofenceRequest geofenceRequest = GeofenceRequest(geofenceList:
geofenceList);
try {
int requestCode = await geofenceService.createGeofenceList
(geofenceRequest);
print(requestCode);
} catch (e) {
print(e.toString());
}
}
To listen to the geofence events, you need to use onGeofenceData method in your code.
Code:
GeofenceService geofenceService;
StreamSubscription<GeofenceData> geofenceStreamSub;
@override
void initState() {
geofenceService = GeofenceService();
geofenceStreamSub = geofenceService.onGeofenceData.listen((data) {
infoText = data.toString(); //you can use this infoText to show a toast message to the user.
print(data.toString);
});
super.initState();
}
Search Nearby Places
In home screen, place a button onto the map to search nearby places with a keyword and when it is clicked a new alertDialog page will show up.
Code:
void _showAlertDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Search Location"),
content: Container(
height: 150,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TextField(
controller: searchQueryController,
),
MaterialButton(
color: Colors.blue,
child: Text(
"Search",
style: TextStyle(color: Colors.white),
),
onPressed: () async {
Navigator.pop(context);
_markers =
await nearbySearch(center, searchQueryController.text);
setState(() {});
},
)
],
),
),
actions: [
FlatButton(
child: Text("Close"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
},
);
}
After you enter the keyword and click Search button, there will be markers related to the keyword will appear on the map.
Conclusion
In this article you have learnt how to use some of the features of Huawei Map, Location and Site kits in your projects. Also, you have learnt the geofencing concept. Now you can add geofences to your app and with geofencing, you can define an audience based on a customer’s behavior in a specific location. With location information, you can show suitable ads to the right people simultaneously, wherever they are.
Thank you for reading this article, I hope it was useful and you enjoyed it!
Huawei is the best Android smartphone devices making company. I don't know why Android creating a so much of issues. I feel bad
Can we show GIF image on huawei map at predefined locaation?

Intermediate: How to Integrate Huawei Analytics kit in Flutter (Cross platform)

{
"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"
}
Introduction
Flutter Analytics Plugin provides wider range of predefined analytics models to get more insight into your application users, products, and content. With this insight, you can prepare data-driven approach to market your apps and optimize your products based on the analytics.
With Analytics Kit's on-device data collection SDK, you can:
Collect and report custom events.
Set a maximum of 25 user attributes.
Automate event collection and session calculation.
Pre-set event IDs and parameters.
Restrictions
1. Devices:
a. Analytics Kit depends on HMS Core (APK) to automatically collect the following events: INSTALLAPP (app installation), UNINSTALLAPP (app uninstallation), CLEARNOTIFICATION (data deletion), INAPPPURCHASE (in-app purchase), RequestAd (ad request), DisplayAd (ad display), ClickAd (ad tapping), ObtainAdAward (ad award claiming), SIGNIN (sign-in), and SIGNOUT (sign-out). These events cannot be automatically collected on third-party devices where HMS Core (APK) is not installed (including but not limited to OPPO, vivo, Xiaomi, Samsung, and OnePlus).
b. Analytics Kit does not work on iOS devices.
2. Number of events:
A maximum of 500 events are supported.
3. Number of event parameters:
You can define a maximum of 25 parameters for each event, and a maximum of 100 event parameters for each project.
4. Supported countries/regions
The service is now available only in the countries/regions listed in Supported Countries/Regions.
Integration process
1. Create flutter project
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle
Java:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Add root level gradle dependencies
Java:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Add app level gradle dependencies
Java:
implementation 'com.huawei.hms:hianalytics:5.1.0.300'
Step 3: Add the below permissions in Android Manifest file.
XML:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
Step 4: Flutter plugin for Huawei analytics kit.
Unzip downloaded plugin in the parent directory of the project.
Step 5: Declare plugin path in pubspec.yaml file under dependencies.
Step 5 : Create a project in AppGallery Connect.
pubspec.yaml
YAML:
<p style="margin-top: 20.0px;white-space: normal;">name: flutter_app
</p><p style="margin-top: 20.0px;white-space: normal;">description: A new Flutter application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_analytics:
path: ../huawei_analytics/
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# The following section is specific to Flutter.
flutter:</p>
main.dart
Code:
import 'package:flutter/material.dart';
import 'package:flutter_app/result.dart';
import 'package:huawei_analytics/huawei_analytics.dart';
import './quiz.dart';
import './result.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
int _totalScore = 0;
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
_enableLog();
_predefinedEvent();
super.initState();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("TestUser123");
await _hmsAnalytics.enableLog();
}
void _restartQuiz() {
setState(() {
_questionIndex = 0;
_totalScore = 0;
});
}
void _predefinedEvent() async {
String name = HAEventType.SIGNIN;
dynamic value = {HAParamType.ENTRY: 06534797};
await _hmsAnalytics.onEvent(name, value);
print("Event posted");
}
void _customEvent(int index, int score) async {
String name = "Question$index";
dynamic value = {'Score': score};
await _hmsAnalytics.onEvent(name, value);
print("Event posted");
}
static const _questions = [
{
'questionText': 'What\'s you favorite color?',
'answers': [
{'text': 'Black', 'Score': 10},
{'text': 'White', 'Score': 1},
{'text': 'Green', 'Score': 3},
{'text': 'Red', 'Score': 5},
]
},
{
'questionText': 'What\'s your favorite place?',
'answers': [
{'text': 'India', 'Score': 1},
{'text': 'Rassia', 'Score': 5},
{'text': 'US', 'Score': 4},
{'text': 'Singapore', 'Score': 7},
]
},
{
'questionText': 'What\'s your childwood nick name?',
'answers': [
{'text': 'Bunty', 'Score': 2},
{'text': 'Binto', 'Score': 1},
{'text': 'Tom', 'Score': 5},
{'text': 'Ruby', 'Score': 3},
]
},
{
'questionText': 'What\'s your favorite subject?',
'answers': [
{'text': 'Math', 'Score': 5},
{'text': 'Physics', 'Score': 1},
{'text': 'Chemistry', 'Score': 3},
{'text': 'Biology', 'Score': 2},
]
}
];
Future<void> _answerQuestion(int score) async {
_totalScore += score;
if (_questionIndex < _questions.length) {
print('Iside if $_questionIndex');
setState(() {
_questionIndex = _questionIndex + 1;
});
print('Current questionIndex $_questionIndex');
} else {
print('Inside else $_questionIndex');
}
_customEvent(_questionIndex, score);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('QuizApp'),
),
body: _questionIndex < _questions.length
? Quiz(
answerQuestion: _answerQuestion,
questionIndex: _questionIndex,
questions: _questions,
)
: Result(_totalScore, _restartQuiz),
));
}
}
question.dart
Code:
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(30.0),
child: Text(
questionText,
style: TextStyle(
fontSize: 28,
),
textAlign: TextAlign.center,
),
);
}
}
answer.dart
Code:
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function selectHandler;
final String answerText;
Answer(this.selectHandler, this.answerText);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: RaisedButton(
child: Text(answerText),
color: Colors.blue,
textColor: Colors.white,
onPressed: selectHandler,
),
);
}
}
quiz.dart
Code:
import 'package:flutter/material.dart';
import './answer.dart';
import './question.dart';
class Quiz extends StatelessWidget {
final List<Map<String, Object>> questions;
final int questionIndex;
final Function answerQuestion;
Quiz({
@required this.answerQuestion,
@required this.questions,
@required this.questionIndex,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Question(
questions[questionIndex]['questionText'],
),
...(questions[questionIndex]['answers'] as List<Map<String, Object>>)
.map((answer) {
return Answer(() => answerQuestion(answer['Score']), answer['text']);
}).toList()
],
);
}
}
result.dart
Code:
import 'package:flutter/material.dart';
class Result extends StatelessWidget {
final int resulScore;
final Function restarthandler;
Result(this.resulScore, this.restarthandler);
String get resultPhrase {
String resultText;
if (resulScore <= 8) {
resultText = 'You are awesome and innocent!.';
} else if (resulScore <= 12) {
resultText = 'Pretty likable!.';
} else if (resulScore <= 12) {
resultText = 'You are .. strange!.';
} else {
resultText = 'You are so bad!';
}
return resultText;
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Text(
resultPhrase,
style: TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
FlatButton(
child: Text('Restart again', style: TextStyle(fontSize: 22)),
textColor: Colors.blue,
onPressed: restarthandler,
),
],
),
);
}
}
Result
Tricks and Tips
Make sure that downloaded plugin is added in specified directory.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in Ag-connect.
Enable debug mode using following command
Code:
adb shell setprop debug.huawei.hms.analytics.app package_name
Conclusion
In this article, we have learnt how to integrate Huawei Analytics Kit into Flutter QuizApp, which lets you to app analytics like users, predefined events and Custom events in the Ag-connect.
Thank you so much for reading, I hope this article helps you to understand the Huawei Analytics Kit in flutter.
Reference
Official plugin guide for flutter :
Document
developer.huawei.com
Flutter plugin :
Document
developer.huawei.com
HMS Core :
Document
developer.huawei.com
Read In Forum
Does it supports real time analytics?

Intermediate: Integration of Huawei map kit and Location kit in DeliveryApp in Flutter (Cross platform)

Introduction​In this article, we will be integrating Huawei Map kit and Location kit in Food Delivery application. Huawei Map kit currently allows developer to create map, interactions with map and drawing on a map.
We will be covering all three aspects as the delivery application we need to create map and we need to draw polyline from delivery agent location to user location and on interaction also we are providing i.e. on click the marker we are show popup on the map with details as shown in the result section below.
Development Overview​You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements​
A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements​
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process​Step 1. Create flutter project
{
"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"
}
Step 2. Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.​
Code:
apply plugin:'com.huawei.agconnect'
Add root level gradle dependencies.
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Add app level gradle dependencies.
Code:
implementation 'com.huawei.hms:maps:5.0.3.302'
implementation 'com.huawei.hms:location:5.0.0.301'
Step 3: Add the below permissions in Android Manifest file.
Code:
<uses-permission android:name="android.permission.INTERNET " />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION"/>
Step 4: Add below path in pubspec.yaml file under dependencies.
Step 5 : Create a project in AppGallery Connect.​pubspec.yaml​
Code:
name: sample_one
description: A new Flutter application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_map:
path: ../huawei_map/
huawei_location:
path: ../huawei_location/
http: ^0.12.2
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
How to check required permissions are granted or not?​
Code:
void hasPermission() async {
try {
bool status = await permissionHandler.hasLocationPermission();
setState(() {
message = "Has permission: $status";
if (status) {
getLastLocationWithAddress();
//requestLocationUpdatesByCallback();
} else {
requestPermission();
}
});
} catch (e) {
setState(() {
message = e.toString();
});
}
}
How do I request permission?​
Code:
void requestPermission() async {
try {
bool status = await permissionHandler.requestLocationPermission();
setState(() {
message = "Is permission granted $status";
});
} catch (e) {
setState(() {
message = e.toString();
});
}
}
How do I get location data?​
Code:
void getLastLocationWithAddress() async {
try {
HWLocation location =
await locationService.getLastLocationWithAddress(locationRequest);
setState(() {
message = location.street +
" " +
location.city +
" " +
location.state +
" " +
location.countryName +
" " +
location.postalCode;
print("Location: " + message);
});
} catch (e) {
setState(() {
message = e.toString();
print(message);
});
}
}
main.dart​
Code:
import 'package:flutter/material.dart';
import 'package:huawei_map/map.dart';
import 'package:sample_one/mapscreen2.dart';
import 'package:sample_one/order.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Orders'),
),
body: MyApp(),
),
debugShowCheckedModeBanner: false,
);
}
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List orders = [
Order(
imageUrl:
"https://www.namesnack.com/images/namesnack-pizza-business-names-5184x3456-20200915.jpeg",
name: "Veg Pizza Special",
username: "Naresh K",
location: new LatLng(12.9698, 77.7500)),
Order(
imageUrl:
"https://www.pizzahutcouponcode.com/wp-content/uploads/2020/12/10.jpg",
name: "Pretzel Rolls ",
username: "Ramesh",
location: new LatLng(12.9698, 77.7500)),
Order(
imageUrl:
"https://www.manusmenu.com/wp-content/uploads/2015/01/1-Chicken-Spring-Rolls-9-1-of-1.jpg",
name: "Special Veg Rolls",
username: "Mahesh N",
location: new LatLng(12.9598, 77.7540)),
Order(
imageUrl:
"https://www.thespruceeats.com/thmb/axBJnjZ_30_-iHgjGzP1tS4ssGA=/4494x2528/smart/filters:no_upscale()/thai-fresh-rolls-with-vegetarian-option-3217706_form-rolls-step-07-f2d1c96942b04dd0830026702e697f17.jpg",
name: "The Great Wall of China",
username: "Chinmay M",
location: new LatLng(12.9098, 77.7550)),
Order(
imageUrl:
"https://cdn.leitesculinaria.com/wp-content/uploads/2021/02/pretzel-rolls-fp.jpg.optimal.jpg",
name: "Pretzel Rolls",
username: "Ramesh",
location: new LatLng(12.9658, 77.7400)),
Order(
imageUrl:
"https://dinnerthendessert.com/wp-content/uploads/2019/01/Egg-Rolls-3.jpg",
name: "Egg Rolls",
username: "Preeti",
location: new LatLng(12.9618, 77.7700)),
Order(
imageUrl:
"https://images.immediate.co.uk/production/volatile/sites/30/2020/08/recipe-image-legacy-id-1081476_12-9367fea.jpg",
name: "Easy Spring Rolls",
username: "Nithin ",
location: new LatLng(12.9218, 77.7100)),
];
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white60,
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 1),
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: ListView.builder(
itemCount: orders.length,
itemBuilder: (context, index) {
return ListTile(
leading: Image.network(orders[index].imageUrl),
title: Text(orders[index].name),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => MapPage(
orders[index].name, orders[index].location)));
},
subtitle: Text(orders[index].username),
);
},
),
),
],
),
),
),
);
}
}
mapscreen.dart​
Code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:huawei_map/map.dart';
import 'package:sample_one/directionapiutil.dart';
import 'package:sample_one/routerequest.dart';
import 'package:sample_one/routeresponse.dart';
class MapPage extends StatefulWidget {
String name;
LatLng location;
MapPage(this.name, this.location);
@override
_MapPageState createState() => _MapPageState(name, location);
}
class _MapPageState extends State<MapPage> {
String name, dist = '';
LatLng location, dest_location = new LatLng(12.9709, 77.7257);
_MapPageState(this.name, this.location);
HuaweiMapController _mapController;
final Set<Marker> _markers = {};
final Set<Polyline> _polyLines = {};
final List<LatLng> _points = [];
BitmapDescriptor _markerIcon;
List<LatLng> polyList = [
LatLng(12.9970, 77.6690),
LatLng(12.9569, 77.7011),
LatLng(12.9177, 77.6238)
];
@override
void initState() {
super.initState();
_loadMarkers(location);
showDirection();
}
@override
Widget build(BuildContext context) {
//_customMarker(context);
return new Scaffold(
appBar: null,
body: Stack(
children: [
_buildMap(),
Positioned(
top: 10,
right: 40,
left: 40,
child: ButtonBar(
buttonPadding: EdgeInsets.all(15),
alignment: MainAxisAlignment.center,
children: <Widget>[
/* new RaisedButton(
onPressed: showDirection,
child: new Text("Show direction",
style: TextStyle(fontSize: 20.0)),
color: Colors.green,
),*/
Center(
child: new Text(
"$dist",
style:
TextStyle(fontSize: 20.0, backgroundColor: Colors.cyan),
),
),
/* new RaisedButton(
onPressed: _showPolygone,
child: new Text("Polygon",
style: TextStyle(fontSize: 20.0, color: Colors.white)),
color: Colors.lightBlueAccent,
),*/
],
),
)
],
),
);
}
_buildMap() {
return HuaweiMap(
initialCameraPosition: CameraPosition(
target: location,
zoom: 12.0,
bearing: 30,
),
onMapCreated: (HuaweiMapController controller) {
_mapController = controller;
},
mapType: MapType.normal,
tiltGesturesEnabled: true,
buildingsEnabled: true,
compassEnabled: true,
zoomControlsEnabled: true,
rotateGesturesEnabled: true,
myLocationButtonEnabled: true,
myLocationEnabled: true,
trafficEnabled: true,
markers: _markers,
polylines: _polyLines,
onClick: (LatLng latlong) {
setState(() {
//createMarker(latlong);
});
},
);
}
void showRouteBetweenSourceAndDestination(
LatLng sourceLocation, LatLng destinationLocation) async {
RouteRequest request = RouteRequest(
origin: LocationModel(
lat: sourceLocation.lat,
lng: sourceLocation.lng,
),
destination: LocationModel(
lat: destinationLocation.lat,
lng: destinationLocation.lng,
),
);
try {
RouteResponse response = await DirectionUtils.getDirections(request);
setState(() {
drawRoute(response);
dist = response.routes[0].paths[0].distanceText;
});
} catch (Exception) {
print('Exception: Failed to load direction response');
}
}
drawRoute(RouteResponse response) {
if (_polyLines.isNotEmpty) _polyLines.clear();
if (_points.isNotEmpty) _points.clear();
var steps = response.routes[0].paths[0].steps;
for (int i = 0; i < steps.length; i++) {
for (int j = 0; j < steps[i].polyline.length; j++) {
_points.add(steps[i].polyline[j].toLatLng());
}
}
setState(() {
_polyLines.add(
Polyline(
width: 2,
polylineId: PolylineId("route"),
points: _points,
color: Colors.blueGrey),
);
/*for (int i = 0; i < _points.length - 1; i++) {
totalDistance = totalDistance +
calculateDistance(
_points[i].lat,
_points[i].lng,
_points[i + 1].lat,
_points[i + 1].lng,
);
}*/
});
}
void _loadMarkers(LatLng location) {
if (_markers.length > 0) {
setState(() {
_markers.clear();
});
} else {
setState(() {
_markers.add(Marker(
markerId: MarkerId('marker_id_1'),
position: location,
icon: _markerIcon,
infoWindow: InfoWindow(
title: 'Delivery agent',
snippet: 'location',
),
rotation: 5));
_markers.add(Marker(
markerId: MarkerId('marker_id_2'),
position: dest_location,
draggable: true,
icon: _markerIcon,
clickable: true,
infoWindow: InfoWindow(
title: 'User',
snippet: 'location',
),
rotation: 5));
});
}
}
void _customMarker(BuildContext context) async {
if (_markerIcon == null) {
final ImageConfiguration imageConfiguration =
createLocalImageConfiguration(context);
BitmapDescriptor.fromAssetImage(
imageConfiguration, 'assets/images/icon.png')
.then(_updateBitmap);
}
}
void _updateBitmap(BitmapDescriptor bitmap) {
setState(() {
_markerIcon = bitmap;
});
}
void createMarker(LatLng latLng) {
Marker marker;
marker = new Marker(
markerId: MarkerId('Welcome'),
position: LatLng(latLng.lat, latLng.lng),
icon: BitmapDescriptor.defaultMarker);
setState(() {
_markers.add(marker);
});
}
void remove() {
setState(() {
_markers.clear();
});
}
showDirection() {
Future.delayed(const Duration(seconds: 1), () {
//setState(() {
showRouteBetweenSourceAndDestination(location, dest_location);
//});
});
}
}
Result​
Tips and Tricks
Make sure you have downloaded latest plugin.
Make sure that updated plugin path in yaml.
Make sure that plugin unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added build file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in Ag-connect.
Conclusion​In this article, we have learnt how to integrate Huawei Map kit and Location kit in Flutter for the DeliveryApp, where application gets the list of orders and delivery agent click on the order to navigate to map. Similar way you can use Huawei Map kit as per user requirement in your application.
Thank you so much for reading, I hope this article helps you to understand the Huawei Map kit and Location kit in flutter.
References​Flutter map
Flutter plugin
Location Kit
Original Source
What are all the different types of maps it will supports?
can we implement start navigation feature like google map feature?

Using Huawei Cloud Functions as Chatbot Service in Flutter ChatBotApp Part-2

{
"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"
}
Introduction
In this article, we will learn how to use Huawei Cloud Functions service as Chatbot service in ChatBotApp in flutter. Cloud Functions enables serverless computing.
It provides the Function as a Service (FaaS) capabilities to simplify app development and O&M by splitting service logic into functions and offers the Cloud Functions SDK that works with Cloud DB and Cloud Storage so that your app functions can be implemented more easily. Cloud Functions automatically scales in or out functions based on actual traffic, freeing you from server resource management and helping you reduce costs.
Key Functions
Key Concepts
How the Service Works
To use Cloud Functions, you need to develop cloud functions that can implement certain service functions in AppGallery Connect and add triggers for them, for example, HTTP triggers for HTTP requests, and Cloud DB triggers for data deletion or insertion requests after Cloud DB is integrated. After your app that integrates the Cloud Functions SDK meets conditions of specific function triggers, your app can call the cloud functions, which greatly facilitates service function building.
Platform Support
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
Android phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1: Create Flutter project.
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.
[/B][/B]
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
[B][B]
Root level gradle dependencies
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
Step 3: Add the below permissions in Android Manifest file.
<uses-permission android:name="android.permission.INTERNET" />
Step 4: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.
Add path location for asset image.
Prevoius article
Using Huawei Cloud Functions as Chatbot Service in Flutter ChatBotApp Part-1
Let's start coding
main.dart
[/B]
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ChatBotService',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'ChatBotService'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isLoggedIn = false;
String str = 'Login required';
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
List<String> gridItems = ['Email Service', 'Call Center', 'FAQ', 'Chat Now'];
@override
void initState() {
_enableLog();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Visibility(
visible: true,
child: Card(
child: Padding(
padding: EdgeInsets.all(20),
child: Text(
str,
style: const TextStyle(color: Colors.teal, fontSize: 22),
),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (!isLoggedIn) {
setState(() {
isLoggedIn = true;
signInWithHuaweiID();
});
print('$isLoggedIn');
} else {
setState(() {
isLoggedIn = false;
signOutWithID();
});
print('$isLoggedIn');
}
},
tooltip: 'Login/Logout',
child: isLoggedIn ? const Icon(Icons.logout) : const Icon(Icons.login),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void signInWithHuaweiID() async {
try {
// The sign-in is successful, and the user's ID information and authorization code are obtained.
Future<AuthAccount> account = AccountAuthService.signIn();
account.then(
(value) => setLoginSuccess(value),
);
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("ChatBotServiceApp");
await _hmsAnalytics.enableLog();
}
void setLoginSuccess(AuthAccount value) {
setState(() {
str = 'Welcome ' + value.displayName.toString();
});
showToast(value.displayName.toString());
print('Login Success');
}
Future<void> signOutWithID() async {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
setState(() {
str = 'Login required';
showToast('You are logged out.');
});
}
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast(String name) async {
Fluttertoast.showToast(
msg: "$name",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
}
[B]
ChatPage.dart
[/B][/B]
class ChatPage extends StatefulWidget {
const ChatPage({Key? key}) : super(key: key);
@override
_ChatPageState createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
List<types.Message> _messages = [];
final _user = const types.User(id: '06c33e8b-e835-4736-80f4-63f44b66666c');
final _bot = const types.User(id: '06c33e8b-e835-4736-80f4-63f54b66666c');
void _addMessage(types.Message message) {
setState(() {
_messages.insert(0, message);
});
}
void _handleSendPressed(types.PartialText message) {
final textMessage = types.TextMessage(
author: _user,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: message.text,
);
_addMessage(textMessage);
callCloudFunction2(message.text);
}
void _loadMessages() async {
final response = await rootBundle.loadString('assets/messages.json');
final messages = (jsonDecode(response) as List)
.map((e) => types.Message.fromJson(e as Map<String, dynamic>))
.toList();
setState(() {
_messages = messages;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Chat(
messages: _messages,
onAttachmentPressed: null,
onMessageTap: null,
onPreviewDataFetched: null,
onSendPressed: _handleSendPressed,
user: _user,
),
);
}
Future<void> callCloudFunction2(String msg) async {
try {
RequestData data = RequestData(msg);
List<Map<String, Object>> params = <Map<String, Object>>[data.toMap()];
var input = data.toMap();
FunctionCallable functionCallable =
FunctionCallable('test-funnel-\$latest');
FunctionResult functionResult = await functionCallable.call(input);
print("Input " + input.toString());
var result = functionResult.getValue();
final textMessage = types.TextMessage(
author: _bot,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: jsonDecode(result)['response'].toString(),
);
_addMessage(textMessage);
} on PlatformException catch (e) {
print(e.message);
}
}
}
[B][B]
handler.js
[/B][/B][/B]
let myHandler = function(event, context, callback, logger) {
try {
var _body = JSON.parse(event.body);
var reqData = _body.message;
var test = '';
if(reqData == '1'){
test = "Thank you for choosing, you will get callback in 10 min.";
}else if(reqData == '2'){
test = "Please click on the link https://feedback.com/myfeedback";
}else if(reqData == '3'){
test = "Please click on the link https://huawei.com/faq";
}
else if(reqData == 'Hi'){
test = " Welcome to ChatBot Service.";
}else{
test = "Enter 1. For call back. 2. For send feedback. 3. For FAQ ";
}
let res = new context.HTTPResponse({"response": test}, {
"res-type": "simple example",
"faas-content-type": "json"
}, "application/json", "200");
callback(res);
} catch (error) {
let res = new context.HTTPResponse({"response": error}, {
"res-type": "simple example",
"faas-content-type": "json"
}, "application/json", "300");
callback(res);
}
};
module.exports.myHandler = myHandler;
[B][B][B]
Result
Tricks and Tips
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Conclusion
In this article, we have learnt how to integrate Huawei Account kit, analytics kit and ChatBot function using Cloud Functions in flutter ChatBotApp. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.
Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Account kit, Analytics kit and Huawei Cloud Functions in flutter ChatBotApp.
Reference
Cloud Functions
Training Videos
Checkout in forum

Categories

Resources