Nearby Service Puts Games on the Large Screen, with Nimble Phone Controls - Huawei Developers

1. Background
Today's online games offer stunning effects and exhilarating gameplay, and user expectations for gaming have skyrocketed. Here, we'll talk about how large-screen games can be controlled on a mobile phone or tablet, via Nearby Service's Bluetooth- and Wi-Fi-based solution.
2. Applicable Scenarios
With Nearby Service, users are able to wirelessly transmit real-time data from the sensor on a mobile phone or tablet to a large-screen device, to enjoy gaming that is vast in scale, but remarkably easy to control. This controller function can be downloaded, simply by scanning the QR code displayed on the home page for the large-screen game, after which all gaming operations can be transmitted. Now we'll show you how transmission works for phone gyroscope data.
This solution enables users to benefit from a more powerful and cost-effective game controller, which does not require additional mobile data to be consumed, or even an Internet connection, meaning that it remains reliable at all times. In addition, it empowers the controller to discover, connect, and exchange data with nearby large-screen gaming devices, facilitating effortless multiplayer gaming.
3. Implementation Process
As shown below, the discoverer corresponds to the game controller, while the broadcaster corresponds to the large-screen gaming device. The implementation process is similar: broadcast and scanning -> connection setup -> data transmission -> disconnection. In the broadcast and scanning phase, Bluetooth low energy (BLE) broadcasting technology is used to discover devices. In the data transmission phase, high-speed transmission between devices can be implemented with ease, backed by the traditional P2P protocol.
{
"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"
}
4. Key Integration Steps and Code
(1) Broadcast.
Code:
<p style="line-height: 1.5em;">public void doStartBroadcast(View view) {
Context context = getApplicationContext();
mDiscoveryEngine = Nearby.getDiscoveryEngine(context);
BroadcastOption.Builder advBuilder = new BroadcastOption.Builder();
advBuilder.setPolicy(Policy.POLICY_STAR);
mDiscoveryEngine.startBroadcasting(myNameStr, myServiceId, mConnCb, advBuilder.build());
}
</p>
(2) Scan.
Code:
<p style="line-height: 1.5em;">public void doStartScan(View view) {
ScanOption.Builder discBuilder = new ScanOption.Builder();
discBuilder.setPolicy(Policy.POLICY_STAR);
mDiscoveryEngine.startScan(myServiceId, mDiscCb, discBuilder.build());
}
</p>
(3) Request a connection.
Code:
<p style="line-height: 1.5em;">private void connect(View view) {
mDiscoveryEngine.requestConnect(myNameStr, mEndpointId, mConnCb)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(SensorActivity.this,"connect Success",Toast.LENGTH_SHORT).show();
Log.d(TAG, "connect Success:");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Toast.makeText(SensorActivity.this,"connect Failure",Toast.LENGTH_SHORT).show();
Log.d(TAG, "connect Failure");
}
});
}
</p>
(4) Send and receive data.
Controller: Send the real-time data obtained by the phone gyroscope.
Code:
<p style="line-height: 1.5em;">private void sendData(Data bytesData){ Nearby.getTransferEngine(getApplicationContext()).sendData(mEndpointId, bytesData);}
</p>
Large-screen games: Receive data.
Code:
<p style="line-height: 1.5em;">private DataCallback mDataCb =
new DataCallback() {
@Override
public void onReceived(String string, Data data) {
Log.d(TAG, "onReceived, Data.Type = " + data.getType());
Log.d(TAG, "onReceived, string ======== " + string);
switch (data.getType()) {
case Data.Type.BYTES:
String str = new String(data.asBytes(), UTF_8);
receiveMessage(data);
break;
default:
Log.i(TAG, "the other Unknown data type, please check the uploaded file.");
return;
}
}
@Override
public void onTransferUpdate(String string, TransferStateUpdate update) {
Log.d(TAG, "onTransferUpdate.Status=======" + update.getStatus());
return;
}
}
};
</p>
Code:
<p style="line-height: 1.5em;">private void receiveMessage(Data data) {
msgStr = new String(data.asBytes(), UTF_8);
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
String dateStr = dateFormat.format(new Date());
tvData.append("\n" + dateStr + msgStr);
}
</p>
(5) Disconnect.
Code:
<p style="line-height: 1.5em;">private void disconnect(){
mDiscoveryEngine.disconnect(mEndpointId);
}
</p>
5. Effects
Due to hardware limitations, we used two mobile phones for the test, with one serving as the controller to send real-time data for phone gyroscope, and the other as the large-screen gaming device to receive the data. After the data is received, it is calculated to obtain the game controller operations.
When the distance between the two devices is about three meters, the comparison between the transmitted and received data is as follows:
When two devices are close to each other (for example, approximately three or four meters apart), the latency for data transmission is generally less than one second, which can be regarded as real-time data. Even when the distance is changing, the service remains user-friendly.
Note: Currently, when there are no obstacles obstructing the Bluetooth signal from the two devices, data transmission remains smooth within seven meters. The Bluetooth connection will likely be inconsistent when the distance exceeds eight meters, and non-existent beyond ten meters.
6. Precautions
(1) In this example, you would need to enter the names of both devices for the connection. In the broadcast and scanning phase, you can display the list of discovered devices and allow users to select the devices to be connected.
(2) The example above makes use of the point-to-point connection policy, which supports a 1-to-N or star-shaped connection topology. You can also use the point-to-point connection policy that supports an M-to-N or cluster-shaped connection topology, and policy that supports a 1-to-1 connection topology. For details about the application scenarios of these three policies, please refer to Nearby Service-Broadcast and Scanning.
(3) The data transmitted in this example is in byte sequence (BYTES), in which the data size cannot exceed 32 KB. You can also use two other data types, as needed: FILE and STREAM.
(4) In this example, unprocessed phone gyroscope data is sent. You can control the game operations by calculating the data.
(5) In this example, there is some amount of latency when data is sent and received. The latency is for reference only, and should not be regarded as the standard of performance for Nearby Service.

