Plan Routes to Nearby Places in an App - Huawei Developers

Route planning is a very common thing that all of us do in our daily lives. Route planning in apps allows users to enter a location that they want to go to and then select an appropriate route based on various factors such as the estimated time of arrival (ETA), and is applicable to a wide range of scenarios. In a travel app for example, travelers can select a starting point and destination and then select an appropriate route. In a lifestyle app, users can search for nearby services within the specified scope and then view routes to these service locations. In a delivery app, delivery riders can plan optimal routes to facilitate order pickup and delivery.
So, how do we go about implementing such a useful function in an app? That's exactly what I'm going to introduce to you today. In this article, I'll show you how to use HMS Core Site Kit (place service) and Map Kit (map service) to build the route planning function into an app. First, I will use the place search capability in the place service to build the function of searching for nearby places in a specific geographical area by entering keywords. During actual implementation, you can choose whether to specify a geographical area for place search. Then, I will use the route planning capability in the map service to build the function of planning routes to destination places and showing the planned routes on an in-app map. In order to quickly pinpoint the precise location of a user device, I will use the fused location capability which implements precise positioning by combining GNSS, Wi-Fi, and base station data. In addition, the map service provides map data covering over 200 countries and regions and supports hundreds of languages, helping provide the best user experience possible for users all over the world. On top of this, the map service can plan routes for different modes of transport based on the real-time traffic conditions, and calculate the ETAs of the planned routes.
​Demo​The map service supports three transport modes: driving, cycling, and walking. It can quickly plan several appropriate routes based on the selected transport mode, and show the distances and ETAs of these routes. The figure below shows the route planning effects for different transport modes.
{
"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"
}
Route planning effects for different transport modes
On top of this, the map service allows users to choose the shortest route or fastest route based on the traffic conditions, greatly improving user experience.
Preferred route choosing
Integration Procedure​1. Register as a developer and create an app in AppGallery Connect.
1) Visit AppGallery Connect to register as a developer.
2) Create an app, add the SHA-256 signing certificate fingerprint, enable Map Kit and Site Kit, and download the agconnect-services.json file of your app.
2. Integrate the Map SDK and Site SDK.
1) Copy the agconnect-services.json file to the app's root directory of your project.
Go to allprojects > repositories and configure the Maven repository address for the SDK.
Go to buildscript > repositories and configure the Maven repository address for the SDK.
If you have added the agconnect-services.json file to your app, go to buildscript > dependencies and add the AppGallery Connect plugin configuration.
Code:
buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}
}
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
}
}
2) Add build dependencies in the dependencies block.
Code:
dependencies {
implementation 'com.huawei.hms:maps:{version}'
implementation 'com.huawei.hms:site:{version}'
}
3) Add the following configuration to the file header:
Code:
apply plugin: 'com.huawei.agconnect'
4) Copy your signing certificate file to the app directory of your project, and configure the signing information in android in the build.gradle file.
Code:
signingConfigs {
release {
// Signing certificate.
storeFile file("**.**")
// KeyStore password.
storePassword "******"
// Key alias.
keyAlias "******"
// Key password.
keyPassword "******"
v2SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true
}
debug {
debuggable true
}
}
Main Code and Used Functions​1. Keyword search: Call the keyword search function in the place service to search for places based on entered keywords and display the matched places.
Code:
SearchResultListener<TextSearchResponse> resultListener = new SearchResultListener<TextSearchResponse>() {
// Return search results upon a successful search.
@Override
public void onSearchResult(TextSearchResponse results) {
List<Site> siteList;
if (results == null || results.getTotalCount() <= 0 || (siteList = results.getSites()) == null
|| siteList.size() <= 0) {
resultTextView.setText("Result is Empty!");
return;
}
mFirstAdapter.refresh(siteList);
StringBuilder response = new StringBuilder("\n");
response.append("success\n");
int count = 1;
AddressDetail addressDetail;
Coordinate location;
Poi poi;
CoordinateBounds viewport;
for (Site site : siteList) {
addressDetail = site.getAddress();
location = site.getLocation();
poi = site.getPoi();
viewport = site.getViewport();
response.append(String.format(
"[%s] siteId: '%s', name: %s, formatAddress: %s, country: %s, countryCode: %s, location: %s, poiTypes: %s, viewport is %s \n\n",
"" + (count++), site.getSiteId(), site.getName(), site.getFormatAddress(),
(addressDetail == null ? "" : addressDetail.getCountry()),
(addressDetail == null ? "" : addressDetail.getCountryCode()),
(location == null ? "" : (location.getLat() + "," + location.getLng())),
(poi == null ? "" : Arrays.toString(poi.getPoiTypes())),
(viewport == null ? "" : viewport.getNortheast() + "," + viewport.getSouthwest())));
}
resultTextView.setText(response.toString());
Log.d(TAG, "onTextSearchResult: " + response.toString());
}
// Return the result code and description upon a search exception.
@Override
public void onSearchError(SearchStatus status) {
resultTextView.setText("Error : " + status.getErrorCode() + " " + status.getErrorMessage());
}
};
// Call the place search API.
searchService.textSearch(request, resultListener);
2. Walking route planning: Call the route planning API in the map service to plan walking routes and display the planned routes on a map.
Code:
NetworkRequestManager.getWalkingRoutePlanningResult(latLng1, latLng2,
new NetworkRequestManager.OnNetworkListener() {
@Override
public void requestSuccess(String result) {
generateRoute(result);
}
@Override
public void requestFail(String errorMsg) {
Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("errorMsg", errorMsg);
msg.what = 1;
msg.setData(bundle);
mHandler.sendMessage(msg);
}
});
Conclusion​Route planning is a very useful function for mobile apps in various industries. With this function, mobile apps can provide many useful services for users, thus improving the stickiness of their users.
In this article I demonstrated how integrating Map Kit and Site Kit is an effective way to implement route planning into an app. The whole implementation process is straightforward, empowering developers to implement route planning for their apps with ease.

Related

It’s Show Time App using Huawei Location & Site Kit

More information like this, you can visit HUAWEI Developer Forum​
{
"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"
}
An Idea
The Idea behind creating this article is to showcase the power of Huawei Kits. In this article we are going to combine four kits that is Huawei Auth Service, Account kit, Location kit and Site kit to create a movie booking app. Earlier Sujith has already talked about integrating Huawei Auth Service and Account Kit. Refer his article in order to see our process of integrating both kits.
Introduction
Huawei Location Kit combines the GPS, Wi-Fi, and base station location functionalities into our app to build up global positioning capabilities, allowing us to provide flexible location-based services targeted at users around the globe. Currently, it provides three main capabilities: fused location, activity identification, and geofence.
With Huawei Site Kit, your app can provide users with convenient and secure access to diverse, place-related services.
Use Case
We will get user current location using location kit and use this location in site kit to get nearby movie theatres.
In this article, we will see how we have use these two kits and combine them in order to create a movie booking app.
Prerequisite
1. Must have a Huawei Developer Account
2. Must have a Huawei phone with HMS 4.0.0.300 or later
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 installed.
Things Need To Be Done
1) Create a project in android studio.
2) Get the SHA Key. For getting the SHA key we can refer to this article.
3) Create an app in the Huawei app gallery connect.
4) Provide the SHA Key in App Information Section.
5) Provide storage location.
6) Enable Site Kit in Manage API Section.
7) After completing all the above points we need to download the agconnect-services.json from App Information Section. Copy and paste the json file in the app folder of the android project.
8) Enter below class path inside the dependencies of buildscript ( project build.gradle file )
Code:
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
9) Enter below maven url inside the repositories of buildscript and allprojects ( project build.gradle file )
Code:
maven { url 'http://developer.huawei.com/repo/' }
10) Enter below plugin in the app build.gradle file dependencies section.
Code:
implementation 'com.huawei.hms:location:4.0.2.300'
implementation 'com.huawei.hms:site:5.0.0.300'
11) If the project is using progaurd, enter the below code in the progaurd-rules.pro file.
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
12) The HUAWEI Ads SDK requires the following permissions:
Code:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
13) Now sync the app.
Demo
In this demo, user will login using their Huawei ID. After that they will view the list of movies released in their respective cities. Once user selects a movie for booking purpose, user can see theatres near to their respective location. After selecting the theatre, user can see seats available for booking.
Getting user location
1) We need to check for permission.
Code:
private void grantPermission(){
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
Log.i(TAG, "sdk < 28 Q");
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] strings =
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
ActivityCompat.requestPermissions(this, strings, 1);
}
} else {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
"android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
"android.permission.ACCESS_BACKGROUND_LOCATION"};
ActivityCompat.requestPermissions(this, strings, 2);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults.length > 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION successful");
} else {
Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSSION failed");
}
}
if (requestCode == 2) {
if (grantResults.length > 2 && grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION successful");
} else {
Log.i(TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION failed");
}
}
}
2) In order to get user current location, create a FusedLocationProviderClient instance using the onCreate() method of Activity and use the instance to call location-related APIs.
Code:
FusedLocationProviderClient fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
3) The location function of Huawei Location Kit depends on the device location settings. For example, if the location function is disabled on a device, your app cannot obtain the device location. So, it is recommended that your app check whether the device settings meet the location requirements before continuously obtaining the device location. Huawei Location Kit provides the function of checking device location settings. In order to do that, obtain the SettingsClient instance using getSettingsClient(Activity activity) of LocationServices and call the checkLocationSettings(LocationSettingsRequest locationSettingsRequest) API to obtain the device location settings.
Code:
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
4) Create a location information request.
Code:
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setNeedAddress(true);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
5) Finally we need to get last location with address using FusedLocationProviderClient, so that we will be able to make user aware of their city also we need latitude and longitude of their current location in order to get nearby theatres using Huawei Site Kit.
Code:
fusedLocationProviderClient.getLastLocationWithAddress(mLocationRequest)
.addOnSuccessListener(new OnSuccessListener<HWLocation>() {
@SuppressLint("SetTextI18n")
@Override
public void onSuccess(HWLocation hwLocation) {
System.out.println("CITY >>> " + hwLocation.getCity());
lat = hwLocation.getLatitude();
lon = hwLocation.getLongitude();
txtWelcomMsg.setText("You are right now in " +hwLocation.getCity()+ " location. Grab a pop corn and book a movie because It's Show Time.");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
}
});
Getting user nearby theatres
1) We need API key in order to work with Huawei Site Kit. To get API key,
Choose AGC console > My Project > General Information > API Key. Copy this API key and save the key somewhere in your project.
2) Declare a SearchService object and use SearchServiceFactory to instantiate the object. Also the API key which we got from AGC console, need to be encoded using encodeURI.
Code:
try {
SearchService searchService = SearchServiceFactory.create(this, URLEncoder.encode(Constant.API_KEY, "utf-8"));
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "encode apikey error");
}
3) Need to create Coordinate in order to set the location later. We will use user current location latitude and longitude fetched using Huawei Location Kit.
Code:
Coordinate location = new Coordinate(lat, lon);
4) Create a QuerySuggestionRequest object, which is used as the request body for search suggestion. Related parameters are as follows, among which query is mandatory and others are optional:
a) query: search keyword.
b) location: longitude and latitude to which search results need to be biased.
c) radius: search radius, in meters. The value ranges from 1 to 50000. The default value is 50000.
d) bounds: coordinate bounds to which search results need to be biased.
e) poiTypes: List of POI types. The value range is a subset of LocationType.
f) countryCode: code of the country where places are searched, which complies with the ISO 3166-1 alpha-2 standard. Code of the country where places are searched, which complies with the ISO 3166-1 alpha-2 standard.
g) language: language in which search results are displayed. Language in which search results are displayed.
Code:
QuerySuggestionRequest request = new QuerySuggestionRequest();
request.setQuery("Movie theater");
request.setLocation(location);
request.setRadius(50);
request.setCountryCode("IN");
request.setLanguage("en");
QuerySuggestionRequest request2 = new QuerySuggestionRequest();
request2.setQuery("PVR cinemas");
request2.setLocation(location);
request2.setRadius(50);
request2.setCountryCode("IN");
request2.setLanguage("en");
QuerySuggestionRequest request3 = new QuerySuggestionRequest();
request3.setQuery("INOX Movies");
request3.setLocation(location);
request3.setRadius(50);
request3.setCountryCode("IN");
request3.setLanguage("en");
5) Finally create a SearchResultListener object to listen for the search result. Use the created SearchService object to call the querySuggestion() API and pass the created QuerySuggestionRequest and SearchResultListener objects to the API. Obtain the QuerySuggestionResponse object using the created SearchResultListener object. You can obtain a Site object from the QuerySuggestionResponse object and then parse it to obtain specific search results.
Code:
SearchResultListener<QuerySuggestionResponse> resultListener = new SearchResultListener<QuerySuggestionResponse>() {
@Override
public void onSearchResult(QuerySuggestionResponse results) {
if (results == null) {
return;
}
List<Site> sites = results.getSites();
for (Site site : sites) {
theaterNameList.add(site.getName());
}
}
@Override
public void onSearchError(SearchStatus status) {
Log.i("TAG", "Error : " + status.getErrorCode() + " " + status.getErrorMessage());
}
};
searchService.querySuggestion(request, resultListener);
searchService.querySuggestion(request2, resultListener);
searchService.querySuggestion(request3, resultListener);
GitHub
After we complete our series we will provide the github link for your reference
For More Information
https://developer.huawei.com/consumer/en/doc/HMSCore-Guides-V5/introduction-0000001050706106-V5
https://developer.huawei.com/consumer/en/doc/HMSCore-Guides-V5/android-sdk-introduction-0000001050158571-V5

