[Huawei Developers] lokeshsuryan:
View attachment 5271423

"Hey, they say it's five centimeters per second. The falling speed of a cherry blossom petal. Five centimeters per second."

Upon hearing these famous lines from a well-known Japanese anime, John, a Huawei programmer, realized that cherry trees are currently blossoming.

John's girlfriend, Jenny, also loves cherry blossoms and planned to visit Paris's most famous park for cherry blossoms, Parc de Sceaux, on the weekend. John, unfortunately, was still on a business trip that weekend and could not go with his girlfriend.

So John said to himself, "How about I make an intelligent travel app, I am a programmer after all, for Jenny, so that she can enjoy the cherry blossoms in the best possible way?" John then listed the following requirements for the app he was about to quickly create:

l Considerate travel reminders: remind her of important events in advance in her schedule, such as when to depart.

l Weather forecast: provide suggestions on what to bring and wear based on the weather conditions at her destination.

l Push messages: push helpful tips and discount information to her once she arrives at the destination.

...

Luckily for John, the preceding capabilities can be implemented without hassle using the time and weather awareness capabilities of HUAWEI Awareness Kit, the geofence capabilities of HUAWEI Location Kit, and the message pushing capabilities of HUAWEI Push Kit.

Overview​

Awareness Kit provides your app the ability to obtain contextual information including users' current time, location, behavior, headset status, weather, ambient light, car stereo connection status, and beacon connection status, which can be combined to create various barriers that run in the background and trigger once the predefined context is met.

Location Kit combines GNSS, Wi-Fi, and base station positioning capabilities into your app, allowing you to provide flexible location-based services for users around the world.

Push Kit is a messaging service tailored for developers, which helps create a cloud-to-device messaging channel. With Push Kit integrated, your app can send messages to users' devices in real time.

Code Development​

1. Awareness Kit Integration​

Preparations​

The following three key steps are required for integrating Awareness Kit. For details, please refer to the development guide on the HUAWEI Developers website.

1. Configure app information in AppGallery Connect.

2. Integrate the HMS Core Awareness SDK.

3. Configure obfuscation scripts.

Development Procedure​

1. Declare required permissions in the AndroidManifest.xml file.

<p style="line-height: 1.5em;"><
uses-permission
android
:name
="android.permission.ACCESS_FINE_LOCATION"
/>
<
uses-permission
android
:name
="android.permission.ACCESS_BACKGROUND_LOCATION"
/></p>

2. Obtain weather information based on the city name.

String city = edCity.getText().toString();
if (city != null && !city.equals("")) {
WeatherPosition weatherPosition = new WeatherPosition();
weatherPosition.setCity(city);
// Pass the language type of the passed address. The value format is "Language_country", such as "zh_CN", "en_US".
weatherPosition.setLocale("en_US");

// Obtain the Capture Client of Awareness Kit, and call the weather query capability.
Awareness.getCaptureClient(getApplicationContext()).getWeatherByPosition(weatherPosition)
.addOnSuccessListener(new OnSuccessListener<WeatherStatusResponse>() {
@Override
public void onSuccess(WeatherStatusResponse weatherStatusResponse) {
// Process the returned weather data.
WeatherStatus weatherStatus = weatherStatusResponse.getWeatherStatus();
WeatherSituation weatherSituation = weatherStatus.getWeatherSituation();
Situation situation = weatherSituation.getSituation();
String weather;
// Match the weather ID with the weather.
weather = getApplicationContext().getResources().getStringArray(R.array.cnWeather)[situation.getCnWeatherId()];
// Update UI.
((TextView) findViewById(R.id.tv_weather)).setText(weather);
((TextView) findViewById(R.id.tv_windDir)).setText(situation.getWindDir());
((TextView) findViewById(R.id.tv_windSpeed)).setText(situation.getWindSpeed() + " km/h");
((TextView) findViewById(R.id.tv_temperature)).setText(situation.getTemperatureC() + "℃");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {

}
});
}

3. Implement scheduled reminders and message pushing once a user arrives at the destination.

（1） Register a static broadcast receiver to receive notifications when the app is terminated.

The sample code in the AndroidManifest.xml file is as follows:

<receiver android:name=".BarrierReceiver">
<intent-filter>
<action android:name="com.test.awarenessdemo.TimeBarrierReceiver.BARRIER_RECEIVER_ACTION"/>
</intent-filter>
</receiver>

The Java sample code is as follows:

Intent intent = new Intent();
intent.setComponent(new ComponentName(MainActivity.this, BarrierReceiver.class));
mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

（2） Define the time barrier and corresponding label, then add the barrier.

// Obtain the entered time.
String timeHour = edTimeHour.getText().toString();
String timeMinute = edTimeMinute.getText().toString();
int hour = 0;
int minute = 0;
if (!timeHour.equals("")) {
hour = Integer.parseInt(timeHour);
if (!timeMinute.equals("")) {
minute = Integer.parseInt(timeMinute);
}
}
long oneHourMilliSecond = 60 * 60 * 1000L;
long oneMinuteMilliSecond = 60 * 1000L;
// Define the duringPeriodOfDay barrier to send notifications within a specified time period in a specified time zone.
AwarenessBarrier periodOfDayBarrier = TimeBarrier.duringPeriodOfDay(TimeZone.getDefault(),
// Set the notification time to two hours in advance.
(hour - 2) * oneHourMilliSecond + minute * oneMinuteMilliSecond,
hour * oneHourMilliSecond + minute * oneMinuteMilliSecond);

String timeBarrierLabel = "period of day barrier label";
// Define a request for updating a barrier.
BarrierUpdateRequest.Builder builder = new BarrierUpdateRequest.Builder();
BarrierUpdateRequest request = builder.addBarrier(timeBarrierLabel, periodOfDayBarrier, mPendingIntent).build();
Awareness.getBarrierClient(getApplicationContext()).updateBarriers(request)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
}
});

