Create a Social Networking App that Connects Users in New Ways with Nearby Service

Sherlock
Sherlock
Nov 24, 2020 · 6 min read
Image for post
Image for post

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
  • 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.
Image for post
Image for post
  • 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.

Image for post
Image for post
  • 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.

Image for post
Image for post
  • 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.
Image for post
Image for post
  • 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.

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 NearbyPeoplePresenter(Context mContext, INearbyPeopleView view) {super(mContext, view);nearbyAgent = new NearbyAgent(mContext, new NearbyAgent.INearbyMessageView() {@Overridepublic void onMessageFound(MessageBean messageBean) {// notify view when found someoneview.onMemberChanged(false,messageBean);}@Overridepublic void onMessageLost(MessageBean messageBean) {view.onMemberChanged(true,messageBean);}@Overridepublic 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.

public CreateGroupPresenter(Context mContext, ICreateGroupView view) {super(mContext, view);nearbyAgent = new NearbyAgent(mContext, new NearbyAgent.INearbyMessageView() {@Overridepublic void onMessageFound(MessageBean messageBean) {view.onPeopleFound(messageBean);}@Overridepublic void onMessageLost(MessageBean messageBean) {}@Overridepublic 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() {@Overridepublic void onMessageFound(MessageBean messageBean) {view.onMessageFound(messageBean);}@Overridepublic void onMessageLost(MessageBean messageBean) {}@Overridepublic 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() {@Overridepublic void onFound(String endpointId, ScanEndpointInfo discoveryEndpointInfo) {Log.d(TAG, "onFound -- Nearby Connection Demo app: onFound endpoint: " + endpointId);view.onFound(endpointId,discoveryEndpointInfo);}@Overridepublic 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

Huawei Developers

Huawei Developers

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store