Explore the world Trip Booking App- 4 Location and Awareness

Introduction
This article provides information to book any trip using Trip Booking Android app. It provides a solution for HMS based multiple kits such as Account Kit, Huawei Ads, Huawei Map Direction Polyline API, Huawei Location, Huawei Map, Huawei Awareness Weather API, and Huawei Analytics to use in Trip Booking.
The following HMS Kits used in this application:
1) Huawei Account Kit: Integrated this kit for login and logout.
2) Huawei Ads: Integrated this kit for better ads experiences so that users can find the better advertisements.
3) Huawei Analytics: Integrated this kit in this application for better analysis.
4) Huawei Map: Integrated this kit for better real time experience of trip booking so that user can identify the location of trip on map.
5) Huawei Direction API: Integrated this API for better trip booking experience such as users can identify the trip direction from his/her location on map.
6) Huawei Awareness Weather API: Integrated this API for weather forecast of trip.
7) Huawei Location: Integrated this Kit to get current location of user so that users can identify from current location to desire trip location.
Note: Refer to the previous articles.
1) Explore the world Trip Booking App, Part-1 login with Huawei ID
2) Explore the world Trip Booking App, Part-2 Ads and Analytics
3) Explore the world Trip Booking App, Part-3 Map and direction API
Prerequisite
1. A computer (desktop or laptop)
2. A Huawei phone, which is used to debug the developed app
3. HUAWEI Analytics Kit 5.0.3.
4. Android SDK applicable to devices using Android API-Level 19 (Android 4.4 KitKat) or higher.
5. Android Studio
6. Java JDK 1.7 or later (JDK 1.8 recommended).
Things Need To Be Done
To integrate HUAWEI HMS Core services, you must complete the following preparations:
1. Create an app in AppGallery Connect.
2. Create an Android Studio project.
3. Add the app package name and save the configuration file.
4. Configure the Maven repository address and AppGallery Connect gradle plug-in.
Weather Awareness API
HUAWEI Awareness Kit provides your app with the ability to obtain contextual information including users' current time, location, behavior, audio device status, ambient light, weather, and nearby beacons. Your app can gain insight into a user's current situation more efficiently, making it possible to deliver a smarter, more considerate user experience.
Integration process
1) Assigning Permissions in the Manifest File
2) Importing API Classes
3) Developing Capabilities
1) Assigning Permissions in the Manifest File
Before calling the weather awareness capability, assign required permissions in the manifest file.
Code:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2) Importing API Classes
To use the weather awareness capability, you need to import the public capability classes of Awareness Kit, and also the weather-related classes.
Code:
import com.huawei.hmf.tasks.OnFailureListener;import com.huawei.hmf.tasks.OnSuccessListener;import com.huawei.hms.kit.awareness.Awareness;
import com.huawei.hms.kit.awareness.status.WeatherStatus;
import com.huawei.hms.kit.awareness.status.weather.Situation;
import com.huawei.hms.kit.awareness.status.weather.WeatherSituation;
3) Developing Capabilities
Obtain the Capture Client object of Awareness Kit.
Code:
public class AwarenessWeather {
private static final String TAG = AwarenessWeather.class.getName();
public CurrentWeather.Current getWeatherSituation(Context context) {
CurrentWeather.Current current = new CurrentWeather().new Current();
Awareness.getCaptureClient(context).getWeatherByDevice()
.addOnSuccessListener(weatherStatusResponse -> {
WeatherStatus weatherStatus = weatherStatusResponse.getWeatherStatus();
WeatherSituation weatherSituation = weatherStatus.getWeatherSituation();
Situation situation = weatherSituation.getSituation();
String weatherInfoStr =
"Time Zone : " + (weatherSituation.getCity().getTimeZone()) + "\n\n" +
"Weather id : " + situation.getWeatherId() + "\n\n" +
"Temperature : " + situation.getTemperatureC() + "℃" +
"/" + situation.getTemperatureF() + "℉" + "\n\n" +
"Wind speed : " + situation.getWindSpeed() + "km/h" + "\n\n" +
"Wind direction : " + situation.getWindDir() + "\n\n" +
"Humidity : " + situation.getHumidity() + "%";
Log.i(TAG, weatherInfoStr);
current.setObservationTime("Day");
current.setTemperature(Math.toIntExact(situation.getTemperatureC()));
current.setIsDay(url);
})
.addOnFailureListener(e -> {
Log.e(TAG, "get weather failed");
});
return current;
}
}
Location Kit
HUAWEI Location Kit combines the GNSS, Wi-Fi, and base station location functionalities into your app to build up global positioning capabilities, allows you to provide flexible location-based services targeted at users around the globe. Currently, it provides three main capabilities: Fused location, Activity identification, and Geofence. You can call one or more of these capabilities as required.
1) Fused location: Provides a set of simple and easy-to-use APIs for your app to quickly obtain the device location based on the GNSS, Wi-Fi, and base station location data.
2) Activity identification: Identifies user motion status through the acceleration sensor, cellular network information, and magnetometer, help to adapt the app to user behavior.
3) Geofence: Allows you to set an interesting area through an API so that your app can receive a notification when a specified action (such as leaving, entering, or staying in the area) occurs.
Integration process
1) Add following dependency in Gradle File.
Code:
implementation 'com.huawei.hms:location:5.0.2.301
2) Assigning App Permissions.
Apply for location permissions in the AndroidManifest.xml file.
Code:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
3) Creating a Location Service Client.
Create a FusedLocationProviderClient instance using the onCreate() method of Activity and use the instance to call location-related APIs.
Code:
private FusedLocationProviderClient fusedLocationProviderClient;
private LocationRequest mLocationRequest;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
}
4) Check permission.
Code:
// check location permisiion
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
Log.i(TAG, "sdk < 28 Q");
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] strings =
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
ActivityCompat.requestPermissions(this, strings, 1);
}
} else {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
"android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
"android.permission.ACCESS_BACKGROUND_LOCATION"};
ActivityCompat.requestPermissions(this, strings, 2);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults.length > 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSION successful");
} else {
Log.i(TAG, "onRequestPermissionsResult: apply LOCATION PERMISSSION failed");
}
}
if (requestCode == 2) {
if (grantResults.length > 2 && grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION successful");
} else {
Log.i(TAG, "onRequestPermissionsResult: apply ACCESS_BACKGROUND_LOCATION failed");
}
}
}
Huawei Map Direction API
Huawei Map provides Direction API so that user can access all the information related to Map in RESTful API.
Huawei has provided the following API endpoint to access Direction API.
https://mapapi.cloud.huawei.com/mapApi/v1
Huawei provides the following direction API:
1. Walking Route Planning
2. Bicycling Route Planning
3. Driving Route Planning
Implemented the Driving Route API with the help of Retrofit and MVVM.
Retrofit Client
Created MapApiClient class for accessing the Direction API.
Code:
public class MapApiClient {
private final static HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
private static OkHttpClient okHttpClient;
public static Service getClient() {
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Consants.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
return retrofit.create(Service.class);
}
public interface Service {
@POST("mapApi/v1/routeService/driving")
Single<PolylineResponse> getPolylines(
@Query("key") String apiKey,
@Body PolylineBody polylineBody);
}
}
API Repository
I have created MapApiRepo class for accessing the API client.
Code:
public class MapApiRepo {
private MapApiClient.Service mService;
public MapApiRepo() {
this.mService = MapApiClient.getClient();
}
public Single<PolylineResponse> executeMapApi(PolylineBody polylineBody) {
return mService.getPolylines(Consants.API_KEY, polylineBody);
}
}
ViewModel
I have created MapApiViewModel class for handling the API calls.
Code:
public class MapApiViewModel extends ViewModel {
private final CompositeDisposable disposables = new CompositeDisposable();
private MapApiRepo mapApiRepo = new MapApiRepo();
private MutableLiveData<PolylineResponse> mPolylineLiveData = new MutableLiveData<>();
public LiveData<PolylineResponse> getPolylineLiveData(PolylineBody body) {
disposables.add(mapApiRepo.executeMapApi(body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> mPolylineLiveData.setValue(result),
throwable -> mPolylineLiveData.setValue(null)
));
return mPolylineLiveData;
}
@Override
protected void onCleared() {
disposables.clear();
}
}
Drawing Polyline
I have implemented this functionality in the following activity.
Code:
mapApiViewModel.getPolylineLiveData(getPolylineBody()).observe(this, result -> {
Log.d(TAG, result.toString());
getPolylineData(result);
}); private PolylineBody getPolylineBody() {
PolylineBody polylineBody = new PolylineBody();
Origin origin = new Origin();
origin.setLat("30.0444");
origin.setLng("31.2357");
Destination destination = new Destination();
destination.setLat("30.0131");
destination.setLng("31.2089");
polylineBody.setDestination(destination);
polylineBody.setOrigin(origin);
return polylineBody;
}
public void getPolylineData(PolylineResponse polylineResponse) {
List<Routes> routesList = polylineResponse.getRoutes();
List<Paths> paths = new ArrayList<>();
List<Steps> steps = new ArrayList<>();
List<Polyline> polylines = new ArrayList<>();
latLngList = new ArrayList<>();
for (int x = 0; x < routesList.size(); x++) {
//here we can access each array list with main.get(x).
for (Paths paths1 : routesList.get(x).getPaths()) {
paths.add(paths1);
}
for (int y = 0; y < paths.size(); y++) {
for (Steps step :
paths.get(y).getSteps()) {
steps.add(step);
}
}
for (int i = 0; i < steps.size(); i++) {
for (Polyline polyline :
steps.get(i).getPolyline()) {
polylines.add(polyline);
}
}
}
for (int i = 0; i < polylines.size(); i++) {
latLngList.add(new LatLng(Double.valueOf(polylines.get(i).getLat())
, Double.valueOf(polylines.get(i).getLng())));
}
hmap.addPolyline(new PolylineOptions()
.addAll(latLngList)
.color(Color.BLUE)
.width(3));
}
App Development
Created the following package inside the project. In which integrated as Account Kit, Huawei Ads, Huawei Map Direction Polyline API, Huawei Location, Huawei Map, Huawei Awareness Weather API, and Huawei Analytics.
{
"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"
}
PolyLineActivity
In this activity, I have integrated Location kit, Map, and Direction API.
Launch the application
Let us launch our application, see the result
If you have any doubts or queries. Leave your valuable comment in the comment section and do not forget to like and follow me
Conclusion
In this article, I have explained how to integrate Location Kit and Weather Awareness in Trip Booking application and draw a route between origins to destination.
References
Driving Direction API:
https://developer.huawei.com/consumer/en/doc/development/HMSCore-References-V5/directions-driving-0000001050161496-V5