（3） Define the location barrier and corresponding label, then add the barrier.

if (city != null && !city.equals("")) {
// Obtain the longitude and latitude of the city based on the city name from the assets folder.
String data = cityMap.get(city);
if (data != null){
int flag = data.indexOf(",");
double latitude = Double.parseDouble(data.substring(flag+1));
double longitude = Double.parseDouble(data.substring(0,flag));
double radius = 50;
long timeOfDuration = 5000;
// Define the stay barrier. If a user enters a specified area and stays for a specified time period, a barrier event is triggered and reported.
AwarenessBarrier stayBarrier = LocationBarrier.stay(latitude, longitude, radius, timeOfDuration);
String stayBarrierLabel = "stay barrier label";
// Define a request for updating a barrier.
BarrierUpdateRequest.Builder builder = new BarrierUpdateRequest.Builder();
BarrierUpdateRequest request = builder.addBarrier(stayBarrierLabel, stayBarrier, mPendingIntent).build();
Awareness.getBarrierClient(getApplicationContext()).updateBarriers(request)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
}
});
}
}

（4） Define the broadcast receiver to listen for the barrier event for further processing

class BarrierReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
BarrierStatus barrierStatus = BarrierStatus.extract(intent);
String label = barrierStatus.getBarrierLabel();
int barrierPresentStatus = barrierStatus.getPresentStatus();
String city = intent.getStringExtra("city");
switch (label) {
case DURING_PERIOD_OF_DAT_BARRIER_LABEL:
if (barrierPresentStatus == BarrierStatus.TRUE) {

initNotification(context,"1","time_channel","Travel reminder","Two hours before departure");
} else if (barrierPresentStatus == BarrierStatus.FALSE) {
showToast(context, "It's not between ");
} else {
showToast(context, "The time status is unknown.");
}
break;

case STAY_BARRIER_LABEL:
if (barrierPresentStatus == BarrierStatus.TRUE) {

initNotification(context,"2","area_channel","Welcome to"+city,"View travel plans");
} else if (barrierPresentStatus == BarrierStatus.FALSE) {
showToast(context,"You are not staying in the area set by locationBarrier" +
" or the time of duration is not enough.");
} else {
showToast(context, "The location status is unknown.");
}
break;
}
}

}

2. Location-based Message Pushing

Preparations​

1. Add the Huawei Maven repository address to the build.gradle file in the root directory of your project. The sample code is as follows:

<p style="line-height: 1.5em;">buildscript {
repositories {
maven { url 'http://developer.huawei.com/repo/'}
}
dependencies {
...
// Add AppGallery Connect plugin configuration.
classpath 'com.huawei.agconnect:agcp:1.4.2.300'
}
}allprojects {
repositories {
maven { url 'http://developer.huawei.com/repo/'}
}
}</p>

2. Add dependencies on the Location and Push SDKs to the build.gradle file in the app directory of your project.

<p style="line-height: 1.5em;">dependencies {
implementation 'com.huawei.hms:location:5.0.2.300'
implementation 'com.huawei.hms:push: 5.0.2.301'
}</p>

Key Steps​

1. Declare system permissions in the AndroidManifest.xml file.

Location Kit incorporates GNSS, Wi-Fi, and base station positioning capabilities into your app. In order to do this, it requires the network, precise location, and coarse location permissions. If you want the app to continuously obtain user locations when running in the background, you also need to declare the ACCESS_BACKGROUND_LOCATION permission in the AndroidManifest.xml file.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

Note: The ACCESS_FINE_LOCATION, WRITE_EXTERNAL_STORAGE, and READ_EXTERNAL_STORAGE permissions are dangerous system permissions, so you need to dynamically apply for these permissions. If your app does not have the permissions, Location Kit will be unable to provide services for your app.

2. Create a geofence and trigger it.

Create a geofence or geofence group as needed, and set related parameters.

LocationSettingsRequest.Builder builders = new LocationSettingsRequest.Builder();
builders.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builders.build();
// Before requesting location update, call checkLocationSettings to check device settings.
Task<LocationSettingsResponse> locationSettingsResponseTasks = mSettingsClient.checkLocationSettings(locationSettingsRequest);
locationSettingsResponseTasks.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "check location settings success");
mFusedLocationProviderClient
.requestLocationUpdates(mLocationRequest, mLocationCallbacks, Looper.getMainLooper())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
LocationLog.i(TAG, "geoFence onSuccess");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
LocationLog.e(TAG,
"geoFence onFailure:" + e.getMessage());
}
});
}
})

3. 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.

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 is triggered when the user stays in the geofence. If Trigger is set to 7 in the code, callbacks for all scenarios, including entering, staying, and leaving the geofence, are configured.

Let's see this Demo:

View attachment 5271429

For more details, you can go to:

l Our official website

l Our Development Documentation page, to find the documents you need

l Experience the easy-integration process on Codelabs

l GitHub to download demos and sample codes

l Stack Overflow to solve any integration problem

| Original Source