如下視頻是對融雲 Android SDK 開發使用的詳細講解,您能夠在閱讀文檔時配合學習。html
更多視頻教程以下:java
開發者在集成融雲即時通信、實時網絡能力前,需前往融雲官方網站註冊建立融雲開發者賬號。android
您能夠到融雲官方網站下載融雲 SDK。融雲 SDK 各部分功能以插件化的形式獨立提供,開發者能夠根據本身的須要,自由組合下載。各組件的功能以下:git
名稱 | 功能介紹 | 支持的 CPU 架構 |
---|---|---|
IMKit |
融雲 IM 界面組件 | —— |
IMLib |
融雲 IM 通信能力庫 | armeabi, armeabi-v7a, arm64-v8a, x86 |
CallKit |
融雲音視頻界面組件 | —— |
CallLib |
融雲音視頻核心組件 | armeabi-v7a, x86 |
LocationLib |
融雲位置相關庫 | —— |
PushLib |
融雲第三方推送庫 | armeabi, armeabi-v7a, arm64-v8a, x86 |
RedPacket |
融雲紅包相關組件 | —— |
您要進行應用開發以前,須要先在融雲開發者平臺建立應用。若是您已經註冊了融雲開發者賬號,請前往融雲開發者平臺建立應用。github
您建立完應用後,首先須要瞭解的是 App Key / Secret,它們是融雲 SDK 鏈接服務器所必須的標識,每個 App 對應一套 App Key / Secret。針對開發者的生產環境和開發環境,咱們提供兩套 App Key / Secret,兩套環境的功能徹底一致。您在應用最終上線前,使用開發環境便可。web
Token 稱爲用戶令牌,App Key 是您的 App 的惟一標識,Token 則是您 App 上的每個用戶的身份受權象徵。您能夠經過提交 userId 等信息來得到一個該用戶對應的 Token,並使用這個 Token 做爲該用戶的惟一身份憑證與其餘用戶進行通訊。數據庫
Token 的主要做用是身份受權和安全,所以不能經過客戶端直接訪問融雲服務器獲取 Token,您必須經過 Server API 從融雲服務器 獲取 Token 返回給您的 App,並在以後鏈接時使用。詳細描述請參考 Server 開發指南中的用戶服務和獲取 Token 方法小節。json
經過 API 調試,您能夠獲得一個 Token 返回值。您就能夠直接使用這個 Token 爲這位用戶進行發送和接受消息。api
環境要求數組
在您集成融雲 SDK 前環境要求以下:
咱們建議初次集成 SDK 的用戶,先建立一個空項目來集成融雲的 SDK,而後再考慮加入您的工程。
以 Module 形式導入前面下載的融雲 SDK 裏面的各個組件。
打開您的工程, File -> New -> Import Module
打開您從官網下載的融雲 SDK,選擇 IMLib。如圖:
根據您的須要,以一樣的步驟導入SDK裏的其它組件: IMKit, CallKit, CallLib, RedPacket。
將 PushLib 中的 jar 包 和 pushDaemon -> libs 目錄下應用所支持平臺的 so 拷貝到您應用的 libs 目錄下,另外還須要將 pushDaemon -> executable 目錄下各平臺的可執行文件 push_daemon 拷貝到您應用 Module 的 assets 目錄下。如圖:
注意 : 放置 so 的文件夾位置須要和您 build.gradle 文件中配置的 jni 目錄一致。
將 LocationLib 裏的 jar 包拷貝到您應用的 libs 目錄下(若是不須要位置功能,可跳過此步驟)。
注意
音視頻通話組件 CallLib 僅支持 armeabi-v7a 和 x86 架構 CPU (組件功能),若是您使用了咱們的音視頻通話功能,注意須要把 IMLib 和 PushLib 組件中其它 CPU 架構的 so 刪除。或者您也能夠在應用的 build.gradle 文件中增長以下配置來過濾 so :
defaultConfig {
applicationId "XXX" ... ndk { abiFilters "armeabi-v7a", "x86" } }
打開應用的 build.gradle,在 dependencies 中添加相應模塊的依賴。如圖:
打開 IMLib Module 的 AndroidManifest.xml 文件,把 meta-data RONG_CLOUD_APP_KEY 的值修改成您本身的 AppKey. 如圖:
<meta-data
android:name="RONG_CLOUD_APP_KEY" android:value="您的應用 AppKey" />
打開應用的 App Module 的 AndroidManifest.xml 文件, 把從高德官網獲取的 AppKey 添加到 meta-data 裏 (若是您不使用位置功能,可跳過此步驟)。
<meta-data
android:name="com.amap.api.v2.apikey" android:value="高德地圖的 AppKey" />
在應用的 App Module 的 AndroidManifest.xml 文件中,添加 FileProvider 相關配置,修改 android:authorities 爲 「您的應用的包名稱.FileProvider」。
<provider android:name="android.support.v4.content.FileProvider" android:authorities="您的應用包名.FileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/rc_file_path" /> </provider>
在整個應用程序全局,您只須要調用一次 init
方法。對於快速集成,咱們建議您在 App 主進程初始化,您只須要實現一句函數,如下爲融雲 Demo 代碼示例:
public class App extends Application { @Override public void onCreate() { super.onCreate(); RongIM.init(this); } }
關於初始化的注意事項
融雲的 SDK 使用了跨進程機制來進行通訊,運行後您的 App 後您會發現如下三個進程: 一、您的應用進程;二、您的應用進程: ipc,這是融雲的通訊進程;三、io.rong.push,這是融雲的推送進程。
鏈接服務器前,確認已經過融雲 Server API 接口獲取 Token。
connect() 方法在整個應用只須要調用一次,且必須在主進程調用。若是鏈接失敗, SDK 會自動啓動重連機制,進行最多10次重連,分別是1, 2, 4, 8, 16, 32, 64, 128, 256, 512秒後。若是仍然沒有鏈接成功,還會在檢測網絡狀態變化時再次重連。應用不須要作額外的重連操做。
/** * <p>鏈接服務器,在整個應用程序全局,只須要調用一次,需在 {@link #init(Context)} 以後調用。</p> * <p>若是調用此接口遇到鏈接失敗,SDK 會自動啓動重連機制進行最多10次重連,分別是1, 2, 4, 8, 16, 32, 64, 128, 256, 512秒後。 * 在這以後若是仍沒有鏈接成功,還會在當檢測到設備網絡狀態變化時再次進行重連。</p> * * @param token 從服務端獲取的用戶身份令牌(Token)。 * @param callback 鏈接回調。 * @return RongIM 客戶端核心類的實例。 */ private void connect(String token) { if (getApplicationInfo().packageName.equals(App.getCurProcessName(getApplicationContext()))) { RongIM.connect(token, new RongIMClient.ConnectCallback() { /** * Token 錯誤。能夠從下面兩點檢查 1. Token 是否過時,若是過時您須要向 App Server 從新請求一個新的 Token * 2. token 對應的 appKey 和工程裏設置的 appKey 是否一致 */ @Override public void onTokenIncorrect() { } /** * 鏈接融雲成功 * @param userid 當前 token 對應的用戶 id */ @Override public void onSuccess(String userid) { Log.d("LoginActivity", "--onSuccess" + userid); startActivity(new Intent(LoginActivity.this, MainActivity.class)); finish(); } /** * 鏈接融雲失敗 * @param errorCode 錯誤碼,可到官網 查看錯誤碼對應的註釋 */ @Override public void onError(RongIMClient.ErrorCode errorCode) { } }); } }
融雲 IMKit SDK 使用了 Fragment 做爲會話列表和會話界面的組件,其優勢是支持各類嵌套方式,更符合您的定製化需求。 下面說明如何在 Activity 裏以靜態方式加載融雲 Fragment.
這是您的會話列表 Activity 對應的佈局文件:conversationlist.xml。注意 android:name 固定爲融雲的 ConversationListFragment。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/conversationlist" android:name="io.rong.imkit.fragment.ConversationListFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
public class ConversationListActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.conversationlist); } }
融雲 SDK 是經過隱式調用的方式來實現界面跳轉的。所以您須要在 AndroidManifest.xml 中,您的會話列表 Activity 下面配置 intent-filter,其中,android:host 是您應用的包名,須要手動修改,其餘請保持不變。
<!--會話列表--> <activity android:name="io.rong.fast.activity.ConversationListActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/conversationlist" android:scheme="rong" /> </intent-filter> </activity>
融雲支持在會話列表頁面自定義某種類型的會話以聚合形式展現,好比,定義全部私聊會話聚合顯示,則在會話列表頁全部私聊會話聚合顯示爲「個人私人會話」,點擊「個人私人會話」,會進入全部私聊會話的展現頁面,這個頁面即爲聚合會話列表,如圖:
若是您的應用定義了聚合會話,請按照下面的說明進行相應配置,不然能夠直接跳過此步驟。
自定義聚合會話列表請參考會話列表自定義。
這是您的聚合會話列表 Activity 對應的佈局文件:subconversationlist.xml。 注意 android:name 固定爲融雲的 SubConversationListFragment。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/subconversationlist" android:name="io.rong.imkit.fragment.SubConversationListFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
public class SubConversationListActivtiy extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.subconversationlist); } }
在 AndroidManifest.xml 中, 聚合會話 Activity 下面配置 intent-filter。 注意請修改 android:host 爲您應用的包名,其餘保持不變。
<!--聚合會話列表--> <activity android:name="io.rong.fast.activity.SubConversationListActivtiy" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/subconversationlist" android:scheme="rong" /> </intent-filter> </activity>
會話 Fragment 跟會話列表是徹底一致的,您能夠用一樣的方式快速的配置好。
這是您的會話 Activity 對應的佈局文件 conversation.xml,注意 android:name 固定爲融雲的 ConversationFragment。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/conversation" android:name="io.rong.imkit.fragment.ConversationFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
public class ConversationActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.conversation); } }
在 AndroidManifest.xml 中,會話 Activity 下面配置 intent-filter。 注意請修改 android:host 爲您應用的包名,其餘保持不變。
<!--會話界面--> <activity android:name="io.rong.fast.activity.ConversationActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/conversation/" android:scheme="rong" /> </intent-filter> </activity>
會話列表及界面實現的視頻教程
視頻講解會話界面、會話列表的配置以及 Fragment
的嵌套和 ViewPager+Fragment
的使用。
RongIM.getInstance().startConversationList();
去喚起會話列表。
會話界面 Title 配置的視頻教程
此視頻講解了會話界面的 Title
如何編寫,以及怎樣經過 intent
的方式拿到 targetId
、暱稱、會話類型等。
完成以上配置後,便可啓動會話及會話列表界面,啓動界面操做必須在執行初始化 SDK 方法 init
及鏈接融雲服務器 connect
以後進行,示例以下:
/** * <p>啓動會話界面。</p> * <p>使用時,能夠傳入多種會話類型 {@link io.rong.imlib.model.Conversation.ConversationType} 對應不一樣的會話類型,開啓不一樣的會話界面。 * 若是傳入的是 {@link io.rong.imlib.model.Conversation.ConversationType#CHATROOM},sdk 會默認調用 * {@link RongIMClient#joinChatRoom(String, int, RongIMClient.OperationCallback)} 加入聊天室。 * 若是你的邏輯是,只容許加入已存在的聊天室,請使用接口 {@link #startChatRoomChat(Context, String, boolean)} 而且第三個參數爲 true</p> * * @param context 應用上下文。 * @param conversationType 會話類型。 * @param targetId 根據不一樣的 conversationType,多是用戶 Id、討論組 Id、羣組 Id 或聊天室 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ public void startConversation(Context context, Conversation.ConversationType conversationType, String targetId, String title) /** * 啓動會話列表界面。 * * @param context 應用上下文。 * @param supportedConversation 定義會話列表支持顯示的會話類型,及對應的會話類型是否聚合顯示。 * 例如:supportedConversation.put(Conversation.ConversationType.PRIVATE.getName(), false) 非聚合式顯示 private 類型的會話。 */ public void startConversationList(Context context, Map<String, Boolean> supportedConversation) /** * 啓動聚合後的某類型的會話列表。<br> 例如:若是設置了單聊會話爲聚合,則經過該方法能夠打開包含全部的單聊會話的列表。 * * @param context 應用上下文。 * @param conversationType 會話類型。 */ public void startSubConversationList(Context context, Conversation.ConversationType conversationType)
當您的應用處於後臺運行或者和融雲服務器 disconnect() 的時候,若是收到消息,融雲 SDK 會以通知形式提醒您。因此您還須要自定義一個繼承融雲 PushMessageReceiver 的廣播接收器,用來接收提醒通知。如圖:
public class SealNotificationReceiver extends PushMessageReceiver { @Override public boolean onNotificationMessageArrived(Context context, PushNotificationMessage message) { return false; // 返回 false, 會彈出融雲 SDK 默認通知; 返回 true, 融雲 SDK 不會彈通知, 通知須要由您自定義。 } @Override public boolean onNotificationMessageClicked(Context context, PushNotificationMessage message) { return false; // 返回 false, 會走融雲 SDK 默認處理邏輯, 即點擊該通知會打開會話列表或會話界面; 返回 true, 則由您自定義處理邏輯。 } }
具體可參考文檔。
融雲 SDK 提供如下兩種斷開鏈接的方法:
若是您想在斷開和融雲的鏈接後,有新消息時,仍然可以收到推送通知,調用 disconnect() 方法。
/** * <p>斷開與融雲服務器的鏈接。當調用此接口斷開鏈接後,仍然能夠接收 Push 消息。</p> * <p>若想斷開鏈接後不接受 Push 消息,能夠調用{@link #logout()}</p> */ public void disconnect()
若是斷開鏈接後,有新消息時,不想收到任何推送通知,調用 logout() 方法。
/** * <p>斷開與融雲服務器的鏈接,而且再也不接收 Push 消息。</p> * <p>若想斷開鏈接後仍然接受 Push 消息,能夠調用 {@link #disconnect()}</p> */ public void logout()
經過以上步驟,您即完成了融雲 SDK 的集成。
您也能夠參考下面的快速集成 Demo 來快速集成融雲 SDK。 Android Studio 快速集成。
設計原理說明:
融雲認爲,每個設計良好且功能健全的 App 都應該可以在本地獲取、緩存並更新用戶信息。因此,融雲不維護用戶基本信息(用戶 Id
、暱稱
、頭像
)。此外,App 提供用戶信息也避免了因爲緩存致使的用戶信息更新不及時,App 中不一樣界面上的用戶信息不統一(好比:一部分 App 從 App 服務器上獲取並顯示,一部分由融雲服務器獲取並顯示),可以得到最佳的用戶體驗。
融雲提供了兩種方式從 App 的數據源顯示用戶暱稱和頭像
。
一、設置用戶信息提供者:
調用 RongIM.setUserInfoProvider
方法設置 UserInfoProvider
。用戶信息提供者採用 Provider
模式,即您提供給融雲的 IMKit 一個 UserInfoProvider
,當融雲的 IMKit 須要使用用戶信息的時候,調用您傳入的 UserInfoProvider.getUserInfo
方法,向您獲取用戶信息。因此您在 UserInfoProvider.getUserInfo
方法中,須要根據傳入的 userId 參數,向咱們返回對應的用戶信息。
/** * 設置用戶信息的提供者,供 RongIM 調用獲取用戶名稱和頭像信息。 * * @param userInfoProvider 用戶信息提供者。 * @param isCacheUserInfo 設置是否由 IMKit 來緩存用戶信息。<br> * 若是 App 提供的 UserInfoProvider * 每次都須要經過網絡請求用戶數據,而不是將用戶數據緩存到本地內存,會影響用戶信息的加載速度;<br> * 此時最好將本參數設置爲 true,由 IMKit 將用戶信息緩存到本地內存中。 * @see UserInfoProvider */ RongIM.setUserInfoProvider(new RongIM.UserInfoProvider() { @Override public UserInfo getUserInfo(String userId) { return findUserById(userId);//根據 userId 去你的用戶系統裏查詢對應的用戶信息返回給融雲 SDK。 } }, true);
不少時候 getUserInfo 這個方法會去 App 服務器異步獲取用戶信息,不能實時返回用戶信息。這種狀況下,請在成功獲取到用戶信息的異步回調中使用下面方法來刷新信息。
刷新用戶信息:
/** * 刷新用戶緩存數據。 * * @param userInfo 須要更新的用戶緩存數據。 */ RongIM.getInstance().refreshUserInfoCache(new UserInfo("userId", "啊明", Uri.parse("http://rongcloud-web.qiniudn.com/docs_demo_rongcloud_logo.png")));
刷新羣組信息
/** * 刷新羣組緩存數據。 * * @param group 須要更新的羣組緩存數據。 */ public void refreshGroupInfoCache(Group group)
刷新討論組信息
/** * 刷新討論組緩存數據,可用於討論組修更名稱後刷新討論組內其餘人員的緩存數據。 * * @param discussion 須要更新的討論組緩存數據。 */ public void refreshDiscussionCache(Discussion discussion)
二、使用消息攜帶用戶信息
當 App 自己沒有用戶系統或者由於某些緣由不方便使用上述用戶信息提供者的時候,可使用消息攜帶用戶信息來發送給消息接收方。
請注意這種方式不要和用戶信息提供者混用。而且,這種方式會在每條發送的消息裏都攜帶當前登錄用戶的信息,增長消息的長度。
首先,須要使用 setCurrentUserInfo
方法來設置當前的用戶信息。
/** * 設置當前用戶信息, * * @param userInfo 當前用戶信息 */ RongIM.getInstance().setCurrentUserInfo(userInfo);
接下來,在 init
以後調用下面方法設置消息攜帶用戶信息。
/** * 設置消息體內是否攜帶用戶信息。 * * @param state 是否攜帶用戶信息,true 攜帶,false 不攜帶。 */ RongIM.getInstance().setMessageAttachedUserInfo(true);
接收方在接收到消息後,SDK 會自動從消息中取出用戶信息,並顯示到 UI 上。
常見問題:
如下視頻主要講解融雲 IMKit
中用戶信息的實現包括頭像及暱稱。
單聊是最基本的聊天界面,提供文字、表情、語音片斷、圖片、VoIP 等多種輸入內容,解決 App 內用戶的溝通瓶頸。會話關係由融雲負責創建並保持,退出聊天界面或者離線後能夠收到推送通知。
前提條件:
打開單聊窗口:
/** * 啓動單聊界面。 * * @param context 應用上下文。 * @param targetUserId 要與之聊天的用戶 Id。 * @param title 聊天的標題,開發者須要在聊天界面經過 intent.getData().getQueryParameter("title") * 獲取該值, 再手動設置爲聊天界面的標題。 */ RongIM.getInstance().startPrivateChat(getActivity(), "9527", "標題");
常見問題:
討論組業務的描述,請參見新手指南中的說明。
前提條件:
打開討論組聊天窗口:
/** * 啓動已經建立的討論組聊天界面。 * * @param context 應用上下文。 * @param targetDiscussionId 要啓動的討論組 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ RongIM.getInstance().startDiscussionChat(getActivity(), "9527", "標題");
建立討論組會話並進入會話界面:
/** * 建立討論組會話並進入會話界面。 * 討論組建立成功後,會返回討論組 id。 * * @param context 應用上下文。 * @param targetUserIds 要與之聊天的討論組用戶 Id 列表。 * @param title 聊天的標題,若是傳入空值,則默認顯示與之聊天的用戶名稱。 * @param callback 討論組回調,成功時,返回討論組 id。 */ public void createDiscussionChat(final Context context, final List<String> targetUserIds, final String title, final RongIMClient.CreateDiscussionCallback callback) {})
建立討論組
/** * 建立討論組。 * * @param name 討論組名稱,如:當前全部成員的名字的組合。 * @param userIdList 討論組成員 Id 列表。 * @param callback 建立討論組成功後的回調。 */ public void createDiscussion(final String name, final List<String> userIdList, final RongIMClient.CreateDiscussionCallback callback)
添加討論組成員:
同一個用戶最多可加入 500 個討論組。
ArrayList<String> userIds = new ArrayList<String>(); userIds.add("101");//增長 userId。 userIds.add("102");//增長 userId。 userIds.add("103");//增長 userId。 /** * 添加一名或者一組用戶加入討論組。 * * @param discussionId 討論組 Id。 * @param userIdList 邀請的用戶 Id 列表。 * @param callback 執行操做的回調。 */ RongIM.getInstance().addMemberToDiscussion("9527", userIds, new RongIMClient.OperationCallback() { @Override public void onSuccess() { } @Override public void onError(RongIMClient.ErrorCode errorCode) { } });
移除討論組成員:
/** * 供建立者將某用戶移出討論組。 * * 移出本身或者調用者非討論組建立者將產生 {@link RongIMClient.ErrorCode#UNKNOWN} 錯誤。 * * @param discussionId 討論組 Id。 * @param userId 用戶 Id。 * @param callback 執行操做的回調。 */ RongIM.getInstance().removeMemberFromDiscussion("discussionId_9527", "user_9527", new RongIMClient.OperationCallback() { @Override public void onSuccess() { } @Override public void onError(RongIMClient.ErrorCode errorCode) { } });
討論組人數上限設置:
討論組人數在服務端有上限限制,爲 500 人,客戶端根據具體的業務需求,能夠經過配置文件配置討論組人數上限,請在 res/values/rc_config.xml 文件中修改, xml 文件以下:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="discussion_member_max_count">50</integer> </resources>
羣組業務的描述,請參見新手指南中的說明。
羣組信息與羣成員信息是由 App 自已提供並進行維護管理,融雲只是同步羣組關係數據,並不保存羣組的具體信息,融雲會根據開發者同步的羣組數據,計算羣組的成員信息並羣發消息。因此,當界面組件建立會話須要顯示羣組信息時,須要向 App 獲取。App 須要設置一個羣組信息提供者給 IMKit,以便 IMKit 讀取好友關係。
前提條件:
啓動羣組聊天界面:
/** * 啓動羣組聊天界面。 * * @param context 應用上下文。 * @param targetGroupId 要聊天的羣組 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ RongIM.getInstance().startGroupChat(getActivity(), "9527", "標題");
客戶端的全部羣組操做都須要請求您的 App Server, 您的 App Server 能夠根據本身的邏輯進行管理和控制,而後經過 Server API 接口進行羣組操做,並將結果返回給客戶端。
詳請見 Server API 羣組服務接口。
如下展現了客戶端進行羣組操做的流程:
建立羣組
加入羣組
退出羣組
解散羣組
設置羣組信息
獲取羣組成員列表
獲取羣組列表
聊天室業務的描述,請參見新手指南中的說明。
聊天室與羣組最大的不一樣在於,聊天室的消息沒有 Push 通知,也沒有成員的概念。想參與聊天室聊天,接收聊天室消息,加入聊天室便可;不參與聊天室聊天,不接收消息,退出聊天室便可。IMKit 組件中已經內置了加入和退出聊天室的接口調用,您直接啓動便可:
前提條件:
啓動聊天室界面:
/** * <p>啓動聊天室會話。</p> * <p>設置參數 createIfNotExist 爲 true,對應到 kit 中調用的接口是 * {@link RongIMClient#joinChatRoom(String, int, RongIMClient.OperationCallback)}. * 若是聊天室不存在,則自動建立並加入,若是回調失敗,則彈出 warning。</p> * <p>設置參數 createIfNotExist 爲 false,對應到 kit 中調用的接口是 * {@link RongIMClient#joinExistChatRoom(String, int, RongIMClient.OperationCallback)}. * 若是聊天室不存在,則返回錯誤 {@link io.rong.imlib.RongIMClient.ErrorCode#RC_CHATROOM_NOT_EXIST},而且會話界面會彈出 warning. * </p> * * @param context 應用上下文。 * @param chatRoomId 聊天室 id。 * @param createIfNotExist 若是聊天室不存在,是否建立。 */ public void startChatRoomChat(Context context, String chatRoomId, boolean createIfNotExist);
加入聊天室
加入聊天室,若是聊天室不存在,則建立聊天室並加入;若是已經存在,則直接加入。
/** * 加入聊天室。 * <p>若是聊天室不存在,sdk 會建立聊天室並加入,若是已存在,則直接加入</p> * <p>加入聊天室時,能夠選擇拉取聊天室消息數目。</p> * * @param chatroomId 聊天室 Id。 * @param defMessageCount 進入聊天室拉取消息數目,-1 時不拉取任何消息,0 時拉取 10 條消息,最多隻能拉取 50 條。 * @param callback 狀態回調。 */ public void joinChatRoom(final String chatroomId, final int defMessageCount, final RongIMClient.OperationCallback callback)
加入已經存在的聊天室
/** * 加入已存在的聊天室。 * <p>若是聊天室不存在,則加入失敗</p> * <p>加入聊天室時,能夠選擇拉取聊天室消息數目。</p> * * @param chatroomId 聊天室 Id。 * @param defMessageCount 進入聊天室拉取消息數目,-1 時不拉取任何消息,0 時拉取 10 條消息,最多隻能拉取 50 條。 * @param callback 狀態回調。 */ public void joinExistChatRoom(final String chatroomId, final int defMessageCount, final RongIMClient.OperationCallback callback)
聊天室拉取消息數設置:
進入聊天室時默認拉取消息數爲 10 條,根據需求可經過配置文件修改拉取消息條數,建議拉取消息數不超過 50 條,請在 res/values/rc_config.xml 文件中修改,爲 -1 表示不獲取任何歷史消息,0 表示不特殊設置而使用 SDK 默認的設置(默認爲獲取10條),最大值爲50。 xml 文件以下:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="rc_chatroom_first_pull_message_count">10</integer> </resources>
前提條件:
打開系統會話聊天界面:
/** * 啓動系統會話聊天界面。 * * @param context 應用上下文。 * @param conversationType 開啓會話類型。 * @param targetId 目標 Id; * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ RongIM.getInstance().startConversation(getActivity(), Conversation.ConversationType.SYSTEM, "9527", "標題");
IMKit 中提供封裝好的客服功能和 UI 界面,輕鬆的幾行代碼就能完成集成,爲應用中用戶提供優質的客服服務。
前提條件:
客服 ID
。打開客服聊天界面:
//首先須要構造使用客服者的用戶信息 CSCustomServiceInfo.Builder csBuilder = new CSCustomServiceInfo.Builder(); CSCustomServiceInfo csInfo = csBuilder.nickName("融雲").build(); /** * 啓動客戶服聊天界面。 * * @param context 應用上下文。 * @param customerServiceId 要與之聊天的客服 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 * @param customServiceInfo 當前使用客服者的用戶信息。{@link io.rong.imlib.model.CSCustomServiceInfo} */ RongIM.getInstance().startCustomerServiceChat(getActivity(), id, "在線客服",csInfo);
使用咱們的客服須要集成 ConversationFragment
到 Activity
中 ,當您退出這個 Activity
的時候調用以下代碼:
@Override public void onBackPressed() { ConversationFragment fragment = (ConversationFragment) getSupportFragmentManager().findFragmentById(R.id.conversation); if(!fragment.onBackPressed()) { finish(); } }
當觸發 onKeyDown
事件的時候,作如下處理:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); }
目的就是爲了讓咱們的 ConversationFragment
捕捉到 back
事件,而後彈出 Dialog
。
退出客服界面是否關閉客服設置
在 rc_config.xml
配置文件中,設置退出客服界面後是否關閉客服功能,默認爲 true
退出後關閉客服不接收客服消息,爲 false
時退出客服界面後不關閉客服,還能正常接收客服消息。
<resources> <!-- 退出客服頁面是否關閉客服 --> <bool name="rc_stop_custom_service_when_quit">true</bool> </resources>
客服界面提示窗自定義
客服界面的提示窗口,首先集成一個自定義的類繼承自 ConversationFragment, 而後在自定義類中重寫 onCustomServiceWarning() 方法,以下圖:
機器人模式的評價和人工模式的評價,能夠經過在自定義類中重寫 onCustomServiceEvaluation() 方法來自定義,以下圖:
融雲公衆服務
是爲應用開發者和公衆賬號運營者提供的鏈接服務產品,經過融雲公衆服務,App 能夠具有爲本身的用戶提供公衆賬號服務的能力和資源。
公衆服務包括
:應用公衆服務
和公衆服務平臺
。
應用公衆服務
:是爲應用開發者提供的 App 內建公衆服務能力,經過在融雲開發者站點建立 App 公衆號,實現應用內的公衆服務。
公衆服務平臺
:是在應用開發者和公衆賬號運營者之間創建的對接平臺,應用開發者能夠經過平臺引入公衆服務資源,幫助 App 快速覆蓋用戶需求,公衆賬號持有者經過平臺能夠有機會向全部集成融雲 SDK 的 App 提供服務,進而得到更加精準更加豐富的受衆渠道。
開發者可在 融雲開發者平臺 的公衆服務模塊中,經過添加公衆服務
或應用公衆服務
中的公衆號到自已的應用中。
IMKit
組件中已經內置了訂閱和取消訂閱公衆號的接口調用,您直接啓動便可:
前提條件:
打開應用公衆服務會話界面:
/** * 啓動應用公衆服務會話界面。 * * @param context 應用上下文。 * @param conversationType 開啓會話類型。 * @param targetId 目標 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ RongIM.getInstance().startConversation(getActivity(), Conversation.ConversationType.APP_PUBLIC_SERVICE, "9527", "公衆賬號標題");
打開公衆服務號會話界面:
/** * 啓動公衆服務號會話界面。 * * @param context 應用上下文。 * @param conversationType 開啓會話類型。 * @param targetId 目標 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ RongIM.getInstance().startConversation(getActivity(), Conversation.ConversationType.PUBLIC_SERVICE, "9527", "公衆賬號標題");
打開應用公衆服務信息界面:
/** * 啓動應用公衆服務信息界面。 * * @param context 應用上下文。 * @param conversationType 會話類型。 * @param targetId 目標 Id。 */ RongIM.getInstance().startPublicServiceProfile(getActivity(), Conversation.ConversationType.APP_PUBLIC_SERVICE, "9527");
打開公共服務號信息界面:
/** * 啓動公共服務號信息界面。 * * @param context 應用上下文。 * @param conversationType 會話類型。 * @param targetId 目標 Id。 */ RongIM.getInstance().startPublicServiceProfile(getActivity(), Conversation.ConversationType.PUBLIC_SERVICE, "9527");
搜索公衆號
經過 searchPublicService
或 searchPublicServiceByType
方法搜索已經添加的公衆號列表,能夠按關鍵字精確匹配或模糊匹配方式進行搜索。
/** * 搜索所有公衆服務。 * * @param searchType 搜索類型枚舉。 * @param keywords 搜索關鍵字。 */ RongIM.getInstance().searchPublicService(RongIMClient.SearchType.EXACT, keywords, new RongIMClient.SearchPublicServiceCallback() { @Override public void onError(RongIMClient.ErrorCode e) { //錯誤回調處理 } @Override public void onSuccess(PublicServiceProfileList publicServiceProfileList) { //成功回調處理 } }); /** * 按公衆服務類型搜索公衆服務。 * * @param conversationType 會話類型。 * @param searchType 搜索類型枚舉。 * @param keywords 搜索關鍵字。 */ RongIM.getInstance().searchPublicServicebyType(Conversation.PublicServiceType.PUBLIC_SERVICE, RongIMClient.SearchType.EXACT, keywords, new RongIMClient.SearchPublicServiceCallback() { @Override public void onError(RongIMClient.ErrorCode e) { //錯誤回調處理 } @Override public void onSuccess(PublicServiceProfileList publicServiceProfileList) { //成功回調處理 } });
獲取己關注公共帳號列表:
在應用中須要展現已關注公共帳號列表時,可經過 getPublicServiceList
方法獲取己關注公共帳號列表信息。
RongIM.getInstance().getPublicServiceList(new RongIMClient.SearchPublicServiceCallback() { @Override public void onSuccess(PublicServiceProfileList publicServiceProfileList) { //成功回調處理 } @Override public void onError(RongIMClient.ErrorCode e) { //錯誤回調處理 } });
獲取某公衆號信息
/** * 按公衆服務類型搜索公衆服務。 * * @param publicServiceType 公衆服務類型。 * @param publicServiceId 公衆號 Id。 */ RongIM.getInstance().getPublicServiceProfile(Conversation.PublicServiceType.PUBLIC_SERVICE, publicServiceId, new RongIMClient.ResultCallback<PublicServiceProfile>() { @Override public void onSuccess(PublicServiceProfile profile) { //成功後返回公衆號信息 } @Override public void onError(RongIMClient.ErrorCode e) { //錯誤回調處理 } });
發送文本消息以下:
// 構造 TextMessage 實例 TextMessage myTextMessage = TextMessage.obtain("我是消息內容"); /* 生成 Message 對象。 * "7127" 爲目標 Id。根據不一樣的 conversationType,多是用戶 Id、討論組 Id、羣組 Id 或聊天室 Id。 * Conversation.ConversationType.PRIVATE 爲私聊會話類型,根據須要,也能夠傳入其它會話類型,如羣組,討論組等。 */ Message myMessage = Message.obtain("7127", Conversation.ConversationType.PRIVATE, myTextMessage); /** * <p>發送消息。 * 經過 {@link io.rong.imlib.IRongCallback.ISendMessageCallback} * 中的方法回調發送的消息狀態及消息體。</p> * * @param message 將要發送的消息體。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 若是發送的是自定義消息,該字段必須填寫,不然沒法收到 push 消息。 * 若是發送 sdk 中默認的消息類型,例如 RC:TxtMsg, RC:VcMsg, RC:ImgMsg,則不須要填寫,默認已經指定。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param callback 發送消息的回調,參考 {@link io.rong.imlib.IRongCallback.ISendMessageCallback}。 */ RongIM.getInstance().sendMessage(myMessage, null, null, new IRongCallback.ISendMessageCallback() { @Override public void onAttached(Message message) { //消息本地數據庫存儲成功的回調 } @Override public void onSuccess(Message message) { //消息經過網絡發送成功的回調 } @Override public void onError(Message message, RongIMClient.ErrorCode errorCode) { //消息發送失敗的回調 } });
構造位置消息:
/** * 生成LocationMessage對象。 * * @param lat 緯度。 * @param lng 經度。 * @param poi poi信息。 * @param imgUri 地圖縮率圖地址。 * @return LocationMessage實例對象。 */ public static LocationMessage obtain(double lat, double lng, String poi, Uri imgUri)
根據位置消息生成 Message 實例,以下:
LocationMessage locationMessage = LocationMessage.obtain(lat, lng, poi, thumb); io.rong.imlib.model.Message message = io.rong.imlib.model.Message.obtain(mTargetId, mConversationType, locationMessage);
發送位置消息:
/** * <p>發送地理位置消息。並同時更新界面。</p> * <p>發送前構造 {@link Message} 消息實體,消息實體中的 content 必須爲 {@link LocationMessage}, 不然返回失敗。</p> * <p>其中的縮略圖地址 scheme 只支持 file:// 和 http:// 其餘暫不支持。</p> * * @param message 消息實體。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 若是發送的是自定義消息,該字段必須填寫,不然沒法收到 push 消息。 * 若是發送 sdk 中默認的消息類型,例如 RC:TxtMsg, RC:VcMsg, RC:ImgMsg,則不須要填寫,默認已經指定。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param sendMessageCallback 發送消息的回調,參考 {@link io.rong.imlib.IRongCallback.ISendMessageCallback}。 */ public void sendLocationMessage(Message message, String pushContent, final String pushData, final IRongCallback.ISendMessageCallback sendMessageCallback)
融雲 SDK 默認使用的是高德地圖,您也能夠基於其它第三方實現位置功能,請參考基於百度地圖實現融雲 SDK 文檔。
默認圖片消息發送
獲取 ImageMessage 實例
/** * 生成ImageMessage對象。 * * @param thumUri 縮略圖地址。 * @param localUri 大圖地址。 * @param isFull 是否發送原圖。 * @return ImageMessage對象實例。 */ public static ImageMessage obtain(Uri thumUri, Uri localUri, boolean isFull)
發送圖片消息
/** * <p>根據會話類型,發送圖片消息。</p> * * @param type 會話類型。 * @param targetId 目標 Id。根據不一樣的 conversationType,多是用戶 Id、討論組 Id、羣組 Id 或聊天室 Id。 * @param content 消息內容,例如 {@link TextMessage}, {@link ImageMessage}。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 若是發送的是自定義消息,該字段必須填寫,不然沒法收到 push 消息。 * 若是發送 sdk 中默認的消息類型,例如 RC:TxtMsg, RC:VcMsg, RC:ImgMsg,則不須要填寫,默認已經指定。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param callback 發送消息的回調。 */ RongIM.getInstance().sendImageMessage(Conversation.ConversationType.PRIVATE, "9517", imgMsg, null, null, new RongIMClient.SendImageMessageCallback() { @Override public void onAttached(Message message) { //保存數據庫成功 } @Override public void onError(Message message, RongIMClient.ErrorCode code) { //發送失敗 } @Override public void onSuccess(Message message) { //發送成功 } @Override public void onProgress(Message message, int progress) { //發送進度 } });
上面的方法是 SDK 默認發送圖片的方法,圖片會存儲到七牛,默認保存一個月。
發送圖片消息而且上傳到本身的服務器
構造消息實例
ImageMessage imageMessage = ImageMessage.obtain(thumbPathUri, localPathUri); Message message = Message.obtain(targetId, conversationType, imageMessage);
調用下面的方法發送圖片消息
/** * <p>發送圖片消息,可使用該方法將圖片上傳到本身的服務器發送,同時更新圖片狀態。</p> * <p>使用該方法在上傳圖片時,會回調 {@link io.rong.imlib.RongIMClient.SendImageMessageWithUploadListenerCallback} * 此回調中會攜帶 {@link RongIMClient.UploadImageStatusListener} 對象,使用者只須要調用其中的 * {@link RongIMClient.UploadImageStatusListener#update(int)} 更新進度 * {@link RongIMClient.UploadImageStatusListener#success(Uri)} 更新成功狀態,並告知上傳成功後的圖片地址 * {@link RongIMClient.UploadImageStatusListener#error()} 更新失敗狀態 </p> * * @param message 發送消息的實體。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 若是發送的是自定義消息,該字段必須填寫,不然沒法收到 push 消息。 * 若是發送 sdk 中默認的消息類型,例如 RC:TxtMsg, RC:VcMsg, RC:ImgMsg,則不須要填寫,默認已經指定。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param callback 發送消息的回調,回調中攜帶 {@link RongIMClient.UploadImageStatusListener} 對象,用戶調用該對象中的方法更新狀態。 * {@link #sendImageMessage(Message, String, String, RongIMClient.SendImageMessageCallback)} */ RongIM.getInstance().sendImageMessage(message, pushContent, pushData, new RongIMClient.SendImageMessageWithUploadListenerCallback() { @Override public void onAttached(Message message, final RongIMClient.UploadImageStatusListener uploadImageStatusListener) { /*上傳圖片到本身的服務器*/ uploadImg(imgMsg.getPicFilePath(), new UploadListener() { @Override public void onSuccess(String url) { // 上傳成功,回調 SDK 的 success 方法,傳遞迴圖片的遠端地址 uploadImageStatusListener.success(Uri.parse(url)); } @Override public void onProgress(float progress) { //刷新上傳進度 uploadImageStatusListener.update((int) progress); } @Override public void onFail() { // 上傳圖片失敗,回調 error 方法。 uploadImageStatusListener.error(); } }); } @Override public void onError(Message message, RongIMClient.ErrorCode errorCode) { //發送失敗 } @Override public void onSuccess(Message message) { //發送成功 } @Override public void onProgress(Message message, int progress) { //發送進度 } });
content
中,大圖首先上傳到文件服務器(融雲 SDK 中默認上傳到七牛雲存儲,
圖片有效期爲 1 個月
。),而後將雲存儲上的大圖地址放入消息體中。
圖片縮略圖機制:
縮略圖尺寸爲:240 x 240 像素,以寬度和高度中較長的邊不超過 240 像素等比壓縮。
大圖尺寸爲:960 x 960 像素,以寬度和高度中較長的邊不超過 960 像素等比壓縮。
基本原理:錄製語音,本地存儲轉換爲 AMR 格式,獲取語音時長,構造語音消息併發送。
/** * 獲取語音消息實體。 * * @param Uri 語音 Uri 。 * @param duration 語音時長(單位:秒)。 */ VoiceMessage vocMsg = VoiceMessage.obtain(Uri.fromFile(voiceFile), 10); /** * <p>發送消息。 * 經過 {@link io.rong.imlib.IRongCallback.ISendMessageCallback} * 中的方法回調發送的消息狀態及消息體。</p> * * @param message 將要發送的消息體。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 若是發送的是自定義消息,該字段必須填寫,不然沒法收到 push 消息。 * 若是發送 sdk 中默認的消息類型,例如 RC:TxtMsg, RC:VcMsg, RC:ImgMsg,則不須要填寫,默認已經指定。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param callback 發送消息的回調,參考 {@link io.rong.imlib.IRongCallback.ISendMessageCallback}。 */ RongIM.getInstance().sendMessage(myMessage, null, null, new IRongCallback.ISendMessageCallback() { @Override public void onAttached(Message message) { //消息本地數據庫存儲成功的回調 } @Override public void onSuccess(Message message) { //消息經過網絡發送成功的回調 } @Override public void onError(Message message, RongIMClient.ErrorCode errorCode) { //消息發送失敗的回調 } });
生成圖文消息實例:
/** * 生成RichContentMessage對象。 * * @param title 消息標題。 * @param content 消息內容。 * @param imageUrl 消息圖片url. * @return 生成RichContentMessage對象。 */ public static RichContentMessage obtain(String title, String content, String imageUrl)
發送消息
RichContentMessage richContentMessage = RichContentMessage.obtain("標題", "內容", "http://rongcloud.cn/images/logo.png"); //"9517" 爲目標 Id。根據不一樣的 conversationType,多是用戶 Id、討論組 Id、羣組 Id 或聊天室 Id。 //Conversation.ConversationType.PRIVATE 爲會話類型。 Message myMessage = Message.obtain("9517", Conversation.ConversationType.PRIVATE, richContentMessage); /** * <p>發送消息。 * 經過 {@link io.rong.imlib.IRongCallback.ISendMessageCallback} * 中的方法回調發送的消息狀態及消息體。</p> * * @param message 將要發送的消息體。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 若是發送的是自定義消息,該字段必須填寫,不然沒法收到 push 消息。 * 若是發送 sdk 中默認的消息類型,例如 RC:TxtMsg, RC:VcMsg, RC:ImgMsg,則不須要填寫,默認已經指定。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param callback 發送消息的回調,參考 {@link io.rong.imlib.IRongCallback.ISendMessageCallback}。 */ RongIM.getInstance().sendMessage(myMessage, null, null, new IRongCallback.ISendMessageCallback() { @Override public void onAttached(Message message) { //消息本地數據庫存儲成功的回調 } @Override public void onSuccess(Message message) { //消息經過網絡發送成功的回調 } @Override public void onError(Message message, RongIMClient.ErrorCode errorCode) { //消息發送失敗的回調 } });
融雲 SDK 默認支持文件發送功能,點擊查看文件消息產品介紹。
注: 融雲 SDK 默認實現了文件管理器功能,若是您想自定義文件管理器,能夠經過自定義會話擴展區的方式來自定義文件管理器。
接受到文件消息,並點擊下載後,該文件默認保存在 SD 卡的 /RongCloud/Media/
下。
您能夠經過更改 SDK 的 res/values/rc_configuration.xml
裏面的 rc_media_message_default_save_path
的值,來自定義文件的存儲路徑。
發送文件消息
/** * <p>發送多媒體消息</p> * <p>發送前構造 {@link Message} 消息實體</p> * @param message 發送消息的實體。 * @param pushContent 當下發 push 消息時,在通知欄裏會顯示這個字段。 * 發送文件消息時,此字段必須填寫,不然會收不到 push 推送。 * @param pushData push 附加信息。若是設置該字段,用戶在收到 push 消息時,能經過 {@link io.rong.push.notification.PushNotificationMessage#getPushData()} 方法獲取。 * @param callback 發送消息的回調 {@link io.rong.imlib.RongIMClient.SendMediaMessageCallback}。 */ public void sendMediaMessage(Message message, String pushContent, final String pushData, final IRongCallback.ISendMediaMessageCallback callback)
下載文件消息
/** * 下載多媒體消息。 * 用來獲取媒體原文件時調用。若是本地緩存中包含此文件,則從本地緩存中直接獲取,不然將從服務器端下載。 * * @param message 文件消息。 * @param callback 下載文件的回調。 */ public void downloadMediaMessage(Message message, final IRongCallback.IDownloadMediaMessageCallback callback)
取消文件下載
/** * 取消多媒體消息下載。 * @param message 包含多媒體文件的消息, * @param callback 取消下載多媒體文件時的回調。 * */ public void cancelDownloadMediaMessage(Message message, RongIMClient.OperationCallback callback)
若是您使用的是 IMLib SDK 集成,可參考 IMLib 文件消息文檔。
融雲推送服務及集成第三方推送服務,詳細請查看推送服務開發指南。
設置本身發出消息的監聽器,在 init() 以後便可設置。
注意:若是在 Activity 裏設置,須要在 Activity 銷燬時,將監聽設置爲 null,防止內存泄露。
/** * 設置發送消息的監聽。 * * @param listener 發送消息的監聽。 */ public void setSendMessageListener(OnSendMessageListener listener)
設置後實現消息發送監聽接口 OnSendMessageListener
,消息發送失敗可在 onSent
方法中根據 SentMessageErrorCode
返回的狀態碼實現自已的邏輯處理。onSent
返回 true
表示走自已的處理方式,不然走融雲默認處理方式。
RongIM.getInstance().setSendMessageListener(new MySendMessageListener()); private class MySendMessageListener implements RongIM.OnSendMessageListener { /** * 消息發送前監聽器處理接口(是否發送成功能夠從 SentStatus 屬性獲取)。 * * @param message 發送的消息實例。 * @return 處理後的消息實例。 */ @Override public Message onSend(Message message) { //開發者根據本身需求自行處理邏輯 return message; } /** * 消息在 UI 展現後執行/本身的消息發出後執行,不管成功或失敗。 * * @param message 消息實例。 * @param sentMessageErrorCode 發送消息失敗的狀態碼,消息發送成功 SentMessageErrorCode 爲 null。 * @return true 表示走自已的處理方式,false 走融雲默認處理方式。 */ @Override public boolean onSent(Message message,RongIM.SentMessageErrorCode sentMessageErrorCode) { if(message.getSentStatus()== Message.SentStatus.FAILED){ if(sentMessageErrorCode== RongIM.SentMessageErrorCode.NOT_IN_CHATROOM){ //不在聊天室 }else if(sentMessageErrorCode== RongIM.SentMessageErrorCode.NOT_IN_DISCUSSION){ //不在討論組 }else if(sentMessageErrorCode== RongIM.SentMessageErrorCode.NOT_IN_GROUP){ //不在羣組 }else if(sentMessageErrorCode== RongIM.SentMessageErrorCode.REJECTED_BY_BLACKLIST){ //你在他的黑名單中 } } MessageContent messageContent = message.getContent(); if (messageContent instanceof TextMessage) {//文本消息 TextMessage textMessage = (TextMessage) messageContent; Log.d(TAG, "onSent-TextMessage:" + textMessage.getContent()); } else if (messageContent instanceof ImageMessage) {//圖片消息 ImageMessage imageMessage = (ImageMessage) messageContent; Log.d(TAG, "onSent-ImageMessage:" + imageMessage.getRemoteUri()); } else if (messageContent instanceof VoiceMessage) {//語音消息 VoiceMessage voiceMessage = (VoiceMessage) messageContent; Log.d(TAG, "onSent-voiceMessage:" + voiceMessage.getUri().toString()); } else if (messageContent instanceof RichContentMessage) {//圖文消息 RichContentMessage richContentMessage = (RichContentMessage) messageContent; Log.d(TAG, "onSent-RichContentMessage:" + richContentMessage.getContent()); } else { Log.d(TAG, "onSent-其餘消息,本身來判斷處理"); } return false; } }
接收消息的監聽器,在 init() 以後便可設置。注意,建議設置在 Application 裏面,這樣才能在整個應用的生命週期,都能監聽到接收消息事件。
/** * 設置接收消息的監聽器。 * <p/> * 全部接收到的消息、通知、狀態都經由此處設置的監聽器處理。包括私聊消息、討論組消息、羣組消息、聊天室消息以及各類狀態。 * * @param listener 接收消息的監聽器。 */ public static void setOnReceiveMessageListener(RongIMClient.OnReceiveMessageListener listener)
接收消息監聽器的實現,全部接收到的消息、通知、狀態都經由此處設置的監聽器處理。包括私聊消息、討論組消息、羣組消息、聊天室消息以及各類狀態。
RongIM.setOnReceiveMessageListener(new MyReceiveMessageListener()); private class MyReceiveMessageListener implements RongIMClient.OnReceiveMessageListener { /** * 收到消息的處理。 * * @param message 收到的消息實體。 * @param left 剩餘未拉取消息數目。 * @return 收到消息是否處理完成,true 表示本身處理鈴聲和後臺通知,false 走融雲默認處理方式。 */ @Override public boolean onReceived(Message message, int left) { //開發者根據本身需求自行處理 return false; } }
您能夠在自定義的繼承融雲 PushMessageReceiver 的廣播接收器裏面監聽到 push 事件。
public class SealNotificationReceiver extends PushMessageReceiver { /* push 通知到達事件*/ @Override public boolean onNotificationMessageArrived(Context context, PushNotificationMessage message) { return false; // 返回 false, 會彈出融雲 SDK 默認通知; 返回 true, 融雲 SDK 不會彈通知, 通知須要由您自定義。 } /* push 通知點擊事件 */ @Override public boolean onNotificationMessageClicked(Context context, PushNotificationMessage message) { return false; // 返回 false, 會走融雲 SDK 默認處理邏輯, 即點擊該通知會打開會話列表或會話界面; 返回 true, 則由您自定義處理邏輯。 } }
關於融雲推送的詳細機制和功能,您能夠參考推送服務開發指南。
設置鏈接狀態監聽,必須在 init
後進行調用。 注意:建議設置在 Application 裏面,這樣才能在整個應用的生命週期,都能監聽到狀態變化。
/** * 設置鏈接狀態變化的監聽器。 * * @param listener 鏈接狀態變化的監聽器。 */ public static void setConnectionStatusListener(final RongIMClient.ConnectionStatusListener listener)
實現鏈接狀態監聽器,以獲取當前鏈接相關狀態。
RongIM.setConnectionStatusListener(new MyConnectionStatusListener()); private class MyConnectionStatusListener implements RongIMClient.ConnectionStatusListener { @Override public void onChanged(ConnectionStatus connectionStatus) { switch (connectionStatus){ case CONNECTED://鏈接成功。 break; case DISCONNECTED://斷開鏈接。 break; case CONNECTING://鏈接中。 break; case NETWORK_UNAVAILABLE://網絡不可用。 break; case KICKED_OFFLINE_BY_OTHER_CLIENT://用戶帳戶在其餘設備登陸,本機會被踢掉線 break; } } }
會話列表操做監聽,在調用 init
以後便可進行設置。
/** * 設置會話列表界面操做的監聽器。 */ RongIM.setConversationListBehaviorListener(new MyConversationListBehaviorListener());
實現會話列表操做監聽接口 ConversationListBehaviorListener
。
private class MyConversationListBehaviorListener implements RongIM.ConversationListBehaviorListener{ /** * 當點擊會話頭像後執行。 * * @param context 上下文。 * @param conversationType 會話類型。 * @param targetId 被點擊的用戶id。 * @return 若是用戶本身處理了點擊後的邏輯處理,則返回 true,不然返回 false,false 走融雲默認處理方式。 */ boolean onConversationPortraitClick(Context context, Conversation.ConversationType conversationType, String targetId){ } /** * 當長按會話頭像後執行。 * * @param context 上下文。 * @param conversationType 會話類型。 * @param targetId 被點擊的用戶id。 * @return 若是用戶本身處理了點擊後的邏輯處理,則返回 true,不然返回 false,false 走融雲默認處理方式。 */ boolean onConversationPortraitLongClick(Context context, Conversation.ConversationType conversationType, String targetId){ return false; } /** * 長按會話列表中的 item 時執行。 * * @param context 上下文。 * @param view 觸發點擊的 View。 * @param uiConversation 長按時的會話條目。 * @return 若是用戶本身處理了長按會話後的邏輯處理,則返回 true, 不然返回 false,false 走融雲默認處理方式。 */ @Override public boolean onConversationLongClick(Context context, View view, UIConversation uiConversation) { return false; } /** * 點擊會話列表中的 item 時執行。 * * @param context 上下文。 * @param view 觸發點擊的 View。 * @param uiConversation 會話條目。 * @return 若是用戶本身處理了點擊會話後的邏輯處理,則返回 true, 不然返回 false,false 走融雲默認處理方式。 */ @Override public boolean onConversationClick(Context context, View view, UIConversation uiConversation) { return false; } }
會話界面操做的監聽器,在調用 init
後便可進行設置。
/** * 設置會話界面操做的監聽器。 */ RongIM.setConversationBehaviorListener(new MyConversationBehaviorListener());
實現會話界面操做的監聽接口 ConversationBehaviorListener
。會話界面中點擊用戶頭像、長按用戶頭像、點擊消息、長按消息的操做都在此處理。
private class MyConversationBehaviorListener implements RongIM.ConversationBehaviorListener{ /** * 當點擊用戶頭像後執行。 * * @param context 上下文。 * @param conversationType 會話類型。 * @param userInfo 被點擊的用戶的信息。 * @return 若是用戶本身處理了點擊後的邏輯,則返回 true,不然返回 false,false 走融雲默認處理方式。 */ @Override public boolean onUserPortraitClick(Context context, Conversation.ConversationType conversationType, UserInfo userInfo) { return false; } /** * 當長按用戶頭像後執行。 * * @param context 上下文。 * @param conversationType 會話類型。 * @param userInfo 被點擊的用戶的信息。 * @return 若是用戶本身處理了點擊後的邏輯,則返回 true,不然返回 false,false 走融雲默認處理方式。 */ @Override public boolean onUserPortraitLongClick(Context context, Conversation.ConversationType conversationType, UserInfo userInfo) { return false; } /** * 當點擊消息時執行。 * * @param context 上下文。 * @param view 觸發點擊的 View。 * @param message 被點擊的消息的實體信息。 * @return 若是用戶本身處理了點擊後的邏輯,則返回 true, 不然返回 false, false 走融雲默認處理方式。 */ @Override public boolean onMessageClick(Context context, View view, Message message) { return false; } /** * 當長按消息時執行。 * * @param context 上下文。 * @param view 觸發點擊的 View。 * @param message 被長按的消息的實體信息。 * @return 若是用戶本身處理了長按後的邏輯,則返回 true,不然返回 false,false 走融雲默認處理方式。 */ @Override public boolean onMessageLongClick(Context context, View view, Message message) { return false; } /** * 當點擊連接消息時執行。 * * @param context 上下文。 * @param link 被點擊的連接。 * @return 若是用戶本身處理了點擊後的邏輯處理,則返回 true, 不然返回 false, false 走融雲默認處理方式。 */ @Override public boolean onMessageLinkClick(Context context, String link) { return false; } }
未讀消息數監聽器,必須在 init
以後便可調用。
/** * 設置未讀消息數變化監聽器。 * 注意:若是是在 activity 中設置,那麼要在 activity 銷燬時,調用 {@link #removeUnReadMessageCountChangedObserver(IUnReadMessageObserver)} * 不然會形成內存泄漏。 * * @param observer 接收未讀消息消息的監聽器。 * @param conversationTypes 接收未讀消息的會話類型。 */ public void addUnReadMessageCountChangedObserver(final IUnReadMessageObserver observer, Conversation.ConversationType... conversationTypes) }
Activity 銷燬時,移除監聽。
/** * 註銷已註冊的未讀消息數變化監聽器。 * * @param observer 接收未讀消息消息的監聽器。 */ public void removeUnReadMessageCountChangedObserver(final IUnReadMessageObserver observer)
rc_fr_conversationlist.xml 會話列表佈局文件
rc_item_conversation.xml 會話列表各個 item 對應的佈局文件
能夠經過修改這些佈局文件修改背景或字體顏色等。
能夠根據會話類型,限制會話列表只顯示某幾個類型的會話,以及這些會話是否以聚合形式顯示。
下面以自定義會話列表只顯示單聊和羣組會話爲例,說明如何自定義:
a. 配置 Uri
b. 把自定義的 Uri 賦值給 ConversationListFragment
listFragment.setUri(uri);
對於會話列表中每種會話類型的會話,開發者均可以自定義頭像位置的顯示方式,顯示方式有:靠左顯示、靠右顯示、不顯示。
自定義步驟:
一、新建一類繼承要改變的會話提供者類,而後重寫註解,修改 portraitPosition 的值以完成顯示方式。
註解名稱:ConversationProviderTag。屬性:conversationType ,portraitPosition 。
conversationType 的值不能重複不可修改,它是會話提供者的惟一標識;portraitPosition 用來控制頭像的顯示方式,它的值能夠修改,它的值有:1:靠左顯示, 2:靠右顯示, 3:不顯示。
提供者名稱 | 類名 | 註解 conversationType 值 (不可修改) |
註解 portraitPosition 初始值 (可修改) |
---|---|---|---|
二人會話提供者 | PrivateConversationProvider.java |
private | 1 |
討論組會話提供者 | DiscussionConversationProvider.java |
discussion | 1 |
羣聊會話提供者 | GroupConversationProvider.java |
group | 1 |
客服會話提供者 | CustomerServiceConversationProvider.java |
customer_service | 1 |
系統會話提供者 | SystemConversationProvider.java |
system | 1 |
應用公衆服務會話提供者 | AppServiceConversationProvider.java |
app_public_service | 1 |
公衆服務平臺會話提供者 | PublicServiceConversationProvider.java |
public_service | 1 |
二、從新註冊該會話模板,註冊方法應在 init 後調用
RongIM.getInstance().registerConversationTemplate;
自定義示例:
如何在會話列表中讓所單聊會話頭像都靠右顯示?
第一步:
@ConversationProviderTag(conversationType = "private", portraitPosition = 2) public class MyPrivateConversationProvider extends PrivateConversationProvider { ... }
第二步:
RongIM.getInstance().registerConversationTemplate(new MyPrivateConversationProvider());
rc_fr_conversation.xml 會話頁面佈局
rc_item_message.xml 消息列表單個 item 對應的佈局
您能夠經過修改上述佈局文件來更改字體大小顏色及背景色等。
融雲 IMKit SDK 中每一種消息類型(要在 UI 展現的)都對應一個 UI 展現的 Provider,開發者能夠修改 Provider 的註解屬性來完成消息顯示的自定義。
一、新建一類並繼承要修改的消息提供者類,而後重寫註解。
註解名稱:ProviderTag。
註解屬性:
屬性 | 描述 |
---|---|
messageContent |
對應的消息類型 ( 如:TextMessage.class )。 |
showPortrait |
設置是否顯示頭像,默認爲 true。 |
centerInHorizontal |
消息內容是否橫向居中,默認 false。 |
hide |
是否隱藏消息, 默認 false。 |
showProgress |
是否顯示發送進度,默認 true。 |
showSummaryWithName |
是否在會話的內容體裏顯示發送者名字,默認 true。 |
自定義示例:
如何在會話中讓 TextMessage 不顯示頭像且消息內容橫向居中顯示?
第一步:
自定義 TextMessage 的展現模板
@ProviderTag ( messageContent = TextMessage.class , showPortrait = false , centerInHorizontal = true ) public class MyTextMessageItemProvider extends TextMessageItemProvider {...}
第二步:
從新註冊該消息模板,註冊方法應在 init 後調用
RongIM.getInstance().registerMessageTemplate(new MyTextMessageItemProvider());
未讀消息數目和新消息氣泡在 IMKit 中默認不顯示,如須要顯示新消息提醒和未讀消息數目能夠在鏈接成功後經過下面方法設置。
RongIM.getInstance().enableNewComingMessageIcon(true);//顯示新消息提醒 RongIM.getInstance().enableUnreadMessageIcon(true);//顯示未讀消息數目
新消息大於 1 條即展現,超過 99 條顯示爲 "99+",未讀消息大於 10 條即展現,超過 150 條顯示爲 "150+條新消息"。另外,控件的樣式能夠在 layout/rc_fr_messagelist.xml
中進行調整。
能夠經過自定義會話列表或者會話界面的適配器,來自定義界面的展現。
下面以自定義會話界面消息列表的適配器爲例,說明如何自定義:
3.1 自定義會話 fragment 繼承自 ConversationFragment,複寫 onResolveAdapter() 方法,返回自定義的 adapter。
另外您的 activity 佈局文件中也須要配置成自定義的 fragment。
3.2 自定義繼承 MessageListAdapter 的消息列表適配器,根據須要複寫其中的 newView() 或者 bindView() 方法
輸入區域相關概念:
一、輸入區域擴展欄對外接口類爲 RongExtension。如圖 1
二、Plugin 是開發者自定義 「+」 號區域展開後的 item,如圖 1
三、EmoticonTab 是開發者自定義 表情 tab 頁。如圖 2
1、佈局自定義
部分佈局文件以下,您能夠經過修改對應的佈局文件來調整界面佈局,修改背景,更改字體等。
一、rc_ext_extension_bar.xml 輸入框佈局文件。它是整個輸入框的容器,內部有對各部分組件功能描述。
二、rc_ext_input_edit_text.xml EditText 佈局文件。若是想要替換背景,直接修改便可。
三、rc_ext_voice_input.xml 語音輸入佈局文件。
四、輸入框模式自定義。
另外,在會界面中能夠設置輸入框的模式。針對聊天會話的語音/文本切換功能、內容輸入功能、擴展功能,融雲目前提供了 5 種排列組合模式:
style | 組合模式 |
---|---|
SCE |
語音/文本切換功能+內容輸入功能+擴展功能 |
SC |
語音/文本切換功能+內容輸入功能 |
EC |
擴展功能+內容輸入功能 |
CE |
內容輸入功能+擴展功能 |
C |
內容輸入功能 |
用戶能夠經過更改 rc_fr_conversation.xml
裏 app:RCStyle="SCE"
,更改默認輸入顯示形式。
2、「+」號擴展區域自定義
自定義 Plugin
一、自定義 Plugin 並實現 IPluginModule。 如:
public class MyPlugin implements IPluginModule { … }
二、自定義一個 ExtensionModule 繼承自 DefaultExtensionModule,複寫其中的 getPluginModules() 方法,返回須要展現的 plugin 列表。如:
public class MyExtensionModule extends DefaultExtensionModule { private MyPlugin myPlugin; @Override public List<IPluginModule> getPluginModules(Conversation.ConversationType conversationType) { List<IPluginModule> pluginModules = super.getPluginModules(conversationType); pluginModules.add(myPlugin); return pluginModules; } }
三、在初始化以後,取消 SDK 默認的 ExtensionModule,註冊自定義的 ExtensionModule, 以下:
public void setMyExtensionModule() { List<IExtensionModule> moduleList = RongExtensionManager.getInstance().getExtensionModules(); IExtensionModule defaultModule = null; if (moduleList != null) { for (IExtensionModule module : moduleList) { if (module instanceof DefaultExtensionModule) { defaultModule = module; break; } } if (defaultModule != null) { RongExtensionManager.getInstance().unregisterExtensionModule(defaultModule); RongExtensionManager.getInstance().registerExtensionModule(new MyExtensionModule()); } } }
四、視頻講解如何在已默認支持照片、拍照、地理位置、語音通話等功能的狀況下,新增自定義及減小默認功能項。
自定義 EmoticonTab
一、自定義 EmoticonTab 實現 IEmoticonTab。 如:
public class MyEmoticon implements IEmoticonTab { … }
二、自定義一個 ExtensionModule 繼承自 DefaultExtensionModule,複寫其中的 getEmoticonTabs() 方法,返回須要展現的 EmoticonTab 列表。如:
public class MyExtensionModule extends DefaultExtensionModule { private MyEmoticon myEmoticon; @Override public List<IEmoticonTab> getEmoticonTabs() { List<IEmoticonTab> emoticonTabs = super.getEmoticonTabs(); emoticonTabs.add(myEmoticon); return emoticonTabs; } }
三、在初始化以後,取消 SDK 默認的 ExtensionModule,註冊自定義的 ExtensionModule, 以下:
public void setMyExtensionModule() { List<IExtensionModule> moduleList = RongExtensionManager.getInstance().getExtensionModules(); IExtensionModule defaultModule = null; if (moduleList != null) { for (IExtensionModule module : moduleList) { if (module instanceof DefaultExtensionModule) { defaultModule = module; break; } } if (defaultModule != null) { RongExtensionManager.getInstance().unregisterExtensionModule(defaultModule); RongExtensionManager.getInstance().registerExtensionModule(new MyExtensionModule()); } } }
3、輸入區事件監聽
自定義 fragment 繼承 ConversationFragment, 便可獲取或者複寫 ConversationFragment 裏的各個事件,如輸入文本內容的變化,發送按鈕或者語音按鈕的點擊事件等。
詳細請參考融雲 Android Extension 開發文檔。
一、繼承 MessageContent
新建一自定義消息類,繼承 MessageContent 以下面示例代碼:
public class CustomizeMessage extends MessageContent { private String content;//消息屬性,可隨意定義 }
二、重寫和實現方法
實現 encode()
方法,該方法的功能是將消息屬性封裝成 json
串,再將 json
串轉成 byte
數組,該方法會在發消息時調用,以下面示例代碼:
@Override public byte[] encode() { JSONObject jsonObj = new JSONObject(); try { jsonObj.put("content", "這是一條消息內容"); } catch (JSONException e) { Log.e("JSONException", e.getMessage()); } try { return jsonObj.toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; }
覆蓋父類的 MessageContent(byte[] data)
構造方法,該方法將對收到的消息進行解析,先由 byte
轉成 json
字符串,再將 json
中內容取出賦值給消息屬性。
public CustomizeMessage(byte[] data) { String jsonStr = null; try { jsonStr = new String(data, "UTF-8"); } catch (UnsupportedEncodingException e1) { } try { JSONObject jsonObj = new JSONObject(jsonStr); if (jsonObj.has("content")) content = jsonObj.optString("content"); } catch (JSONException e) { RLog.e(this, "JSONException", e.getMessage()); } }
MessageContent
已實現 Parcelable
接口,下面須要實現 Parcelable
中的方法:
//給消息賦值。 public CustomizeMessage(Parcel in) { content=ParcelUtils.readFromParcel(in);//該類爲工具類,消息屬性 ... //這裏可繼續增長你消息的屬性 } /** * 讀取接口,目的是要從Parcel中構造一個實現了Parcelable的類的實例處理。 */ public static final Creator<CustomizeMessage> CREATOR = new Creator<CustomizeMessage>() { @Override public CustomizeMessage createFromParcel(Parcel source) { return new CustomizeMessage(source); } @Override public CustomizeMessage[] newArray(int size) { return new CustomizeMessage[size]; } }; /** * 描述了包含在 Parcelable 對象排列信息中的特殊對象的類型。 * * @return 一個標誌位,代表Parcelable對象特殊對象類型集合的排列。 */ public int describeContents() { return 0; } /** * 將類的數據寫入外部提供的 Parcel 中。 * * @param dest 對象被寫入的 Parcel。 * @param flags 對象如何被寫入的附加標誌。 */ @Override public void writeToParcel(Parcel dest, int flags) { ParcelUtils.writeToParcel(dest, content);//該類爲工具類,對消息中屬性進行序列化 ... //這裏可繼續增長你消息的屬性 }
三、增長註解信息
註解名:MessageTag ;屬性:value ,flag; value 即 ObjectName 是消息的惟一標識不能夠重複,開發者命名時不能以 RC 開頭,避免和融雲內置消息衝突;flag 是用來定義消息的可操做狀態。
以下面代碼段,自定義消息名稱 CustomizeMessage
,vaule 是 app:custom
,flag 是 MessageTag.ISCOUNTED
| MessageTag.ISPERSISTED
表示消息計數且存庫。
@MessageTag(value = "app:custom", flag = MessageTag.ISCOUNTED | MessageTag.ISPERSISTED) public class CustomizeMessage extends MessageContent { ... }
flag
值以下表:
枚舉值 | 說明 |
---|---|
MessageTag.NONE |
爲空值,不表示任何意義,發送的自定義消息不會在會話頁面和會話列表中展現。 |
MessageTag.ISCOUNTED |
表示客戶端收到消息後,要進行未讀消息計數(未讀消息數增長 1),全部內容型消息都應該設置此值。非內容類消息暫不支持消息計數。 |
MessageTag.ISPERSISTED |
表示客戶端收到消息後,要進行存儲,並在以後能夠經過接口查詢,存儲後會在會話界面中顯示。 |
四、註冊自定義消息
自定義消息應在 init
後註冊,代碼以下:
RongIM.registerMessageType(CustomizeMessage.class);
自定義消息在會話列表和會話頁面顯示。
步驟:
一、建立消息提供者
新建一個消息類繼承 IContainerItemProvider.MessageProvider
類,實現對應接口方法,接口方法以下表:
方法名 | 描述 | |
---|---|---|
newView |
初始化 View。 | |
bindView |
將數據填充 View 上。 | |
getContentSummary |
該條消息爲該會話的最後一條消息時,會話列表要顯示的內容,經過該方法進行定義。 | |
onItemClick |
點擊該類型消息觸發。 | |
onItemLongClick |
長按該類型消息觸發。 |
代碼片斷以下:
@ProviderTag(messageContent = CustomizeMessage.class) public class CustomizeMessageItemProvider extends IContainerItemProvider.MessageProvider<CustomizeMessage> { class ViewHolder { TextView message; } @Override public View newView(Context context, ViewGroup group) { View view = LayoutInflater.from(context).inflate(io.rong.imkit.R.layout.item_customize_message, null); ViewHolder holder = new ViewHolder(); holder.message = (TextView) view.findViewById(android.R.id.text1); view.setTag(holder); return view; } @Override public void bindView(View v, int position, CustomizeMessage content, Message message) { ViewHolder holder = (ViewHolder) v.getTag(); if (message.getMessageDirection() == Message.MessageDirection.SEND) {//消息方向,本身發送的 holder.message.setBackgroundResource(io.rong.imkit.R.drawable.rc_ic_bubble_right); } else { holder.message.setBackgroundResource(io.rong.imkit.R.drawable.rc_ic_bubble_left); } holder.message.setText(content.getContent()); AndroidEmoji.ensure((Spannable) holder.message.getText());//顯示消息中的 Emoji 表情。 } @Override public Spannable getContentSummary(CustomizeMessage data) { return new SpannableString("這是一條自定義消息CustomizeMessage"); } @Override public void onItemClick(View view, int position, CustomizeMessage content, Message message) { } @Override public void onItemLongClick(View view, int position, CustomizeMessage content, Message message) { } }
二、註冊消息模板
RongIM.getInstance().registerMessageTemplate(new CustomizeMessageItemProvider);
調用 RongIM.getInstance().sendMessage()
發送自定義消息。須要注意的是,該方法有兩個參數 pushContent 和 pushData 。 說明以下:
pushContent:當客戶端離線,接受推送通知時,通知的內容會顯示爲 pushContent 的內容。若是發送的是自定義消息,該字段必須填寫,不然會沒法收到該消息的推送
。
pushData:收到該消息的推送時的附加信息。若是設置該字段,用戶在收到該消息的推送時,能經過推送監聽 onNotificationMessageArrived() 裏的參數 PushNotificationMessage 的 getPushData() 方法獲取。
對鏈接的幾點特殊說明:
connect() 方法在整個應用全局,建議僅調用一次。 SDK 有重連機制,您不須要屢次重連。
connect() 方法的回調僅在調用時回調一次,後續 SDK 的鏈接狀態發生變化時,不會再經過 connect() 的回調返回,而是 經過您設置的鏈接狀態監聽器得到。詳細請參考鏈接狀態監聽。
重連機制:
10
次從新鏈接服務器,首次斷開 1
秒後會從新鏈接,若是仍然鏈接不成功,會在 2
秒後(重連間隔時間爲上次重連間隔時間乘 2
)嘗試從新鏈接服務器,以此類推當嘗試重連 10
次後,仍然連不上服務器將再也不嘗試從新鏈接,可是在網絡狀況發生變化或從新打開應用時仍然會再次嘗試重連。經過 connect() 的 onError() 回調,或者經過 setConnectionStatusListener() 設置的監聽器監聽到錯誤碼時, 開發者僅須要關注如下幾種鏈接錯誤碼,其他錯誤碼 SDK 均會進行自動重連,開發者無須處理。
App Key 錯誤,請檢查您使用的 App Key 是否正確。
RC_CONN_ID_REJECT = 31002
Token 無效
RC_CONN_USER_OR_PASSWD_ERROR = 31004
Token 無效通常有如下兩種緣由。
一、Token 錯誤,請您檢查客戶端初始化使用的 App Key 和您服務器獲取 Token 使用的 App Key 是否一致;
二、Token 過時,是由於您在開發者後臺設置了 Token 過時時間,您須要請求您的服務器從新獲取 Token 並再次用新的 Token 創建鏈接。
BundleID 不正確
RC_CONN_PACKAGE_NAME_INVALID = 31007
請檢查您 App 的 BundleID 是否正確。
App Key 被封禁或已刪除
RC_CONN_APP_BLOCKED_OR_DELETED = 31008
請檢查您使用的 App Key 是否正確。
用戶被封禁
RC_CONN_USER_BLOCKED = 31009
請檢查您使用的 Token 是否正確,以及對應的 UserId 是否被封禁。
當前用戶在其餘設備上登陸,此設備被踢下線
RC_DISCONN_KICK = 31010
SDK 沒有初始化
BIZ_ERROR_CLIENT_NOT_INIT = 33001
在使用SDK任何功能以前,必須先 Init。
開發者接口調用時傳入的參數錯誤
BIZ_ERROR_INVALID_PARAMETER = 33003
請檢查接口調用時傳入的參數類型和值。
若是聊天的用戶正在輸入文字或者正在錄製語音消息,SDK 能夠在聊天界面的標題欄中顯示對方正在輸入
和對方正在講話
的提示。
您能夠經過 rc_configuration.xml
裏的開關開啓輸入狀態提醒的功能,目前僅支持單聊。默認 true
是開啓,設置爲 false
爲關閉。
<!-- 設置發送輸入狀態 --> <bool name="rc_typing_status">true</bool>
融雲 SDK 內部已經處理好邏輯,開發者不須要關心如何發送輸入狀態,何時取消輸入狀態等細節。只須要註冊監聽,在回調裏更新標題欄便可。
因爲融雲只提供 fragment
,因此標題欄的處理須要開發者本身添加。請在集成了 ConversationFragment的activity
裏註冊輸入狀態的監聽,您能夠在 activity
的 onCreate()
裏添加以下代碼。
RongIMClient.setTypingStatusListener(new RongIMClient.TypingStatusListener() { @Override public void onTypingStatusChanged(Conversation.ConversationType type, String targetId, Collection<TypingStatus> typingStatusSet) { //當輸入狀態的會話類型和targetID與當前會話一致時,才須要顯示 if (type.equals(mConversationType) && targetId.equals(mTargetId)) { //count表示當前會話中正在輸入的用戶數量,目前只支持單聊,因此判斷大於0就能夠給予顯示了 int count = typingStatusSet.size(); if (count > 0) { Iterator iterator = typingStatusSet.iterator(); TypingStatus status = (TypingStatus) iterator.next(); String objectName = status.getTypingContentType(); MessageTag textTag = TextMessage.class.getAnnotation(MessageTag.class); MessageTag voiceTag = VoiceMessage.class.getAnnotation(MessageTag.class); //匹配對方正在輸入的是文本消息仍是語音消息 if (objectName.equals(textTag.value())) { //顯示「對方正在輸入」 mHandler.sendEmptyMessage(SET_TEXT_TYPING_TITLE); } else if (objectName.equals(voiceTag.value())) { //顯示"對方正在講話" mHandler.sendEmptyMessage(SET_VOICE_TYPING_TITLE); } } else { //當前會話沒有用戶正在輸入,標題欄仍顯示原來標題 mHandler.sendEmptyMessage(SET_TARGETID_TITLE); } } } });
當前會話正在輸入的用戶有變化時,會觸發 onTypingStatusChanged()
,回調裏攜帶有當前正在輸入的用戶列表。對於單聊而言,當對方正在輸入時,監聽會觸發一次;當對方不處於輸入狀態時,該監聽還會觸發一次,可是回調裏上來的輸入用戶列表爲空,開發者須要在此時取消正在輸入的顯示,顯示原有的標題。
您能夠經過 rc_config.xml 裏的開關,開啓消息的閱讀回執功能。默認 false 爲關閉狀態,設置成 true 爲開啓。
<!-- 設置已讀回執 --> <bool name="rc_read_receipt">true</bool>
另外,請在 init 以後調用下面方法來設置支持消息回執的會話類型。目前只支持 PRIVATE、GROUP 和 DISCUSSION 三種類型。
Conversation.ConversationType[] types = new Conversation.ConversationType[] { Conversation.ConversationType.PRIVATE, Conversation.ConversationType.GROUP, Conversation.ConversationType.DISCUSSION }; RongIM.getInstance().setReadReceiptConversationTypeList(types);
若是不設置的話,默認只有 PRIVATE 類型的會話支持消息回執。
從 2.6.8 版本開始支持在羣組或者討論組中實現 @ 功能,您能夠 @ 指定用戶或 @ 全部人。
一、開啓 @ 功能
@ 功能默認爲關閉狀態,能夠在 rc_config.xml 設置 rc_enable_mentioned_message 爲 true 開啓 @ 功能。
二、設置 @ 成員信息提供者
在會話 activity,經過 RongIM.getInstance().setGroupMembersProvider(String groupId, RongIM.IGroupMemberCallback) 來設置 @ 成員信息提供者。
您能夠參考咱們 SealTalk 中的 ConversationActivity 來實現。
在 activity 的 onCreate 裏設置 @ 羣組信息提供者:
RongIM.getInstance().setGroupMembersProvider(new RongIM.IGroupMembersProvider() { @Override public void getGroupMembers(String groupId, RongIM.IGroupMemberCallback callback) { ... //獲取羣組成員信息列表 callback.onGetGroupMembersResult(list); // 調用 callback 的 onGetGroupMembersResult 回傳羣組信息 } });
三、@ 成員列表界面自定義
通過第一步打開功能開關後,您就能夠長按頭像 @ 某人或者輸入 @ 字符,彈出成員列表。該成員列表界面您能夠自定義。
自定義步驟以下:
a. RongMentionManager.setMentionedInputListener(IMentionedInputListener listener) 設置 @ 字符輸入監聽器。
b. 在監聽器的回調 onMentionedInput() 裏跳轉到您自定義的 @ 成員選擇界面,並返回 true 。
c. 在成員選擇界面,選擇成員後,調用下面的方法返回所選成員信息。
RongMentionManager.getInstance().mentionMember(item.userInfo);
d. IMentionedInputListener 說明:
public interface IMentionedInputListener { /** * 當啓動@功能,即在rc_config.xml中設置rc_enable_mentioned_message 爲true後,該方法用於設置在羣組或者討論組中,輸入@時的監聽。 * 若是{@link IMentionedInputListener#onMentionedInput(Conversation.ConversationType, String)}返回true, 則您本身處理顯示@成員 * 的選擇界面;若是返回false, 則會顯示融雲SDK默認@成員選擇界面。 * * @param conversationType 會話類型 * @param targetId 會話 id * @return 返回true, 則您本身處理顯示 @ 成員的選擇界面;若是返回false, 則會顯示融雲SDK默認@成員選擇界面。 */ boolean onMentionedInput(Conversation.ConversationType conversationType, String targetId); }
四、@ 全部人功能
@ 全部人時須要新建一個 MentionedType 爲 MentionedType.ALL的MentionedInfo ,並把它設置到 MessageContent中,例:
MentionedInfo mentionedInfo = new MentionedInfo(MentionedInfo.MentionedType.ALL, null, null); textMessage.setMentionedInfo(mentionedInfo); RongIM.getInstance().sendMessage(…);
您也能夠參考 SealTalk 中的 GroupNoticeActivity 來實現。
若是您使用的是 IMLib SDK 集成,可參考 IMLib @ 功能文檔。
從 2.6.8 版本開始 IMKit 中集成了消息撤回功能,默認爲關閉狀態。開啓後,用戶在消息發送成功後的有效時間內長按消息,在彈出菜單中選擇「撤回消息」來將這條消息撤回。這條消息將在發送端刪除,並提示「你撤回了一條消息」,同時發送撤回指令給接收端,接收端收到撤回指令後,也會把同一條消息刪除,提示「XX撤回了一條消息」。
請在 rc_config.xml 中將 rc_enable_message_recall 置爲 true 來開啓消息撤回功能。
rc_message_recall_interval 用來設置撤回消息的有效時間,以秒爲單位。當消息發送成功後,只有在有效時間內方能撤回,超過有效時間將不能再執行撤回操做。
<!-- 設置是否支持消息撤回--> <bool name="rc_enable_message_recall">true</bool> <!-- 消息撤回有效時間(單位:秒)--> <integer name="rc_message_recall_interval">120</integer>
一、 融雲官網提供 RedPacket Module 下載,開發者須要在本身應用的 build.gradle 文件中添加依賴 compile project(':RedPacket')。
二、 SDK 會默認加載紅包模塊,並在私人、羣組會話 "+" 號區域出現紅包插件(暫不支持其餘會話類型)。
三、 開發者須要實現 RongIM#setGroupMembersProvider(IGroupMembersProvider) 方法,用於紅包功能中展現羣組成員信息。
四、 紅包模塊提供以下接口,進入"個人錢包"界面:
/** * 進入個人錢包頁面 * @param activity :從哪一個activity的跳轉 */ JrmfClient.intentWallet(Activity activity);
您能夠經過 rc_config.xml 裏的開關,開啓多端同步閱讀狀態功能。默認 false 爲關閉狀態,設置成 true 爲開啓。
<!-- 開啓以後,用戶在其餘端上閱讀過的消息,當前客戶端會清掉該消息的未讀數。目前僅支持單聊、羣聊、討論組。--> <bool name="rc_enable_sync_read_status">true</bool>
分別介紹這三個 fragment 的使用方式:
靜態集成:
在 AndroidManifest.xml 會話列表Activity 下面配置 intent-filter。此處會話列表 Activity 以 ConversationListActivity 爲例,包名以 io.rong.fast 爲例:
<activity android:name="io.rong.fast.activity.ConversationListActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/conversationlist" android:scheme="rong" /> </intent-filter> </activity>
在 ConversationActivity 的佈局文件 conversationlis.xml 中靜態集成 ConversationListFragment :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/conversationlist" android:name="io.rong.imkit.fragment.ConversationListFragment" //靜態方式集成 ConversationListFragment android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
會話列表 Activity 配置對應的佈局文件。
public class ConversationListActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.conversationlist); } }
啓動會話列表 Activity :
/** * 啓動會話列表界面。 * * @param context 應用上下文。 * @param supportedConversation 定義會話列表支持顯示的會話類型,及對應的會話類型是否聚合顯示。 * 例如:supportedConversation.put(Conversation.ConversationType.PRIVATE.getName(), false) 非聚合式顯示 private 類型的會話。 */ public void startConversationList(Context context, Map<String, Boolean> supportedConversation)
注意,這個方法裏的參數 supportedConversation 是指您的會話列表須要顯示的會話類型,以及對應的會話是否聚合顯示屬性。示例:
private void startConversationList() { Map<String, Boolean> map = new HashMap<>(); map.put(Conversation.ConversationType.PRIVATE.getName(), true); // 會話列表須要顯示私聊會話, 第二個參數 true 表明私聊會話須要聚合顯示 map.put(Conversation.ConversationType.GROUP.getName(), false); // 會話列表須要顯示羣組會話, 第二個參數 false 表明羣組會話不須要聚合顯示 RongIM.getInstance().startConversationList(this.getApplicationContext(), map); }
動態集成:
在 AndroidManifest.xml 中會話列表 Activity 下面配置 intent-filter,以 ConversationListDynamicActivtiy 爲例,包名以 io.rong.fast 爲例:
<!--會話列表--> <activity android:name="io.rong.fast.test.ConversationListDynamicActivtiy" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/conversationlist" android:scheme="rong" /> </intent-filter> </activity>
會話列表佈局文件 rong_activity.xml,代碼示例:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/rong_content" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
動態加載 ConversationListFragment,並配置其顯示屬性
注意: 動態方式加載 ConversationListFragment 的時候,必須調用 setUri() 方法設置 Fragment 的顯示屬性,好比須要顯示哪些類型的會話,會話是否聚合顯示等。 具體的使用方法請參考下面示例:
public class ConversationListDynamicActivtiy extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.rong_activity); ConversationListFragment fragment = new ConversationListFragment(); Uri uri = Uri.parse("rong://" + getApplicationInfo().packageName).buildUpon() .appendPath("conversationlist") .appendQueryParameter(Conversation.ConversationType.PRIVATE.getName(), "true") //設置私聊會話,該會話聚合顯示 .appendQueryParameter(Conversation.ConversationType.GROUP.getName(), "false")//設置羣組會話,該會話非聚合顯示 .build(); fragment.setUri(uri); //設置 ConverssationListFragment 的顯示屬性 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.rong_content, fragment); transaction.commit(); } }
啓動包含會話列表頁的 Activity :
startActivity(new Intent(MainActivity.this, ConversationListDynamicActivtiy.class));
靜態集成:
在 AndroidManifest.xml 聚合會話列表 Activity 下面配置 intent-filter,以 SubConversationListActivtiy 爲例,包名以 io.rong.fast 爲例:
<activity android:name="io.rong.fast.activity.SubConversationListActivtiy" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/subconversationlist" android:scheme="rong" /> </intent-filter> </activity>
在 subconversationlist.xml 中集成 fragment,subconversationlist.xml 代碼示例:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/subconversationlist" android:name="io.rong.imkit.fragment.SubConversationListFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
在 SubConversationListActivtiy 中加載 subconversationlist.xml 便可:
public class SubConversationListActivtiy extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.subconversationlist); } }
啓動聚合會話列表 Activity:
/** * 啓動聚合後的某類型的會話列表。<br> 例如:若是設置了單聊會話爲聚合,則經過該方法能夠打開包含全部的單聊會話的列表。 * * @param context 應用上下文。 * @param conversationType 會話類型。 */ public void startSubConversationList(Context context, Conversation.ConversationType conversationType)
動態集成:
在 AndroidManifest.xml 聚合會話列表 Activity 下面配置 intent-filter,以 SubConversationListDynamicActivtiy 爲例,包名以 io.rong.fast 爲例:
<activity android:name="io.rong.fast.test.subconversationlist.SubConversationListDynamicActivtiy" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/subconversationlist" android:scheme="rong" /> </intent-filter> </activity>
加載 subconversationlist.xml 配置文件,代碼示例:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/rong_content" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
public class SubConversationListDynamicActivtiy extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.rong_activity); SubConversationListFragment fragment = new SubConversationListFragment(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.rong_content, fragment); transaction.commit(); } }
靜態集成:
在 AndroidManifest.xml 會話 Activity 下面配置 intent-filter,以 ConversationActivity 爲例,包名以 io.rong.fast 爲例:
<activity android:name="io.rong.fast.activity.ConversationActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/conversation/" android:scheme="rong" /> </intent-filter> </activity>
在會話 Activity 的佈局文件 conversation.xml 中靜態集成 ConversationFragment. 代碼示例:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/conversation" android:name="io.rong.imkit.fragment.ConversationFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
您的會話界面 Activity。
public class ConversationActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.conversation); } }
啓動會話頁面:
/** * <p>啓動會話界面。</p> * <p>使用時,能夠傳入多種會話類型 {@link io.rong.imlib.model.Conversation.ConversationType} 對應不一樣的會話類型,開啓不一樣的會話界面。 * 若是傳入的是 {@link io.rong.imlib.model.Conversation.ConversationType#CHATROOM},sdk 會默認調用 * {@link RongIMClient#joinChatRoom(String, int, RongIMClient.OperationCallback)} 加入聊天室。 * 若是你的邏輯是,只容許加入已存在的聊天室,請使用接口 {@link #startChatRoomChat(Context, String, boolean)} 而且第三個參數爲 true</p> * * @param context 應用上下文。 * @param conversationType 會話類型。 * @param targetId 根據不一樣的 conversationType,多是用戶 Id、討論組 Id、羣組 Id 或聊天室 Id。 * @param title 聊天的標題,開發者能夠在聊天界面經過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。 */ public void startConversation(Context context, Conversation.ConversationType conversationType, String targetId, String title)
動態集成:
在 AndroidManifest.xml 會話 Activity 下面配置 intent-filter,以 ConversationDynamicActivity 爲例,包名以 io.rong.fast 爲例:
<!--會話頁面--> <activity android:name="io.rong.fast.test.conversation.ConversationDynamicActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.fast" android:pathPrefix="/conversation/" android:scheme="rong" /> </intent-filter> </activity>
動態加載 ConversationFragment,根據 intent 裏面傳來的參數,經過 setUri() 設置 ConversationFragment 相關屬性。 示例:
public class ConversationDynamicActivity extends FragmentActivity { private String mTargetId; //目標 Id private Conversation.ConversationType mConversationType; //會話類型 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.rong_activity); /* 從 intent 攜帶的數據裏獲取 targetId 和會話類型*/ Intent intent = getIntent(); mTargetId = intent.getData().getQueryParameter("targetId"); mTargetIds = intent.getData().getQueryParameter("targetIds"); mConversationType = Conversation.ConversationType.valueOf(intent.getData().getLastPathSegment().toUpperCase(Locale.US())); /* 新建 ConversationFragment 實例,經過 setUri() 設置相關屬性*/ ConversationFragment fragment = new ConversationFragment(); Uri uri = Uri.parse("rong://" + getApplicationInfo().packageName).buildUpon() .appendPath("conversation").appendPath(mConversationType.getName().toLowerCase()) .appendQueryParameter("targetId", mTargetId).build(); fragment.setUri(uri); /* 加載 ConversationFragment */ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.rong_content, fragment); transaction.commit(); } }
融雲 IMKit SDK 使用 Fragment 方式實現組件的自定義和嵌入功能,提供 Fragment 能力的組件包括:
Fragment 的啓動參數是經過獲取所在 Activity 開啓時候所攜帶的 Intent 中的 Data(即 Uri )來實現的。
以會話頁面的啓動 Uri 爲例說明:
rong://{packagename:應用包名}/conversation/[private|discussion|group]?targetId={目標Id}&[title={開啓會話名稱}]
若是您的包名爲 io.rong.imkit.demo,Id 爲 12345 的討論組的 Uri 就是 rong://io.rong.imkit.demo/conversation/discussion?targetId=12345
,那麼配置 AndroidManifest.xml 文件以下:
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="io.rong.imkit.demo" android:pathPrefix="/conversation/" android:scheme="rong" /> </intent-filter>
而後,在配置的 Activity 所屬的 Layout 佈局文件上加入相應的 ConversationFragment。 這樣在 Intent 帶有如上 Uri 後就會喚起 Activity 且 Layout 中的 ConversationFragment 就能夠啓動並得到參數。 各個 Fragment 的開啓 Uri 和 Intent-filter 參數配置以下:
會話列表 ConversationListFragment
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="你的包名" android:pathPrefix="/conversationlist" android:scheme="rong" /> </intent-filter>
聚合後的會話列表 SubConversationListFragment
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="你的包名" android:path="/subconversationlist" android:scheme="rong" /> </intent-filter>
會話頁面 ConversationFragment
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="你的包名" android:pathPrefix="/conversation/" android:scheme="rong" /> </intent-filter>
公衆帳號頁面
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="你的包名" android:pathPrefix="/publicServiceProfile" android:scheme="rong" /> </intent-filter>
融雲 SDK 中已經爲開發者作了斷網重連的機制處理,開發者沒必要在斷網後作連融雲服務器的操做。
在網絡鏈接斷開後,融雲會嘗試 5
次從新鏈接服務器,首次斷網 2
秒後會從新鏈接,若是仍然鏈接不成功,會在 4
秒後(重連間隔時間爲上次重連間隔時間乘 2
)嘗度從新鏈接服務器,以此類推當嘗試重連 5
次後,仍然連不上服務器將不在嘗試從新鏈接,只有在網絡狀況發生變化或從新打開應用時纔會再次嘗試重連。
在獲取到如下錯誤狀態碼時,會進行重連:
code | 描述 |
---|---|
30001 | 進行通訊操做過程當中,當前 Socket 失效。 |
30002 | Socket 鏈接不可用。應該是您當前網絡鏈接不可用。 |
30003 | 進行各類信令的通訊操做過程當中,信令 ACK 返回超時。 |
30004 | 導航操做時,Http 請求失敗。 |
30005 | HTTP 請求失敗。 |
30006 | HTTP 接收失敗。 |
30007 | 經過 HTTP 獲取鏈接網絡必須的配置數據時,服務器返回的不是 200 OK,而是 HTTP 的其它錯誤碼。 |
30008 | 經過 HTTP 獲取配置數據時,成功得到數據,但獲得的內容體部分是空。多是您所在的網絡被劫持,HTTP 被修改。 |
30009 | 導航數據解析後,其中不存在有效 IP 地址。 |
30010 | 建立 Socket 失敗。 |
30011 | Socket 鏈接被斷開,主要有兩種狀況,一是用戶主動調用 disconnect 以後,Socket 被服務器斷開;二是中間路由緣由致使 Socket 斷開。 |
30013 | PING 超時。 |
31000 | 作 connect 鏈接時,收到的 ACK 超時。 |
融云爲了客戶隱私考慮,既不一樣步又不保存用戶的好友關係。因此,全部用戶的好友關係都須要開發者自已實現、管理維護,會話及好友列表中顯示好友的暱稱及頭像信息,須要 App 設置一個用戶信息提供者給 IMKit,以便 IMKit 經過用戶信息提供者, 來實如今聊天界面和會話列表頁中顯示好友的暱稱和頭像。詳細請參見用戶信息提供者參考文檔及好友關係實現示例,視頻教程以下:
陌生人發送加好友邀請,可經過 ContactNotificationMessage
消息類實現。詳情請參見 內置通知類消息
中的聯繫人(好友)通知消息。
startPrivateChat
方法啓動會話界面。傳入要與之聊天的
targetUserId
後便可進行陌生人會話。
應用標識是爲了咱們的 API 可以正確識別並驗證您的應用請求而所必要的信息,對於防止帳戶盜用和濫用有着重要的做用。針對 Android 平臺,須要填寫包名即 Package Name,就是在 AndroidManifest.xml
中的 package
屬性值,如圖所示。
-keepattributes Exceptions,InnerClasses
-keepattributes Signature
# RongCloud SDK -keep class io.rong.** {*;} -keep class * implements io.rong.imlib.model.MessageContent {*;} -dontwarn io.rong.push.** -dontnote com.xiaomi.** -dontnote com.google.android.gms.gcm.** -dontnote io.rong.** # VoIP -keep class io.agora.rtc.** {*;} # Location -keep class com.amap.api.**{*;} -keep class com.amap.api.services.**{*;} # 紅包 -keep class com.google.gson.** { *; } -keep class com.uuhelper.Application.** {*;} -keep class net.sourceforge.zbar.** { *; } -keep class com.google.android.gms.** { *; } -keep class com.alipay.** {*;} -keep class com.jrmf360.rylib.** {*;} -ignorewarnings
另外,您須要 keep 自定義的 BroadcastReceiver 。自定義的 BroadcastReceiver 繼承PushMessageReceiver,使用下面的代碼是不行的。
-keep public class * extends android.content.BroadcastReceiver
您須要使用下面的代碼 keep 自定義的 BroadcastReceiver。
這裏 io.rong.app.DemoNotificationReceiver
改爲您的應用自定義的完整類名
-keep class io.rong.app.DemoNotificationReceiver {*;}
集成融雲 SDK 過程當中,如遇到問題可查看常見狀態碼及處理表。