Intermediate: Site kit Search Capabilities in Food DeliveryApp in Flutter – Part 2

Introduction
In this article, we will be integrating other Search features of Site kit, you can find previous article here, and Huawei Site Kit provides core capabilities to developer to quickly build apps with which users can explore world around them seamlessly. Huawei Site kit provides following Search capabilities to developer as shown below.
Keyword search: returns the place list based on the keywords entered by user.
Nearby place search: Searches for nearby location based on current location of the user’s device.
Place detail search: Search for details about the place.
Place search suggestion: Returns list of suggested places.
Autocomplete: Returns an autocomplete place and a list of suggested places based on the entered keyword.
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.android.application'
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'
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_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARES_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Step 4: Add plugin path in pubspec.yaml file under dependencies.
Step 5: Create a project in AppGallery Connect, find here.
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
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/
huawei_safetydetect:
path: ../huawei_safetydetect
huawei_site:
path: ../huawei_site
http: ^0.12.2
rflutter_alert: ^2.0.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
# add this line to your dependencies
toast: ^0.1.5
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:
Declare and instantiate service object
Code:
Future<void> initmySearchService() async {
searchService = await SearchService.create(Uri.encodeComponent(API_KEY));
}<strong> </strong>
How to I call QueryAutoCompleteRequest api ?
Code:
void autocomplete(String value) async {
// Declare an SearchService object and instantiate it. which i done in above initSearchService()
// Create QueryAutocompleteRequest and its body.
QueryAutocompleteRequest request = QueryAutocompleteRequest(query: value);
// Create QueryAutocompleteResponse object.
// Call queryAutocomplete() method.
// Assign the results.
QueryAutocompleteResponse response =
await searchService.queryAutocomplete(request);
if (response != null) {
Map<String, dynamic> data = json.decode(response.toJson());
List<dynamic> data2;
locations.clear();
entries.clear();
for (String key in data.keys) {
if (key == 'sites') {
data2 = data[key];
for (var element in data2) {
setState(() {
entries.add(element['name'] + "\n" + element['formatAddress']);
locations.add(new LatLng(
element['location']['lat'], element['location']['lng']));
});
}
}
}
}
}
How to I call QuerySuggestionRequest api ?
Code:
void querySuggestionSearch(String value) async {
// Declare an SearchService object and instantiate it. which i done in above initSearchService()
QuerySuggestionRequest request = QuerySuggestionRequest();
request.query = value;
request.location = Coordinate(lat: 12.893478, lng: 77.334595);
request.language = "en";
request.countryCode = "IN";
request.radius = 5000;
// Create QuerySuggestionResponse object.
// Call querySuggestion() method.
// Assign the results.
QuerySuggestionResponse response =
await searchService.querySuggestion(request);
if (response != null) {
Map<String, dynamic> data = json.decode(response.toJson());
List<dynamic> data2;
entries.clear();
for (String key in data.keys) {
if (key == 'sites') {
data2 = data[key];
for (var element in data2) {
setState(() {
entries.add(element['name'] + "\n" + element['formatAddress']);
locations.add(new LatLng(
element['location']['lat'], element['location']['lng']));
});
}
}
}
}
}
How to I call DetailSearchRequest api ?
Code:
void placeDetailSearch(String siteId) async {
// Declare an SearchService object and instantiate it. which i done in above initSearchService()
DetailSearchRequest request = DetailSearchRequest();
request.siteId = siteId;
request.language = "en";
// Create DetailSearchResponse object.
// Call detailSearch() method.
// Assign the results.
DetailSearchResponse response = await searchService.detailSearch(request);
if (response != null) {
Map<String, dynamic> data = json.decode(response.toJson());
List<dynamic> data2;
setState(() {
result = data['site'].toString();
});
} else {
print("Response is NULL");
}
}
Result
Note: Place detail search takes sit id as input and gives site information as result.
Tricks and Tips
Make sure that you have downloaded latest plugin.
Make sure that updated plugin path in yaml.
Make sure that plugin unzipped in parent directoryof project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added in 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 Site kit Search capabilities for DeliveryApp in flutter. Where user can search for specific hotel or restaurants in the search box and clicks on the result to find the list of orders. Similar way you can use Huawei Site kit as per user requirement in your application.
Thank you so much for reading, I hope this article helps you to understand the Huawei Site kit Search capabilities in flutter.
Reference
Site kit
Site kit plugin
Original Source

How to achieve Place Search and Marker Clustering Implementation in Map App

Background​Lots of apps these days include an in-app map feature and the ability to mark places of interest on the map. HMS Core Map Kit enables you to implement such capabilities for your apps. With Map Kit, you can first draw a map and then add markers to the map, as well as configure the map to cluster markers depending on the level of zoom. This article will show you how to implement searching for nearby places using the keyword search capability of Site Kit and display the results on the map.
Application scenarios:
A travel app that allows users to search for scenic spots and shows the results on a map.
2.A bicycle sharing app that can show users nearby bicycles on a map.
Key functions used in the project:
Location service: Use Location Kit to obtain the current longitude-latitude coordinates of a device.
Keyword search: Use Site Kit to search for places such as scenic spots, businesses, and schools in the specified geographical area based on the specified keyword.
Map display: Use Map Kit to draw a map. Marker clustering: Use Map Kit to add markers to the map and configure the map to cluster markers depending on the level of zoom.
Integration Preparations​1.Register as a developer and create a project in AppGallery Connect.
(1)Register as a developer Registration URL
{
"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"
}
(2)Create an app, add the SHA-256 signing certificate fingerprint, enable Map Kit and Site Kit, and download the agconnect-services.json file of the app.
2.Integrate the Map SDK and Site SDK.
(1)Copy the agconnect-services.json file to the app's directory of your project.
Go to allprojects > repositories and configure the Maven repository address for the HMS Core SDK.
Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.
If the agconnect-services.json file has been added to the app, go to buildscript > dependencies and add the AppGallery Connect plugin configuration.
Code:
buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}
}
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
}
}
(2)Add build dependencies in the dependencies block.
Code:
dependencies {
implementation 'com.huawei.hms:maps:{version}'
implementation 'com.huawei.hms:site:{version}'
implementation 'com.huawei.hms:location:{version}'
}
(3)Add the following configuration to the file header:
Code:
apply plugin: 'com.huawei.agconnect'
(4)Copy the signing certificate generated in Generating a Signing Certificate to the app directory of your project, and configure the signing certificate in android in the build.gradle file.
Code:
signingConfigs {
release {
// Signing certificate.
storeFile file("**.**")
// KeyStore password.
storePassword "******"
// Key alias.
keyAlias "******"
// Key password.
keyPassword "******"
v2SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true
}
debug {
debuggable true
}
}
Main Code and Used Functions​1.Use Location Kit to obtain the device location.
Code:
private void getMyLoction() {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
mLocationRequest = new LocationRequest();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
//Check the device location settings.
settingsClient.checkLocationSettings(locationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
//Initiate location requests when the location settings meet the requirements.
fusedLocationProviderClient
.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// Processing when the API call is successful.
Log.d(TAG, "onSuccess: " + aVoid);
}
});
}
})
2.Implement the text search function using Site Kit to search for nearby places.
Code:
SearchResultListener<TextSearchResponse> resultListener = new SearchResultListener<TextSearchResponse>() {
// Return search results upon a successful search.
@Override
public void onSearchResult(TextSearchResponse results) {
List<Site> siteList;
if (results == null || results.getTotalCount() <= 0 || (siteList = results.getSites()) == null
|| siteList.size() <= 0) {
resultTextView.setText("Result is Empty!");
return;
}
updateClusterData(siteList);// Mark places on the map.
}
// Return the result code and description upon a search exception.
@Override
public void onSearchError(SearchStatus status) {
resultTextView.setText("Error : " + status.getErrorCode() + " " + status.getErrorMessage());
}
};
// Call the place search API.
searchService.textSearch(request, resultListener);
3.Draw a map
Code:
@Override
public void onMapReady(HuaweiMap huaweiMap) {
hMap = huaweiMap;
hMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Constants.sMylatLng, 1));
hMap.setMyLocationEnabled(true);
hMap.getUiSettings().setMyLocationButtonEnabled(true);
initCluster(huaweiMap);
}
4.Cluster markers on the map.
Code:
private ClusterManager<MyItem> mClusterManager;
List<MyItem> items = new ArrayList<>();
private void initCluster(HuaweiMap hMap) {
mClusterManager = new ClusterManager<>(this, hMap);
hMap.setOnCameraIdleListener(mClusterManager);
// Add a custom InfoWindowAdapter by setting it to the MarkerManager.Collection object from
// ClusterManager rather than from GoogleMap.setInfoWindowAdapter
//refer: https://github.com/billtom20/3rd-maps-utils
mClusterManager.getMarkerCollection().setInfoWindowAdapter(new HuaweiMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
final LayoutInflater inflater = LayoutInflater.from(SearchClusterActivity.this);
final View view = inflater.inflate(R.layout.custom_marker_window, null);
final TextView textView = view.findViewById(R.id.textViewTitle);
String text = (marker.getTitle() != null) ? marker.getTitle() : "Cluster Item";
textView.setText(text);
return view;
}
@Override
public View getInfoContents(Marker marker) {
return null;
}
});
}
// Update clustered markers.
private void updateClusterData(List<Site> siteList) {
items = new ArrayList<>();
mClusterManager.clearItems();
for (Site s:
siteList) {
Coordinate location = s.getLocation();
MyItem myItem = new MyItem(location.lat,location.lng,s.name,s.formatAddress);
items.add(myItem);
}
mClusterManager.addItems(items);
Coordinate coordinate = siteList.get(0).getLocation();
LatLng latLng = new LatLng(coordinate.lat,coordinate.lng);
mClusterManager.cluster();
hMap.animateCamera(CameraUpdateFactory.newLatLngZoom (latLng,14 ));
}
Results​Enter a place or service in the Query box and tap Search. The figures below show how the search results are displayed as markers on the map.
The preceding four figures show the effect of searching for food and school, as well as the marker clustering effect at different zoom levels. Congratulations, you have now successfully integrated place search and marker clustering into your in-app map.
References​For more details, you can go to:official website
Development Documentation page, to find the documents you need
Reddit to join our developer discussion
GitHub to download sample codes
Stack Overflow to solve any integration problems
Thanks for sharing..