Related

Developing a Function for Precisely Pushing Ads to Nearby People Using HUAWEI Nearby

More articles like this, you can visit HUAWEI Developer Forum and Medium.​
When you want to find a restaurant and your phone receives a push message recommending nearby restaurants to you at the right moment, will you tap open the message? When you're still hesitating on whether to buy a pair of sneakers in a store and an app sends you a coupon offering you a 50% discount, do you still find the ad bothering?
Ads pushed at the right moment meet users' requirements and won't make users feel bothered. More precise advertising not only reduces unnecessary disturbance to users but also improves user satisfaction with your app. Do you want to build such a function for precisely pushing ads to nearby people?
{
"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"
}
Integrate HUAWEI Nearby Service and use the Nearby Beacon Message feature to implement the function. You need to deploy beacons at the place where you want to push messages to nearby people, for example, a mall. Beacons will provide users' locations relative to them so that when a user gets near a restaurant or store, the user will receive a promotion message (such as a coupon or discount information) preconfigured by the merchant in advance. The function demo is as follows.
If you are interested in the implementation details, download the source code from GitHub: https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCanteens
1. Getting Started
If you are already a Huawei developer, skip this step. If you are new to Huawei Mobile Services (HMS), you need to configure app information in AppGallery Connect, enable Nearby Service on the HUAWEI Developers console, and integrate the HMS Core SDK. For details, please refer to the documentation.
1.1 Adding Huawei Maven Repository and AppGallery Connect Plug-in Configurations to the Project-Level build.gradle File
Add the following Huawei maven repository and AppGallery Connect plug-in configurations to your project-level build.gradle file directly:
Code:
buildscript {
repositories {
google()
jcenter()
maven { url 'http://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'http://developer.huawei.com/repo/' }
}
}
1.2 Adding SDK Dependencies to the App-Level build.gradle File
Import the Nearby Service SDKs. The most important SDKs are those starting with com.huawei.
Code:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation "com.huawei.hmf:tasks:1.3.1.301"
implementation "com.huawei.hms:network-grs:1.0.9.302"
implementation 'com.huawei.agconnect:agconnect-core:1.2.1.301'
implementation 'com.huawei.hms:nearby:4.0.4.300'
api 'com.google.code.gson:gson:2.8.5'
}
1.3 Applying for the Network, Bluetooth, and Location Permissions in the AndroidManifest.xml File
The following permissions are required. Each permission name can directly express its purpose. For example, android.permission.INTERNET indicates the network permission, and android.permission.BLUETOOTH indicates the Bluetooth permission.
Code:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2. Code Development
2.1 Initialization and Dynamic Permission Application
The onCreate method is called when the current activity is created. In this method, you can perform some preparations, such as applying for necessary permissions and checking whether the Internet connection, Bluetooth, and GPS are enabled.
Code:
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
setContentView(R.layout.activity_canteen);
boolean isSuccess = requestPermissions(this, this);
if (!isSuccess) {
return;
}
Log.i(TAG, "requestPermissions success");
if (!NetCheckUtil.isNetworkAvailable(this)) {
showWarnDialog(Constant.NETWORK_ERROR);
return;
}
if (!BluetoothCheckUtil.isBlueEnabled()) {
showWarnDialog(Constant.BLUETOOTH_ERROR);
return;
}
if (!GpsCheckUtil.isGpsEnabled(this)) {
showWarnDialog(Constant.GPS_ERROR);
return;
}
intView();
init();
}
Register a listener and display a message if Bluetooth, GPS, or network disconnection is detected.
The following uses the AlertDialog component of Android as an example:
Code:
private void showWarnDialog(String content) {
DialogInterface.OnClickListener onClickListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
android.os.Process.killProcess(android.os.Process.myPid());
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.warn);
builder.setIcon(R.mipmap.warn);
builder.setMessage(content);
builder.setNegativeButton(getText(R.string.btn_confirm), onClickListener);
builder.show();
}
2.2 Beacon Message Reception
The following startScanning method is called in the onStart method to start Bluetooth scanning. In the MessageHandler object, four callback methods are encapsulated: 1. onFound indicates that a beacon message is discovered; 2. OnLost indicates that the message is no longer discoverable; 3. onDistanceChanged indicates the change of the distance between the beacon and the device; 4. onBleSignalChanged indicates that a beacon signal change is detected.
Code:
private void startScanning() {
Log.i(TAG, "startScanning");
mMessageHandler =
new MessageHandler() {
@Override
public void onFound(Message message) {
super.onFound(message);
doOnFound(message);
}
@Override
public void onLost(Message message) {
super.onLost(message);
doOnLost(message);
}
@Override
public void onDistanceChanged(Message message, Distance distance) {
super.onDistanceChanged(message, distance);
}
@Override
public void onBleSignalChanged(Message message, BleSignal bleSignal) {
super.onBleSignalChanged(message, bleSignal);
}
};
MessagePicker msgPicker = new MessagePicker.Builder().includeAllTypes().build();
Policy policy = new Policy.Builder().setTtlSeconds(Policy.POLICY_TTL_SECONDS_INFINITE).build();
GetOption getOption = new GetOption.Builder().setPicker(msgPicker).setPolicy(policy).build();
Task<Void> task = messageEngine.get(mMessageHandler, getOption);
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.e(TAG, "Login failed:", e);
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
int errorStatusCode = apiException.getStatusCode();
if (errorStatusCode == StatusCode.STATUS_MESSAGE_AUTH_FAILED) {
Toast.makeText(mContext, R.string.configuration_error, Toast.LENGTH_SHORT).show();
} else if (errorStatusCode == StatusCode.STATUS_MESSAGE_APP_UNREGISTERED) {
Toast.makeText(mContext, R.string.permission_error, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, R.string.start_get_beacon_message_failed, Toast.LENGTH_SHORT)
.show();
}
} else {
Toast.makeText(mContext, R.string.start_get_beacon_message_failed, Toast.LENGTH_SHORT)
.show();
}
}
});
}
Personalize the display of a detected beacon message.
The most important method during the process is the doOnFound method, which specifies the personalized display processing mode when the client receives a beacon message.
Code:
private void doOnFound(Message message) {
if (message == null) {
return;
}
String type = message.getType();
if (type == null) {
return;
}
String messageContent = new String(message.getContent());
Log.d(TAG, "New Message:" + messageContent + " type:" + type);
if (type.equalsIgnoreCase(Constant.CANTEEN)) {
operateOnFoundCanteen(messageContent);
} else if (type.equalsIgnoreCase(Constant.NOTICE)) {
operateOnFoundNotice(messageContent);
}
}
Display the personalized message.
The following code only demonstrates one of the message processing modes, including implementing the banner notification and text display effect.
Code:
private void operateOnFoundCanteen(String messageContent) {
CanteenAdapterInfo canteenAdapterInfo =
(CanteenAdapterInfo) JsonUtils.json2Object(messageContent, CanteenAdapterInfo.class);
if (canteenAdapterInfo == null) {
return;
}
String canteenName = canteenAdapterInfo.getCanteenName();
if (canteenName == null) {
return;
}
Log.d(TAG, "canteenName:" + canteenName);
if (!canteenNameList.contains(canteenName)) {
return;
}
String notice = "";
if (receivedNoticeMap.containsKey(canteenName)) {
notice = receivedNoticeMap.get(canteenName);
}
int canteenImage = getCanteenImage(canteenName);
int requestCode = getRequestCode(canteenName);
canteenAdapterInfo.setNotice(notice);
canteenAdapterInfo.setCanteenImage(canteenImage);
canteenAdapterInfo.setShowNotice(true);
canteenAdapterInfo.setRequestCode(requestCode);
canteenAdapterInfoMap.put(canteenName, canteenAdapterInfo);
canteenAdapterInfoList.add(canteenAdapterInfo);
sendNotification(Constant.NOTIFICATION_TITLE, Constant.NOTIFICATION_SUBTITLE, canteenName, requestCode);
runOnUiThread(
new Runnable() {
@Override
public void run() {
searchTipTv.setText(R.string.found_tip);
loadingLayout.setVisibility(View.GONE);
canteenAdapter.setDatas(canteenAdapterInfoList);
}
});
}
Conclusion
This demo uses Bluetooth beacon message subscription function of HUAWEI Nearby Service.
Based on the Nearby Beacon Message capability, you not only can develop an ad push function, but also can implement the following functions:
1. A car or lifestyle app can integrate the capability to identify whether a user is near their car to determine whether to enable keyless access and record the driving track of the car.
2. A business app can integrate the capability to accurately record the locations where employees clock in.
3. A travel or exhibition app can integrate the capability to introduce an exhibit to a user when the user gets near the exhibit.
4. A game app can integrate the capability to make your game interact with the real world, for example, unlocking a game level through a physical object and sending rewards to players who are participating in offline events.
If you are interested and want to learn more, check our development guide at the HUAWEI Developers official website.
Any questions about the process, you can visit HUAWEI Developer Forum.
Hi,
Can we use HMS nearby service to create a chat application and can also provide ads about restaurant when user enter the restaurant in the chat application as a message.
Thanks.
sanghati said:
Hi,
Can we use HMS nearby service to create a chat application and can also provide ads about restaurant when user enter the restaurant in the chat application as a message.
Thanks.
Click to expand...
Click to collapse
Nearby has two businesses, one is Connection, you can use Connection to develop chat functions. The other is Message. Deploy a Beacon in the hotel. After registering the Beacon, set the Beacon message. When the user walks into the restaurant, they can receive the message you set in advance. You can also set some conditions on the cloud service, such as the time period of the user, how long it will be for users in the restaurant, etc. After these conditions are met, you will receive the message. The advantages of this method are: 1. You can modify the rules in real time, 2. More accurate advertising push to avoid unnecessary interruptions.

Comparison between Huawei Scan Kit and Zxing

More information like this, you can visit HUAWEI Developer Forum​
Introduction
The Huawei Scan Kit offers versatile scanning, decoding, and generation capacities for bar code and QR code, enabling developers to quickly create the scans for QR code in apps.
Huawei can automatically detect and amplify long-distance or smaller scan codes via its long-range accumulation in the computer vision sector and automate the recognition of normal, complex barcode (example: reflection) scanning (such as dark light, smudge, blur and cylinder) scanning services. Scan Kit improves the performance rate and user experience of QR scanning code.
Zxing is a common third-party open-source SDK, it allows an Android device with imaging hardware (a built-in camera) to scan barcodes or 2-D graphical barcodes and retrieve the data encoded. It only carries out simple QR-code scanning operations and does not support complex scanning conditions, including high light, bend and deformation. However, the optimization effect is still not ideal, and many people will spend a lot of time on the optimization.
Let us now evaluate the Zxing and the Huawei HMS scan kit capabilities:
Note
In this article, I have scanned the code for 5 times and taken the best time captured.
Results may vary from device to device. I have used Huawei Y7p device for scanning, maintained similar condition for both HMS scan and Zxing.
Normal Scanning
{
"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"
}
When simple QR code is scanned from normal distance (around half feet), we have captured the time for decoding the code .
Huawei Scan kit took 0.68 seconds.
Zxing scanner took 1.38 seconds.
Result : HMS Scan kit wins
Scanning QR code at an angle
Let us scan the QR code at an angle more than 45 degrees from line of sight.
Huawei Scan kit took 0.657 seconds.
Zxing scanner took 1.27 seconds.
However, when we tried to capture at an angle more than 60 degrees, Zxing was not able to scan the code.
Result: HMS Scan kit wins
Scanning Complex Code:
Complex QR or bar code is too dense to decode. Let us see effectiveness of both the scanners.
Huawei scanner took 2.214 seconds when scanned from ideal distance (1.5 feet). However, if QR code is scanned from close distance it took 10.237 seconds. When QR code is scanned from distance more that 3 to 4 feet, it took 23.105 seconds.
ZXING scan took 19.10 seconds when scanned from ideal distance (1.5 feet). When scanned from too close or away from QR code, it was not able to able to scan it.
Result: HMS Scan kit wins.
Scanning code from long distance
Since Zxing does not have an automatic zoom-in optimisation, it is difficult to recognize code when the code is less than 20% of the frame.
The HMS Scan Kit has a pre-detection feature that can automatically amplify a long distance QR code even if the QR code cannot be detected by naked eyes.
HMS scan took 1.391 sec to detect when QR code is more 8 feet away.
Zxing failed to detect the code.
Result: HMS Scan kit wins
Implementation of HMS scan kit:
Prerequisite
Java JDK 1.8 or higher is recommended.
Android Studio is recommended.
Before developing an app, you will need to register as a HUAWEI developer. Refer to Register a HUAWEI ID.
Integrating app gallery connect SDK. Refer to AppGallery Connect Service Getting Started.
Development
1. Add the HMS scan kit dependencies in module-level build.gradle
Code:
implementation 'com.huawei.hms:scan:1.1.3.301'
2. To launch HMS default scanner
Code:
ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, new HmsScanAnalyzerOptions.Creator().create());
3. Getting the scan result
Code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK || data == null) {
return;
}
endTime = System.currentTimeMillis();
//Default View
if (requestCode == REQUEST_CODE_SCAN_ONE) {
HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT);
if (obj != null) {
tvTimer.setText(String.valueOf((endTime-startTime) /1 000) + " sec");
}
}
Implementation of Zxing scan:
1. Add the Zxing scan dependencies in module-level build.gradle
Code:
implementation 'com.journeyapps:zxing-android-embedded:3.4.0'
2. To initialize QR code scanner
Code:
qrScan = new IntentIntegrator(this);
3. To launch the scanner
Code:
//initiating the qr code scan
qrScan.initiateScan();
4. Getting the scan result
Code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK || data == null) {
return;
}
endTime = System.currentTimeMillis();
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
tvTimer.setText(String.valueOf((endTime-startTime)/1000) + " sec");
if (result != null) {
//if qrcode has nothing in it
if (result.getContents() == null) {
Toast.makeText(this, "Result Not Found", Toast.LENGTH_LONG).show();
} else {
//if qr contains data
try {
//converting the data to json
JSONObject obj = new JSONObject(result.getContents());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
Very nice and interesting article.
Just curious to know, If we scan in dark with mobile flash light, which takes less time?

How to Integrate Nearby Service to Create a Social Networking App that Connects Users

Background
Most social networking apps offer a set of standard features, such as accurate connections with nearby people, face-to-face grouping, and short-distance local chatting in point-to-point mode. However, while the common "Nearby people" feature can help users discover others hundreds of meters, or even several kilometers away from them, it is not well suited to connect users who are in each other's presence. Likewise, for "face-to-face grouping", it would be great to connect with group members in your vicinity, and communicate with friends, even when there is no Internet connection. Thanks to Nearby Service, this long sought-after ideal is now a full-blown reality! So, without further ado, let's take a look at how you can integrate Nearby Service, to create the social networking app of your dreams.
Applicable Scenarios
Here's an example of an app that has integrated Nearby Service. With Nearby Service, the app is able to discover nearby people, and implement a myriad of different functions, such as face-to-face grouping, group chats, private chats, and chat log migration.
Nearby people
Nearby Service ensures that users can discover people within several meters, with a high degree of accuracy. The service enables users to connect with people in their vicinity, so long as they are in the same room, such as at a conference, exhibition, bar, or cafe.
{
"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"
}
Face-to-face grouping
With Nearby Service, users are able to directly create a group on their device, and set a precise location range. Only people within this location range will be eligible to join the group.
Free chat
Nearby Service facilitates short-distance group chatting, and does not require the group members to add each other. Instead, members can join the group automatically when they are within the location range, and will automatically exit the group when they leave this range.
Private chat
Nearby Service implements short-distance local chatting in point-to-point mode, enabling users to communicate with just the two devices in question, and free of any concern regarding data leakage, due to the presence of encrypted communications data that is not uploaded to the cloud. Furthermore, the feature supports communications in areas with poor signal coverage, such as on high-speed rail or the metro.
Chat log migration
Nearby Service offers a powerful file transmission function as well. The communications APIs in Nearby Service ensure that users enjoy high-speed, traffic-free data transmission when they need to migrate chat records on multiple devices.
Preparing Tools
Two or more Android phones
Android Studio (3.X or later)
Creating an App
Import the source code to Android Studio.
Register as a Huawei developer.
Create an app in Huawei AppGallery. For details, please refer to HUAWEI Developers-App Development. Note that you will need to download the agconnect-services.json file, generate the signing certificate, and save them to the app directory.
Run the adb command to install the generated APK file on the test phones.
Core Code
For more information about the APIs used in the app, please visit Nearby Service-Development Guides.
This app is created in MVP mode. For the source code, you can find the corresponding class in the code path: com\huawei\hms\nearby\im.
1.Nearby people
As shown in the following code, you will need to pass the view object during the initialization of the NearbyPeoplePresenter class. When the NearbyPeoplePresenter.findNearbyPeople() API is called to discover nearby people, call the view API to perform subsequent steps.
Code:
public NearbyPeoplePresenter(Context mContext, INearbyPeopleView view) {
super(mContext, view);
nearbyAgent = new NearbyAgent(mContext, new NearbyAgent.INearbyMessageView() {
@Override
public void onMessageFound(MessageBean messageBean) {
// notify view when found someone
view.onMemberChanged(false,messageBean);
}
@Override
public void onMessageLost(MessageBean messageBean) {
view.onMemberChanged(true,messageBean);
}
@Override
public void onMsgSendResult(boolean isSucceed, MessageBean item) {
view.onLoginResult(isSucceed,item);
if (!isSucceed) {
handler.postDelayed(() -> findNearbyPeople(),DURATION_RE_LOGIN);
}
}
});
handler = new Handler(Looper.getMainLooper());
}
public void findNearbyPeople() {
nearbyAgent.broadcastMessage(null,MessageBean.ACTION_TAG_ONLINE);
nearbyAgent.startScan();
}
2.Face-to-face grouping
This process is similar to that for nearby people. Pass the view object during the initialization of the CreateGroupPresenter.java class. When the joinGroup(groupId) API is called, the user is added to the group. The result is returned by calling the view API.
INearbyPeopleView and xxxView in the following steps are a group of APIs. Their implementation is the corresponding Activity, which you can view through the code path: com\huawei\hms\nearby\im\ui\adapter.
Code:
public CreateGroupPresenter(Context mContext, ICreateGroupView view) {
super(mContext, view);
nearbyAgent = new NearbyAgent(mContext, new NearbyAgent.INearbyMessageView() {
@Override
public void onMessageFound(MessageBean messageBean) {
view.onPeopleFound(messageBean);
}
@Override
public void onMessageLost(MessageBean messageBean) {}
@Override
public void onMsgSendResult(boolean isSucceed, MessageBean item) {
view.onJoinGroupResult(isSucceed,item);
}
});
}
public void joinGroup(String groupId) {
nearbyAgent.broadcastMessage(groupId,"join group");
nearbyAgent.startScan(groupId);
}
3.Free chat
Pass the view object during the initialization of the GroupChatPresenter.java class. You can call broadcastMessage(groupId, sendContent) to send a message to a specified group. The group is not limited if groupId is null. Also, the findMessage(groupId) API can be called to find the message of a specified group. After the message is found, the view API will be called to return the message.
Code:
public GroupChatPresenter(Context mContext, IGroupChatView view) {
super(mContext, view);
nearbyAgent = new NearbyAgent(mContext, new NearbyAgent.INearbyMessageView() {
@Override
public void onMessageFound(MessageBean messageBean) {
view.onMessageFound(messageBean);
}
@Override
public void onMessageLost(MessageBean messageBean) {
}
@Override
public void onMsgSendResult(boolean isSucceed, MessageBean item) {
view.onMsgSendResult(isSucceed,item);
}
});
}
public void broadcastMessage(String groupId, String sendContent) {
nearbyAgent.broadcastMessage(groupId,sendContent);
}
public void findMessage(String groupId) {
nearbyAgent.startScan(groupId);
}
4.Private chat
Private chat implementation differs from the process above. The NearbyConnectionPresenter.java class provides the following APIs:
findNearbyPeople(): Discovering people nearby.
requestConnect(): Connecting users with each other.
sendMessage(String msgStr): Sending messages of strings.
sendFile(Uri uri): Sending files.
Code:
/**
* scanAndBroadcasting to find nearby people
*/
public void findNearbyPeople(){
mDiscoveryEngine.startScan(serviceId, new ScanEndpointCallback() {
@Override
public void onFound(String endpointId, ScanEndpointInfo discoveryEndpointInfo) {
Log.d(TAG, "onFound -- Nearby Connection Demo app: onFound endpoint: " + endpointId);
view.onFound(endpointId,discoveryEndpointInfo);
}
@Override
public void onLost(String endpointId) {
Log.d(TAG, "onLost -- Nearby Connection Demo app: Lost endpoint: " + endpointId);
view.onLost(endpointId);
}
}, scanOption);
}
/**
* request to connect with remote device
* @param endpointId the endpointId of remote device
*/
public void requestConnect(String endpointId) {
Log.d(TAG, "requestConnect -- endpoint: " + endpointId);
mDiscoveryEngine.requestConnect(myNameStr, endpointId, connectCallback);
}
/**
* Send message ,Data.Type.BYTES
*/
public MessageBean sendMessage(String msgStr) {
MessageBean item = new MessageBean();
item.setUserName(CommonUtil.userName);
item.setMsg(msgStr);
item.setType(MessageBean.TYPE_SEND_TEXT);
item.setSendTime(DateUtils.getCurrentTime(DateUtils.FORMAT));
Data data = Data.fromBytes(gson.toJson(item).getBytes(Charset.defaultCharset()));
mTransferEngine.sendData(mEndpointId, data);
return item;
}
/**
* send file ,Data.Type.FILE
* @param uri
*/
public Data sendFile(Uri uri) {
Data filePayload;
try {
ParcelFileDescriptor pfd = mContext.getContentResolver().openFileDescriptor(uri, "r");
filePayload = Data.fromFile(pfd);
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "File not found, cause: ", e);
return null;
}
String fileName = FileUtil.getFileRealNameFromUri(mContext, uri);
String filenameMessage = filePayload.getId() + ":" + fileName;
Data filenameBytesPayload = Data.fromBytes(filenameMessage.getBytes(StandardCharsets.UTF_8));
mTransferEngine.sendData(mEndpointId, filenameBytesPayload);
mTransferEngine.sendData(mEndpointId, filePayload);
return filePayload;
}
Learn More
For more detailed information, please visit HUAWEI Developers.
For further instructions, please visit Development Guides.
You can join the HMS Core developer discussion by going to Reddit.
You can download the demo and sample code on GitHub.
To resolve any integration issues, please go to Stack Overflow.

How to Help College Students Avoid Phone Scams

View attachment Featured image.jpg
As the start of the new academic year approaches, many college students will be leaving their parents to start college life. However, a lack of experience makes it easy for college students to become victims of electronic fraud such as phone scams.
The start of the new academic year is often a period of time that sees an uptick in phone scams, especially those targeting college students. Some scammers trick students to download and register an account on malicious financial apps embedded with viruses and Trojan horses or ones that imitate legitimate apps. With such malicious apps installed on students' phones, scammers are able to steal students' sensitive data, such as bank card numbers and passwords. Some scammers trick students, by offering them small gifts or coupons, to scan QR codes which then direct them to pages that ask users to enter their personal information, such as their phone number and address. Once a student has done this, they will receive a large number of fraudulent calls and junk SMS messages from then on. If the students scan QR codes linking to phishing websites, their personal data may be leaked and sold for malicious purposes. Some scammers even lie about offering students scholarships or grants, in order to trick them into visiting phishing websites and entering their bank account numbers and passwords, causing significant financial losses to such students.
{
"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"
}
To deal with the ever-changing tricks of fraudsters, an app needs to detect phishing websites, malicious apps, and other risks and remind users to be on the lookout for such risks with in-app tips, in order to keep users and their data safe. So, is there a one-stop service that can enhance app security from multiple dimensions? Fortunately, HMS Core Safety Detect can help developers quickly build security capabilities into their apps, and help vulnerable user groups such as college students safeguard their information and property.
The AppsCheck API in Safety Detect allows your app to obtain a list of malicious apps installed on a user's device. The API can identify 99% of malicious apps and detect unknown threats based on app behavior. Your app can then use this information to determine whether to restrict users from performing in-app payments and other sensitive operations.
The URLCheck API in Safety Detect checks whether an in-app URL is malicious. If the URL is determined to be malicious, the app can warn the user of the risk or block the URL.
Safety Detect also provides capabilities to check system integrity and detect fake users, helping developers quickly improve their app security. The integration process is straightforward, which I'll describe below.
Demo​
Integration Procedure​Preparations​You can follow the instructions here to prepare for the integration.
Using the AppsCheck API​You can directly call getMaliciousAppsList of SafetyDetectClient to obtain a list of malicious apps. The sample code is as follows:
Code:
private void invokeGetMaliciousApps() {
SafetyDetectClient appsCheckClient = SafetyDetect.getClient(MainActivity.this);
Task task = appsCheckClient.getMaliciousAppsList();
task.addOnSuccessListener(new OnSuccessListener<MaliciousAppsListResp>() {
@Override
public void onSuccess(MaliciousAppsListResp maliciousAppsListResp) {
// Indicates that communication with the service was successful.
// Use resp.getMaliciousApps() to obtain a list of malicious apps.
List<MaliciousAppsData> appsDataList = maliciousAppsListResp.getMaliciousAppsList();
// Indicates that the list of malicious apps was successfully obtained.
if(maliciousAppsListResp.getRtnCode() == CommonCode.OK) {
if (appsDataList.isEmpty()) {
// Indicates that no known malicious apps were detected.
Log.i(TAG, "There are no known potentially malicious apps installed.");
} else {
Log.i(TAG, "Potentially malicious apps are installed!");
for (MaliciousAppsData maliciousApp : appsDataList) {
Log.i(TAG, "Information about a malicious app:");
// Use getApkPackageName() to obtain the APK name of the malicious app.
Log.i(TAG, "APK: " + maliciousApp.getApkPackageName());
// Use getApkSha256() to obtain the APK SHA-256 of the malicious app.
Log.i(TAG, "SHA-256: " + maliciousApp.getApkSha256());
// Use getApkCategory() to obtain the category of the malicious app.
// Categories are defined in AppsCheckConstants.
Log.i(TAG, "Category: " + maliciousApp.getApkCategory());
}
}
}else{
Log.e(TAG,"getMaliciousAppsList failed: "+maliciousAppsListResp.getErrorReason());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// An error occurred during communication with the service.
if (e instanceof ApiException) {
// An error with the HMS API contains some
// additional details.
ApiException apiException = (ApiException) e;
// You can retrieve the status code using the apiException.getStatusCode() method.
Log.e(TAG, "Error: " + SafetyDetectStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " + apiException.getStatusMessage());
} else {
// A different, unknown type of error occurred.
Log.e(TAG, "ERROR: " + e.getMessage());
}
}
});
}
Using the URLCheck API​1. Initialize the URLCheck API.
Before using the URLCheck API, you must call the initUrlCheck method to initialize the API. The sample code is as follows:
Code:
SafetyDetectClient client = SafetyDetect.getClient(getActivity());
client.initUrlCheck();
2. Request a URL check.
You can pass target threat types to the URLCheck API as parameters. The constants in the UrlCheckThreat class include the current supported threat types.
Code:
public class UrlCheckThreat {
// URLs of this type are marked as URLs of pages containing potentially malicious apps (such as home page tampering URLs, Trojan-infected URLs, and malicious app download URLs).
public static final int MALWARE = 1;
// URLs of this type are marked as phishing and spoofing URLs.
public static final int PHISHING = 3;
}
a. Initiate a URL check request.
The URL to be checked contains the protocol, host, and path but does not contain the query parameter. The sample code is as follows:
Code:
String url = "https://developer.huawei.com/consumer/cn/";
SafetyDetect.getClient(this).urlCheck(url, appId, UrlCheckThreat.MALWARE, UrlCheckThreat.PHISHING).addOnSuccessListener(this, new OnSuccessListener<UrlCheckResponse >(){
@Override
public void onSuccess(UrlCheckResponse urlResponse) {
if (urlResponse.getUrlCheckResponse().isEmpty()) {
// No threat exists.
} else {
// Threats exist.
}
}
}).addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// An error occurred during communication with the service.
if (e instanceof ApiException) {
// HMS Core (APK) error code and corresponding error description.
ApiException apiException = (ApiException) e;
Log.d(TAG, "Error: " + CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
// Note: If the status code is SafetyDetectStatusCode.CHECK_WITHOUT_INIT,
// you did not call the initUrlCheck() method or you have initiated a URL check request before the call is completed.
// If an internal error occurs during the initialization, you need to call the initUrlCheck() method again to initialize the API.
} else {
// An unknown exception occurred.
Log.d(TAG, "Error: " + e.getMessage());
}
}
});
b. Call the getUrlCheckResponse method of the returned UrlCheckResponse object to obtain the URL check result.
The result contains List<UrlCheckThreat>, which includes the detected URL threat type. If the list is empty, no threat is detected. Otherwise, you can call getUrlCheckResult in UrlCheckThreat to obtain the specific threat code. The sample code is as follows:
Code:
final EditText testRes = getActivity().findViewById(R.id.fg_call_urlResult);
List<UrlCheckThreat> list = urlCheckResponse.getUrlCheckResponse();
if (list.isEmpty()) {
testRes.setText("ok");
}
else{
for (UrlCheckThreat threat : list) {
int type = threat.getUrlCheckResult();
}
}
3. Close the URL check session.
If your app does not need to call the URLCheck API anymore or will not need to for a while, you can call the shutdownUrlCheck method to close the URL check session and release relevant resources.
Code:
SafetyDetect.getClient(this).shutdownUrlCheck();
Conclusion​Electronic fraud such as phone scams are constantly evolving and becoming more and more difficult to prevent, bringing great challenges to both developers and users. To combat such risks, developers must utilize technical means to identify phishing websites, malicious apps, and other risks, in order to safeguard users' personal information and property.
In this article, I demonstrated how HMS Core Safety Detect can be used to effectively combat electronic fraud. The whole integration process is straightforward and cost-efficient, and is a quick and effective way to build comprehensive security capabilities into an app.

Allow Users to Track Fitness Status in Your App

During workouts, users expect to be able to track their status and data in real time within the health or fitness app on their phone. Huawei phone users can link a piece of equipment, like a treadmill or spinner bike, via the Huawei Health app, and start and track their workout within the app. As a fitness and health app developer, you can read activity records from the Huawei Health app, and display the records in your app. It is even possible to control the workout status directly within your app, and obtain real-time activity data, without having to redirect users to the Huawei Health app, which helps users conveniently track their workout and greatly enhances the user experience. Here is how.
HMS Core Health Kit provides a wide range of capabilities for fitness and health app developers. Its extended capabilities open up a wealth of real time activity and health data and solutions specific to different scenarios. For example, after integrating the extended capabilities, you can call the APIs for starting, pausing, resuming, and stopping activities, to control activity status directly within your app, without redirecting users to the Huawei Health app. The Huawei Health app runs unobtrusively in the background throughout this entire process.
The extended capabilities also offer APIs for obtaining and halting the collection of real-time workout data. To prevent data loss, your app should call the API for obtaining real-time data before the workout starts, and avoid calling the API for halting the collection of real-time data before the workout ends. If the user links their phone with a Huawei wearable device via the Huawei Health app, the workout status in your app will be synched to the wearable device. This means that the wearable device will automatically display the workout screen when the user starts a workout in your app, and will stop displaying it as soon as the workout is complete. Make sure that you have applied for the right scopes from Huawei and obtained the authorization from users before API calling. Otherwise, API calling will fail. The following workouts are currently supported: outdoor walking, outdoor running, outdoor cycling, indoor running (on a treadmill), elliptical machine, rowing machine, and indoor cycling.
{
"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"
}
Redirecting to the device pairing screen
Demo​
Preparations​Applying for Health Kit​Before applying for Health Kit, you will need to apply for Account Kit first.
Integrating the HMS Core SDK​Before integrating the Health SDK, integrate the Account SDK first.
Before getting started, you need to integrate the HMS Core SDK into your app using Android Studio. Make sure that you use Android Studio V3.3.2 or later during the integration of Health Kit.
Development Procedure​Starting Obtaining Real-time Activity Data​1. Call the registerSportData method of the HiHealthDataStore object to start obtaining real time activity data.
2. Check the returned result through the request parameter HiSportDataCallback.
The sample code is as follows:
Code:
HiHealthDataStore.registerSportData(context, new HiSportDataCallback() {
@Override
public void onResult(int resultCode) {
// API calling result.
Log.i(TAG, "registerSportData onResult resultCode:" + resultCode);
}
@Override
public void onDataChanged(int state, Bundle bundle) {
// Real-time data change callback.
Log.i(TAG, "registerSportData onChange state: " + state);
StringBuffer stringBuffer = new StringBuffer("");
if (state == HiHealthKitConstant.SPORT_STATUS_RUNNING) {
Log.i(TAG, "heart rate : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_HEARTRATE));
Log.i(TAG, "distance : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_DISTANCE));
Log.i(TAG, "duration : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_DURATION));
Log.i(TAG, "calorie : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_CALORIE));
Log.i(TAG, "totalSteps : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_STEPS));
Log.i(TAG, "totalCreep : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_CREEP));
Log.i(TAG, "totalDescent : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_DESCENT));
}
}
});
Stopping Obtaining Real-time Activity Data​1. Call the unregisterSportData method of the HiHealthDataStore object to stop obtaining the real time activity data.
2. Check the returned result through the request parameter HiSportDataCallback.
The sample code is as follows:
Code:
HiHealthDataStore.unregisterSportData(context, new HiSportDataCallback() {
JSONObject jsonResult
@Override
public void onResult(int resultCode) {
// API calling result.
Log.i(TAG, "unregisterSportData onResult resultCode:" + resultCode);
}
@Override
public void onDataChanged(int state, Bundle bundle) {
// The API is not called at the moment.
}
});
Starting an Activity According to the Activity Type​1. Call the startSport method of the HiHealthDataStore object to start a specific type of activity.
2. Use the ResultCallback object as a request parameter to get the query result.
The sample code is as follows:
Code:
// Outdoor running.
int sportType = HiHealthKitConstant.SPORT_TYPE_RUN;
HiHealthDataStore.startSport(context, sportType, new ResultCallback() {
@Override
public void onResult(int resultCode, Object message) {
if (resultCode == HiHealthError.SUCCESS) {
Log.i(TAG, "start sport success");
}
}
});
3. For activities that depend on equipment like treadmills, rowing machines, elliptical machines, and stationary bikes, you will need to first check whether the relevant equipment has been paired in the Huawei Health app before starting the activity. The following uses a rowing machine as an example.
If there is one rowing machine paired, this machine will be connected by default, and the activity will then start in the background.
If the app is paired with more than one rowing machines, a pop-up window will display prompting the user to select a machine. After the user makes their choice, the window will disappear and the workout will start in the background.
If the app is not paired with any rowing machine, the user will be redirected to the device pairing screen in the Huawei Health app, before being returned to your app. The workout will then start in the background.
Starting an Activity Based on the Device Information​1. Call the startSportEx method of the HiHealthDataStore object, and pass the StartSportParam parameter for starting the activity. You can control whether to start the activity in the foreground or in the background by setting CharacteristicConstant.SportModeType.
2. Use the ResultCallback object as a request parameter to get the activity starting result.
The sample code is as follows:
Code:
// The following takes the rowing machine as an example.
// MAC address, with every two digits separated by a colon (:), for example, 11:22:33:44:55:66.
String macAddress = "11:22:33:44:55:66" ;
// Whether FTMP is supported. 0: no; 1: yes.
int isSupportedFtmp = CharacteristicConstant.FtmpType.FTMP_SUPPORTED.getFtmpTypeValue();
// Device type: rowing machine.
int deviceType = CharacteristicConstant.DeviceType.TYPE_ROWER_INDEX.getDeviceTypeValue();
// Activity type: rowing machine.
int sportType = CharacteristicConstant.EnhanceSportType.SPORT_TYPE_ROW_MACHINE.getEnhanceSportTypeValue();
// Construct startup parameters for device connection and activity control.
StartSportParam param = new StartSportParam(macAddress, isSupportedFtmp, deviceType, sportType);
// Whether to start the activity in the foreground (0) or background (1).
param.putInt(HiHealthDataKey.IS_BACKGROUND,
CharacteristicConstant.SportModeType.BACKGROUND_SPORT_MODE.getType());
HiHealthDataStore.startSportEx(mContext, param, new ResultCallback() {
@Override
public void onResult(int resultCode, Object message) {
if (resultCode == HiHealthError.SUCCESS) {
Log.i(TAG, "start sportEx success");
}
}
});
Stopping an Activity​1. Call the stopSport method of the HiHealthDataStore object to stop a specific type of activity. Note that you cannot use this method to stop activities started in the foreground.
2. Use the ResultCallback object as a request parameter to get the query result.
The sample code is as follows:
Code:
HiHealthDataStore.stopSport(context, new ResultCallback() {
@Override
public void onResult(int resultCode, Object message) {
if (resultCode == HiHealthError.SUCCESS) {
Log.i(TAG, "stop sport success");
}
}
});
Conclusion​Huawei phone users can use the Huawei Health app to bind wearable devices, start a workout and control their workout status, and track their workouts over time. When developing a fitness and health app, you can harness the capabilities in Health Kit and the Huawei Health app to get the best of all worlds: easy workout management free of annoying redirections. By calling the APIs provided by the kit's extended capabilities, you will be able to start, pause, resume, and stop workouts directly in your app, or obtain real time workout data from the Huawei Health app and display it in your app, with Huawei Health running in the background. This will considerably enhance the user experience, and make your fitness and health app much more appealing to a wider audience.
References​HMS Core Health Kit Development Guide
Bundle Keys for Real-time Activity
Applying for the HUAWEI ID Service

Categories

Resources