項目總結之即時通訊
融云的服務真是快,有問題提工單,工程師回答速度快,可以很方便解決實際開發中的問題。作為總結,我們還是隨便聊聊融云的使用吧!直接進入正題————>>>
首先去融云開發者平臺注冊、下載SDK、導包、連接、實現會話列表和會話界面這里就簡單說明一下。不懂的可以去之前文章看。本片重點說一下自定義消息和plugin擴展區域自定義。
第一步,使用第三方的東西肯定要去他們的官網注冊一個開發者賬號,步驟很簡單,一步步填寫,下一步就行。注意手機號的填寫,還是要填寫真實的,貌似有條規定,如果手機號為空號可能會導致他們不會給改用戶下的app提供服務,所以為了安全起見還是填寫真實的手機號碼。注冊鏈接地址。
第二步:下載SDK,建議SDK別使用當前太低版本、因為有些功能可能不支持。下載SDK時,我們也要把官方提供的demo下載下來,畢竟這是第一手資料,官網提供的demo功能還是比較豐富的,如果應用要求的功能不是很多,demo里面提供的基本功能使應該能滿足的。demo可能是托管在github上的,所以還要有個git賬號。請自行注冊,畢竟開發者還是應該多去上面看看大牛寫的開源東西來學習。
第三步:注冊應用,使用第三方的工具,不注冊怎么用呢?個人中心填寫下應用的基本情況應該沒啥問題了。
簡要的幾個步驟,具體使用可以參照官方提供的幫助文檔,官方文檔地址戳這里
功能介紹
前沿簡介
前奏
使用第三方的庫,首先就需要進行第三方要求的初始化操作,這部分代碼,基本直接copy官網提供的就可以,這樣可以保證準確性。所以這里簡要介紹需要我們處理的幾個點。
1、Manifest.xml文件中:
android:host選項的值全部為自己應用的包名。例如:android:host=”com.dsw.infor”
meta-data標簽中的appkey的值要改為自己應用申請的appkey
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mydemoplugin">
<permission
android:name="cn.rongcloud.im.permission.MIPUSH_RECEIVE"
android:protectionLevel="signature" /> <!-- 發送位置消息,實時位置共享,如果您需要定位相關的功能,可以打開以下注釋 -->
<permission
android:name="cn.rongcloud.im.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<permission
android:name="cn.rongcloud.im.push.permission.MESSAGE"
android:protectionLevel="signature" /> <!-- targetSdkVersion為29時,如果需要后臺定位權限,需要添加 ACCESS_BACKGROUND_LOCATION 權限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- ?米 配置開始 < -->
<uses-permission android:name="MediaStore.Images.Media.INTERNAL_CONTENT_URI" />
<uses-permission android:name="MediaStore.Images.Media.EXTERNAL_CONTENT_URI" /> <!-- ?米 配置結束 < -->
<!-- GCM 配置開始 < -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- GCM 配置結束 < -->
<!-- 華為 配置開始 < -->
<!-- HMS-SDK引導升級HMS功能,訪問OTA服務器需要網絡權限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- HMS-SDK引導升級HMS功能,保存下載的升級包需要SD卡寫權限 -->
<uses-permission android:name="cn.rongcloud.im.permission.MIPUSH_RECEIVE" /> <!-- 檢測網絡狀態 -->
<uses-permission android:name="cn.rongcloud.im.permission.C2D_MESSAGE" /> <!-- 檢測wifi狀態 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- 為了獲取用戶手機的IMEI,用來唯一的標識用戶;發送位置及實時位置時需要此權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 如果是安卓8.0,應用編譯配置的targetSdkVersion>=26,請務必添加以下權限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 華為 配置結束 < -->
<!-- MeiZu 配置開始 < -->
<!-- 兼容 flyme5.0 以下版本,魅族內部集成 pushSDK 必填,不然無法收到 消息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <!-- 兼容 flyme3.0 配置權限 -->
<uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE" /> <!-- MeiZu 配置結束 < -->
<!-- OPPPO 權限配置 -->
<uses-permission android:name="cn.rongcloud.im.push.permission.MESSAGE" /> <!-- OPPO 配置結束 -->
<uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" /> <!-- 為了獲取用戶手機的IMEI,用來唯一的標識用戶;發送位置消息,實時位置共享需要此權限 -->
<uses-permission android:name="com.coloros.mcs.permission.SEND_MCS_MESSAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyDemoPlugin">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".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="com.example.mydemoplugin"
android:pathPrefix="/conversation/"
android:scheme="rong" />
</intent-filter>
</activity>
<activity
android:name=".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="com.example.mydemoplugin"
android:pathPrefix="/conversationlist"
android:scheme="rong" />
</intent-filter>
</activity>
</application>
</manifest>
2、在我們的Application中進行初始化,執行RongIM.init(this);
代碼如下:
/**
* 應用啟動時,判斷用戶是否已接受隱私協議,如果已接受,正常初始化;否則跳轉到隱私授權頁面請求用戶授權。
*/
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
// if (!AppContext.isInitialized()) {
// AppContext.init(getApplicationContext());
// }
//用戶已接受隱私協議,進行初始化
String appKey = "pvxdm17jpws8r";
// 第一個參數必須傳應用上下文
RongIM.init(this.getApplicationContext(), appKey);
//注冊Plugin自定義類型
registerExtensionPlugin();
//消息自定義類型
RongIM.registerMessageType(RedPackageMessage.class);
RongIM.registerMessageTemplate(new RedPackageItemProvider());
}
private void registerExtensionPlugin() {
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().unregisterExtensionModule(defaultModule);
RongExtensionManager.getInstance().registerExtensionModule(new SealExtensionModule());
}
}
}
}
3、初始化的工作完成后,然后我們就在我們成功登陸后,進行服務器的鏈接。此時,我們需要調用我們的后臺來獲取融云認證的token信息。測試階段,我們可以使用api調試,手動生成來用。
RongIM.connect(token, new ConnectCallback() {
@Override
public void onSuccess(String arg0) {
Log.d("RongClound", "RongClound: Tocken Success");
}
@Override
public void onError(ErrorCode arg0) {
Log.d("RongClound", "RongClound: Tocken Error,ErrorCode:" + arg0);
}
@Override
public void onTokenIncorrect() {
Log.d("RongClound", "RongClound: onTokenIncorrect");
}
});
4.單聊功能
由于IMKit中融云提供的界面都是基于fragment,所以使用也是簡單,我們只需要簡單配置下我們的會話列表界面就可以了,比如:
<?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">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
布局搞好了,我們要創建一個ConversationActivity來進行顯示。
public class ConversationListActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_conversation_list);
ConversationListFragment conversationListFragment=new ConversationListFragment();
// 此處設置 Uri. 通過 appendQueryParameter 去設置所要支持的會話類型. 例如
// .appendQueryParameter(Conversation.ConversationType.PRIVATE.getName(),"false")
// 表示支持單聊會話, false 表示不聚合顯示, true 則為聚合顯示
Uri uri = Uri.parse("rong://" +
getApplicationContext().getApplicationInfo().packageName).buildUpon()
.appendPath("conversationlist")
.appendQueryParameter(Conversation.ConversationType.PRIVATE.getName(), "false") //設置私聊會話是否聚合顯示
.appendQueryParameter(Conversation.ConversationType.GROUP.getName(), "false")//群組
.appendQueryParameter(Conversation.ConversationType.PUBLIC_SERVICE.getName(), "false")//公共服務號
.appendQueryParameter(Conversation.ConversationType.APP_PUBLIC_SERVICE.getName(), "false")//訂閱號
.appendQueryParameter(Conversation.ConversationType.SYSTEM.getName(), "true")//系統
.build();
conversationListFragment.setUri(uri);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, conversationListFragment);
transaction.commit();
Activity創建好自然要在Manifest中進行聲明
<activity
android:name=".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="com.example.mydemoplugin"
android:pathPrefix="/conversationlist"
android:scheme="rong" />
</intent-filter>
</activity>
回話界面
<?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">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
public class ConversationActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_conversation);
ConversationFragment conversationFragment = new ConversationFragment();
Intent intent = getIntent(); // 取得從上一個Activity當中傳遞過來的Intent對象
String targetId = null;
if (intent != null) {
targetId = intent.getStringExtra("targetId");
}
Uri uri = Uri.parse("rong://" +
getApplicationContext().getApplicationInfo().packageName).buildUpon()
.appendPath("conversation").appendPath("private")
.appendQueryParameter("targetId", targetId)//設置私聊會話是否聚合顯示,targetId:單聊人的id
.build();
conversationFragment.setUri(uri);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, conversationFragment);
transaction.commit();
}
}
至此單聊功能就實現了!開始進入正題自定義消息和Plugin擴展。
自定義消息
參考資料:http://www.rongcloud.cn/docs/android.html#新建消息
- 自定義消息實體 –RedPackageMessage(一個自定義的紅包消息)
package com.example.mydemoplugin.PhoneInfoProvider;
/**
* Created by zhangbowen on 6/15/21.
**/
import android.os.Parcel;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import io.rong.common.ParcelUtils;
import io.rong.imlib.MessageTag;
import io.rong.imlib.model.MessageContent;
import io.rong.message.CSSuspendMessage;
/*
* 注解名:MessageTag ;屬性:value ,flag; value 即 ObjectName 是消息的唯一標識不可以重復,
* 開發者命名時不能以 RC 開頭,避免和融云內置消息沖突;flag 是用來定義消息的可操作狀態。
*如下面代碼段,自定義消息名稱 CustomizeMessage ,vaule 是 app:custom ,
* flag 是 MessageTag.ISCOUNTED | MessageTag.ISPERSISTED 表示消息計數且存庫。
* app:RedPkgMsg: 這是自定義消息類型的名稱,測試的時候用"app:RedPkgMsg";
* */
@MessageTag(value = "app:RedPkgMsg", flag = MessageTag.ISCOUNTED | MessageTag.ISPERSISTED)
public class RedPackageMessage extends MessageContent {
//自定義的屬性
private String title;
private String storeName;
private String desc1;
private String desc2;
public RedPackageMessage() {
}
public static RedPackageMessage obtain(String title, String storeName, String desc1, String desc2) {
RedPackageMessage message = new RedPackageMessage();
message.title = title;
message.storeName = storeName;
message.desc1 = desc1;
message.desc2 = desc2;
return message;
}
/*
*
* 實現 encode() 方法,該方法的功能是將消息屬性封裝成 json 串,
* 再將 json 串轉成 byte 數組,該方法會在發消息時調用,如下面示例代碼:
* */
@Override
public byte[] encode() {
JSONObject jsonObj = new JSONObject();
try {
jsonObj.put("title", this.getTitle());
jsonObj.put("storeName", this.getStoreName());
jsonObj.put("desc1", this.getDesc1());
jsonObj.put("desc2", this.getDesc2());
} 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 RedPackageMessage(byte[] data) {
String jsonStr = null;
try {
jsonStr = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
try {
JSONObject jsonObj = new JSONObject(jsonStr);
if (jsonObj.has("title"))
setTitle(jsonObj.optString("title"));
if (jsonObj.has("storeName"))
setStoreName(jsonObj.optString("storeName"));
if (jsonObj.has("desc1"))
setDesc1(jsonObj.optString("desc1"));
if (jsonObj.has("desc2"))
setDesc2(jsonObj.optString("desc2"));
} catch (JSONException e) {
Log.d("JSONException", e.getMessage());
}
}
//給消息賦值。
public RedPackageMessage(Parcel in) {
setTitle(ParcelUtils.readFromParcel(in));//該類為工具類,消息屬性
//這里可繼續增加你消息的屬性
setStoreName(ParcelUtils.readFromParcel(in));//該類為工具類,消息屬性
setDesc1(ParcelUtils.readFromParcel(in));//該類為工具類,消息屬性
setDesc2(ParcelUtils.readFromParcel(in));//該類為工具類,消息屬性
}
/**
* 讀取接口,目的是要從Parcel中構造一個實現了Parcelable的類的實例處理。
*/
public static final Creator<RedPackageMessage> CREATOR = new Creator<RedPackageMessage>() {
@Override
public RedPackageMessage createFromParcel(Parcel source) {
return new RedPackageMessage(source);
}
@Override
public RedPackageMessage[] newArray(int size) {
return new RedPackageMessage[size];
}
};
@Override
public int describeContents() {
return 0;
}
/**
* 將類的數據寫入外部提供的 Parcel 中。
*
* @param dest 對象被寫入的 Parcel。
* @param flags 對象如何被寫入的附加標志。
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
ParcelUtils.writeToParcel(dest, getTitle());
ParcelUtils.writeToParcel(dest, getStoreName());
ParcelUtils.writeToParcel(dest, getDesc1());
ParcelUtils.writeToParcel(dest, getDesc2());
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
public String getDesc2() {
return desc2;
}
public void setDesc2(String desc2) {
this.desc2 = desc2;
}
}
2.自定義消息提供者
package com.example.mydemoplugin.PhoneInfoProvider;
import android.content.ClipboardManager;
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.mydemoplugin.R;
import io.rong.imkit.RongIM;
import io.rong.imkit.emoticon.AndroidEmoji;
import io.rong.imkit.model.ProviderTag;
import io.rong.imkit.model.UIMessage;
import io.rong.imkit.utilities.OptionsPopupDialog;
import io.rong.imkit.widget.provider.IContainerItemProvider;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Message;
/**
* Created by zhangbowen on 6/15/21.PhoneInfo的布局
* desc新建一個消息類繼承 IContainerItemProvider.MessageProvider 類,實現對應接口方法,
* 1.注意開頭的注解!
* 2.注意泛型!
*/
@ProviderTag(
messageContent = RedPackageMessage.class,
showReadState = true
)
public class RedPackageItemProvider extends IContainerItemProvider.MessageProvider<RedPackageMessage> {
public RedPackageItemProvider() {
}
@Override
public View newView(Context context, ViewGroup viewGroup) {
//這就是展示在會話界面的自定義的消息的布局
View view = LayoutInflater.from(context).inflate(R.layout.item_redpackage_message, null);
ViewHolder holder = new ViewHolder();
holder.ll_msg = (FrameLayout) view.findViewById(R.id.ll_msg);
holder.tvTitle = (TextView) view.findViewById(R.id.tv_title);
holder.tvStoreName = (TextView) view.findViewById(R.id.tv_store_name);
holder.tvDesc1 = (TextView) view.findViewById(R.id.tv_desc1);
holder.tvDesc2 = (TextView) view.findViewById(R.id.tv_desc2);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, int i, RedPackageMessage redPackageMessage, UIMessage message) {
//根據需求,適配數據
ViewHolder holder = (ViewHolder) view.getTag();
if (message.getMessageDirection() == Message.MessageDirection.SEND) {//消息方向,自己發送的
// holder.ll_msg.setBackgroundResource(io.rong.imkit.R.drawable.rc_ic_bubble_right);
} else {
// holder.ll_msg.setBackgroundResource(io.rong.imkit.R.drawable.rc_ic_bubble_left);
}
// AndroidEmoji.ensure((Spannable) holder.message.getText());//顯示消息中的 Emoji 表情。
holder.tvTitle.setText(redPackageMessage.getTitle());
holder.tvStoreName.setText(redPackageMessage.getStoreName());
holder.tvDesc1.setText(redPackageMessage.getDesc1());
holder.tvDesc2.setText(redPackageMessage.getDesc2());
}
@Override
public Spannable getContentSummary(RedPackageMessage redPackageMessage) {
return new SpannableString(redPackageMessage.getDesc1());
}
@Override
public void onItemClick(View view, int i, RedPackageMessage redPackageMessage, UIMessage uiMessage) {
}
@Override
public void onItemLongClick(View view, int i, RedPackageMessage redPackageMessage, UIMessage uiMessage) {
//實現長按刪除等功能,咱們直接復制融云其他provider的實現
String[] items1;//復制,刪除
items1 = new String[]{view.getContext().getResources().getString(io.rong.imkit.R.string.rc_dialog_item_message_copy), view.getContext().getResources().getString(io.rong.imkit.R.string.rc_dialog_item_message_delete)};
OptionsPopupDialog.newInstance(view.getContext(), items1).setOptionsPopupDialogListener(new OptionsPopupDialog.OnOptionsItemClickedListener() {
public void onOptionsItemClicked(int which) {
// Log.e("實現長按刪除等功能",uiMessage.getMessage().getMessageId()+"---"+redPackageMessage.describeContents()+"-----"+uiMessage.getMessage());
//長安復制暫時沒有實現
if (which == 0) {
ClipboardManager clipboard = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
// clipboard.setText(redPackageMessage.encode());//這里是自定義消息的消息屬性
} else if (which == 1) {
RongIM.getInstance().deleteMessages(new int[]{uiMessage.getMessage().getMessageId()}, (RongIMClient.ResultCallback) null);
}
}
}).show();
}
private static class ViewHolder {
TextView tvTitle, tvStoreName, tvDesc1, tvDesc2;
FrameLayout ll_msg;
}
}
3.注意自定義消息的布局:(整體布局外面再嵌套一層)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="220dp"
android:layout_height="100dp"
android:background="#eca24f">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="23dp"
android:layout_marginTop="8dp"
android:text="標題"
android:textColor="#333fff"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_store_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_marginTop="36dp"
android:singleLine="true"
android:text="店名店名店名店名店名店名店名店名店名"
android:textColor="@color/white"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_desc1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_marginTop="55dp"
android:singleLine="true"
android:text="送你一個現金紅包"
android:textColor="@color/white"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_desc2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_marginTop="73dp"
android:singleLine="true"
android:text="點擊領取紅包"
android:textColor="@color/white"
android:textSize="12dp" />
</RelativeLayout>
</FrameLayout>
4.注冊消息類型以及消息提供者
RongIM.init(this);
//注意,要在初始化之后注冊
RongIM.registerMessageType(RedPackageMessage.class);
RongIM.registerMessageTemplate(new RedPackageItemProvider());
5.官網測試發消息
6.自定義紅包Plugin
/**
* Created by zhangbowen on 6/15/21.
* 自定義紅包Plugin
**/
public class MyPlugin implements IPluginModule {
@Override
public Drawable obtainDrawable(Context context) {
return ContextCompat.getDrawable(context, io.rong.imkit.R.drawable.rc_cs_evaluate_selector);
}
@Override
public String obtainTitle(Context context) {
return "紅包";
}
@Override
public void onClick(Fragment fragment, RongExtension rongExtension) {
Log.e("發紅包啦!!!", rongExtension.getTargetId());
RedPackageMessage redPackageMessage = RedPackageMessage.obtain("測試" + new Random().nextInt(1000), "商店名稱" + new Random().nextInt(1000), "描述" + new Random().nextInt(1000), "描述" + new Random().nextInt(1000));
RongIM.getInstance().sendMessage(Conversation.ConversationType.PRIVATE, rongExtension.getTargetId(), redPackageMessage, "測試一下pushContent" + new Random().nextInt(100), "測試一下pushData" + new Random().nextInt(100)
, new IRongCallback.ISendMediaMessageCallback() {
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(Message message, RongIMClient.ErrorCode errorCode) {
}
@Override
public void onProgress(Message message, int i) {
}
@Override
public void onCanceled(Message message) {
}
});
}
@Override
public void onActivityResult(int i, int i1, Intent intent) {
Log.e("發紅包啦!!!", "onActivityResult");
}
}
/**
* Created by zhangbowen on 6/15/21.
* Plugin自定義類型
**/
public class SealExtensionModule extends DefaultExtensionModule {
@Override
public List<IPluginModule> getPluginModules(Conversation.ConversationType conversationType) {
List<IPluginModule> pluginModuleList = new ArrayList<>();
IPluginModule image = new ImagePlugin();
IPluginModule location = new DefaultLocationPlugin();
// IPluginModule audio = new AudioPlugin();
// IPluginModule video = new VideoPlugin();
IPluginModule file = new FilePlugin();
IPluginModule myPlugin = new MyPlugin();
if (conversationType.equals(Conversation.ConversationType.GROUP) ||
conversationType.equals(Conversation.ConversationType.DISCUSSION) ||
conversationType.equals(Conversation.ConversationType.PRIVATE)) {
pluginModuleList.add(image);
pluginModuleList.add(location);
// pluginModuleList.add(audio);
// pluginModuleList.add(video);
pluginModuleList.add(file);
pluginModuleList.add(myPlugin);
} else {
pluginModuleList.add(image);
}
return pluginModuleList;
}
@Override
public List<IEmoticonTab> getEmoticonTabs() {
return super.getEmoticonTabs();
}
}
7.將自定義好的Plugin重新注冊(在init初始化之后注冊)
private void registerExtensionPlugin() {
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().unregisterExtensionModule(defaultModule);
RongExtensionManager.getInstance().registerExtensionModule(new SealExtensionModule());
}
}
}
以上就是關于融云在項目中的使用,融云提供很多功能,希望以后有機會再深入研究吧!
簡單demo下載地址