[Huawei Developers] Freemind R:
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.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120015746.24001063216173924803547584576294:50511124024402:2800:8D2A12E42E128EBF1B020188FE4AD8F8C18ADABB29F2C9013F902C190F964607.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120015746.24001063216173924803547584576294:50511124024402:2800:8D2A12E42E128EBF1B020188FE4AD8F8C18ADABB29F2C9013F902C190F964607.png[/IMG]

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.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120022803.62722655413333012532020283314023:50511124024402:2800:A53E304608D57D50413099371AF62517081C469865B925B268A1192B3FCAFF31.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120022803.62722655413333012532020283314023:50511124024402:2800:A53E304608D57D50413099371AF62517081C469865B925B268A1192B3FCAFF31.png[/IMG]

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.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120022859.53732194478068512577363048929761:50511124024402:2800:62A3574C013C30579BCDA320CFD1DFFEC16C1BF41F3CE1C31AC4D3AB73B58F48.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120022859.53732194478068512577363048929761:50511124024402:2800:62A3574C013C30579BCDA320CFD1DFFEC16C1BF41F3CE1C31AC4D3AB73B58F48.png[/IMG]

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.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120023028.29281877267184609731488504531959:50511124024402:2800:73036CD21DECC049AB583CAEBBAF2AD4E458256B54125B807A085CD62082D7A5.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120023028.29281877267184609731488504531959:50511124024402:2800:73036CD21DECC049AB583CAEBBAF2AD4E458256B54125B807A085CD62082D7A5.png[/IMG]

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.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120023203.44931389724611938427449090285213:50511124024402:2800:BF87D422B340097896B64558847F0A73D4CB0A5A6F10FB75E3ED02851AE64D1D.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20201120023203.44931389724611938427449090285213:50511124024402:2800:BF87D422B340097896B64558847F0A73D4CB0A5A6F10FB75E3ED02851AE64D1D.png[/IMG]

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.

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.

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.

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.

/**

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