How to Use Geofences for Precise Audience Messaging

Precise messaging is an important way for mobile apps to retain users and is usually achieved by segmenting users into different groups according to their preferences and then adopting different messaging policies for each user segment. However, if you want to push messages to users based on their precise locations, in-depth customization is usually required since most available third-party messaging services cannot narrow the target audience down to a specific business area or a small area. With geofences, this issue can be effectively resolved. A geofence is a set of virtual boundaries that define a given area on a map. When a user's device enters or leaves the geofence, or stays in the geofence for a specific amount of time, messages and notifications can be automatically sent to an app on the user's device. Geofence and messaging capabilities can work together to precisely send messages to target audiences in a specified area.
For example, suppose that a travel app wants to promote its ticket booking service in Paris. To do so, the app can create geofences for popular scenic spots in Paris. When a target user arrives at a scenic spot during a specified time range, the app will send a promotion message such as "You have received a coupon for the XXX. Tap here to claim the coupon." to the user, increasing their willingness to buy a ticket.
Implementation​You can carry out precise messaging to specified target audiences by using the geofence capability HMS Core Location Kit in conjunction with the message pushing capability of HMS Core Push Kit. By creating a geofence for a specified area, the app can detect the user's status, for example, when they enter, leave, or stay in this area. Once the messaging condition is met, the app on the user's device will receive a push message in real time. The push message can be sent to and displayed on the user's device even when the app is not running in the background, achieving a delivery rate as high as 99%.
​Demo​1. Install the demo app on the test device.
2. Start the demo app, tap Add Geofence on the GeoFence screen, and set relevant parameters to create a geofence.
3. Wait for the geofence to be triggered.
4. Check the received message.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Development Procedure​1. Configure the Maven repository address for the SDK.
(The procedure for configuring the Maven repository address in Android Studio is different for Gradle plugin versions earlier than 7.0, Gradle plugin 7.0, and Gradle plugin 7.1 or later versions. Here, the procedure for Gradle plugin 7.1 is used as an example.)
a) Go to buildscript > dependencies and add AppGallery Connect plugin configurations.
Code:
buildscript {
dependencies {
...
// Add the AppGallery Connect plugin configuration. You are advised to use the latest plugin version.
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
}
b) Open the project-level settings.gradle file and configure the Maven repository address for the SDK.
Code:
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
// Configure the Maven repository address for the SDK.
maven { url 'https://developer.huawei.com/repo/' }
}
}
dependencyResolutionManagement {
...
repositories {
google()
mavenCentral()
// Configure the Maven repository address for the SDK.
maven { url 'https://developer.huawei.com/repo/' }
}
}
2. Add build dependencies in the dependencies block.
Code:
// Configure the app-level build.gradle file.
dependencies {
implementation 'com.huawei.hms:location: 6.4.0.300'
implementation 'com.huawei.hms:push: 6.3.0.304'
}
3. Declare system permissions in the AndroidManifest.xml file.
The Location SDK incorporates the GNSS, Wi-Fi, and base station location functions into an app to build up precise global positioning capabilities. Therefore, it requires the network, precise location, and coarse location permissions to function correctly. If the app needs to continuously obtain user locations when running in the background, the ACCESS_BACKGROUND_LOCATION permission also needs to be declared in the 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_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARES_LOCATION" />
Note: The ACCESS_FINE_LOCATION, WRITE_EXTERNAL_STORAGE, and READ_EXTERNAL_STORAGE permissions are dangerous system permissions, so they must be dynamically applied for. If the app does not have the permissions, Location Kit will be unable to provide services for the app.
​Key Code​Code file: com.huawei.hmssample2.geofence\GeoFenceActivity.java
If you want to integrate the geofence service and implement message pushing in your app, you only need to add relevant code in GeoFenceActivity.java to your app project.
1. Configure geofences.
a) Create geofences and geofence groups as needed, and set relevant parameters, such as the geofence radius and triggering time.
Code:
if (checkStyle(geofences, data.uniqueId) == false) {
LocationLog.d("GeoFenceActivity", "not unique ID!");
LocationLog.i("GeoFenceActivity", "addGeofence failed!");
return;
}
geoBuild.setRoundArea(data.latitude, data.longitude, data.radius);
geoBuild.setUniqueId(data.uniqueId);
geoBuild.setConversions(data.conversions);
geoBuild.setValidContinueTime(data.validContinueTime);
geoBuild.setDwellDelayTime(data.dwellDelayTime);
geoBuild.setNotificationInterval(data.notificationInterval);
geofences.add(geoBuild.build());
LocationLog.i("GeoFenceActivity", "addGeofence success!");
b) Register a broadcast using the intent.
Code:
GeofenceRequest.Builder geofenceRequest = new GeofenceRequest.Builder();
geofenceRequest.createGeofenceList(GeoFenceData.returnList());
if (trigger.getText() != null) {
int trigGer = Integer.parseInt(trigger.getText().toString());
geofenceRequest.setInitConversions(trigGer);
LocationLog.d(TAG, "trigger is " + trigGer);
} else {
geofenceRequest.setInitConversions(5);
LocationLog.d(TAG, "default trigger is 5");
}
final PendingIntent pendingIntent = getPendingIntent();
try {
geofenceService.createGeofenceList(geofenceRequest.build(), pendingIntent)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(Task<Void> task) {
if (task.isSuccessful()) {
LocationLog.i(TAG, "add geofence success! ");
setList(pendingIntent, GeoFenceData.getRequestCode(), GeoFenceData.returnList());
GeoFenceData.createNewList();
} else {
// Get the status code for the error and log it using a user-friendly message.
LocationLog.w(TAG, "add geofence failed : " + task.getException().getMessage());
}
}
});
} catch (Exception e) {
LocationLog.i(TAG, "add geofence error:" + e.getMessage());
}
private PendingIntent getPendingIntent() {
Intent intent = new Intent(this, GeoFenceBroadcastReceiver.class);
intent.setAction(GeoFenceBroadcastReceiver.ACTION_PROCESS_LOCATION);
Log.d(TAG, "new request");
GeoFenceData.newRequest();
return PendingIntent.getBroadcast(this, GeoFenceData.getRequestCode(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
2. Trigger message pushing. Send a push message when onReceive of GeoFenceBroadcastReceiver detects that the geofence is triggered successfully. The message will be displayed in the notification panel on the device.
Code:
GeofenceData geofenceData = GeofenceData.getDataFromIntent(intent);
if (geofenceData != null) {
int errorCode = geofenceData.getErrorCode();
int conversion = geofenceData.getConversion();
ArrayList<Geofence> list = (ArrayList<Geofence>) geofenceData.getConvertingGeofenceList();
Location myLocation = geofenceData.getConvertingLocation();
boolean status = geofenceData.isSuccess();
sb.append("errorcode: " + errorCode + next);
sb.append("conversion: " + conversion + next);
if (list != null) {
for (int i = 0; i < list.size(); i++) {
sb.append("geoFence id :" + list.get(i).getUniqueId() + next);
}
}
if (myLocation != null) {
sb.append("location is :" + myLocation.getLongitude() + " " + myLocation.getLatitude() + next);
}
sb.append("is successful :" + status);
LocationLog.i(TAG, sb.toString());
Toast.makeText(context, "" + sb.toString(), Toast.LENGTH_LONG).show();
//
new PushSendUtils().netSendMsg(sb.toString());
}
Note: The geofence created using the sample code will trigger two callbacks for conversion types 1 and 4. One is triggered when a user enters the geofence and the other when a user stays in the geofence. If Trigger is set to 7 in the code, callbacks will be configured for all scenarios, including entering, staying, and leaving the geofence.
Once you have performed the preceding steps, you will have enabled geofence-based message pushing for your app and can send messages to target audiences in specific areas, achieving precise marketing.
References​Location Kit official website
Location Kit development documentation

Categories

Resources