NearbyService超簡單集成教程get!助你打造一款更加便捷的社交聊天類應用


背景

“附近的人”、“面對面建群”、“近距離點對點本地聊天”…這幾個常見的功能都會出現在各大社交類軟件中。可通常情況下,“附近的人”基本都只能發現距離自己幾百米甚至幾公里以外的人,如何縮小這個距離,實現與數米距離內的人打招呼呢?“面對面建群”如何精確的發現就在自己身邊的人呢?如何不經過雲服務即可直接通信與好友聊天呢?Nearby Service都可以幫你實現!下面將為大家詳細講解Nearby Service集成教程,助你打造一款更加便捷的社交聊天類應用。

應用場景介紹

這里為大家帶來一個集成了Nearby Service的示例應用,這個應用利用Nearby Service能做到發現附近的人,以及基於這個能力可以實現如面對面建群、群聊、私密聊、遷移聊天記錄等功能。

  • 附近的人

可以為用戶精准的發現附近數米的人,支持用戶發現同處一室的朋友,如會議室、展廳、酒吧、咖啡廳等;

在這里插入圖片描述

  • 面對面建群

利用Nearby Service進行建群,只需在端側即可完成建群動作,位置精確,只有同處一地的人能夠進群。

在這里插入圖片描述

  • 隨心聊

利用Nearby Service可以實現近距離范圍內不加好友的群聊,新朋友只需到范圍附近即可自動入群;離開對應范圍自動退出。

在這里插入圖片描述

  • 私密聊

利用Nearby Service可以實現近距離本地點對點聊天。通信只在兩個設備間進行,數據加密不上雲,無需擔心信息泄露;在高鐵、地鐵等信號不好的場所時也可以進行通信。

在這里插入圖片描述

  • 遷移聊天記錄

不僅如此,Nearby Service還提供了強大的文件傳輸功能。當用戶有多個設備需要遷移聊天記錄時,可利用Nearby Service的通信接口,實現高速、免流量的數據遷移。

工具准備

  1. 2台安卓手機或更多

  2. 開發工具 Android Studio(3.X or later)

構建示例應用

  • 在Android Studio中導入示例源代碼。

  • 注冊成為華為開發者。

  • 參考Nearby Service 開發准備在華為應用市場創建一個您的應用。注意:需要下載“agconnect-services.json”文件和參考指導生成簽名證書並放置在app/目錄下。

  • 使用adb命令將生成的apk文件安裝到測試手機。

關鍵代碼

示例應用中使用的接口在官方文檔Nearby Service Guides中有詳細的介紹。

這個示例應用采用MVP的模式進行構建,如您想查看源代碼,請根據代碼路徑: com\huawei\hms\nearby\im找到相應的類。

1. 附近的人

如下面代碼所示NearbyPeoplePresenter類在初始化時需將view對象傳入。當調用NearbyPeoplePresenter.findNearbyPeople()發現附近的人時,調用view的接口執行后續的動作。

INearbyPeopleView和后面步驟中的xxxView是一組接口,它們的具體實現是對應的Activity對象,代碼路徑是:com\huawei\hms\nearby\im\ui\adapter。

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. 面對面建群

與“附近的人”類似,CreateGroupPresenter.java類在初始化時傳入view對象,當調用joinGroup(groupId)接口時會加入該群組,結果會通過調用view的接口返回。

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. 隨心聊

類GroupChatPresenter.java在初始化時需傳入view對象。業務代碼調用broadcastMessage(groupId, sendContent)發送消息到指定的群組,groupId為空時不限定群組;調用findMessage(groupId)發現指定群組的消息,發現后調用view接口返回消息。

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. 私密聊

私密聊的實現與上述接口有所不同,類NearbyConnectionPresenter.java提供了4個接口:

  • findNearbyPeople():發現附近的人

  • requestConnect():與對方建立連接

  • sendMessage(String msgStr):發送字符串類型消息

  • sendFile(Uri uri):發送文件

/**
  * 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;
 }

更多詳情


原文鏈接:
https://developer.huawei.com/consumer/cn/forum/topic/0201415949786580446?fid=18&pid=0301415949786580897
作者:胡椒


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM