枕上从妨一夜睡,灯前读尽十年诗。这篇文章主要讲述Android 融云IM集成方法以及解决的一些问题相关的知识,希望能为你提供帮助。
融云IM的集成方式网上资料也就几篇,看一下还是可以的,官网的资料以及QA还是比较好的,就是官方提供的Demo可能比较老了,现在android端一天一个样,demo好像很难运行起来。
官方文档写的很详细了:https://www.rongcloud.cn/docs/#necessary
- 首先是注册,获取 App Key / Secret,其中Android端只需要APP key就可以。
- 下载导入imLib 和IMkIt,其中IMLib是核心库,IMkit是UI界面库,建议先引入Lib,再进入Kit,最后检查一下,Kit需要依赖Lib.
- 在AndroidManifest中配置,需要在自己的app的manifest中增加对应的activity,还要修改包名,我就是换了一个项目,找了半天才发现包名有问题。另外,还需要在imLib中修改appKey。
- 在application中进行初始化。
到这差不多就算集成进去了,下面就到代码阶段了
- 首先就是用户连接IM服务器,需要传入一个用户Token,在添加用户的时候,融云会返回该用户的Token,该token需要永久保存到自己服务器的数据库中,用户登录自己系统的账户之后,把该Token下发回去,然后再用Token登录IM。
- 融云不提供用户添加好友,以及用户列表的功能,如果需要该功能,可以在自己的服务器中进行管理。发送消息只需要targetId即可发送。
- 下面应该就是配置消息界面,这里可以采用官方提供的UI界面。由于我是采用AndroidX所以遇到了fragment无法转换的异常,不过我在看了官方的QA之后,说报错依然可以执行(我也尝试了AS自带的migrate to androidX功能,不过感觉没啥用)
import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import android.net.Uri; import android.os.Bundle; import io.rong.imkit.fragment.ConversationListFragment; import io.rong.imlib.model.Conversation; public class ConversationListActivity extends AppCompatActivity {@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_conversation_list); FragmentManager fragmentManage = getSupportFragmentManager(); ConversationListFragment fragement = (ConversationListFragment) fragmentManage.findFragmentById(R.id.conversationlist); Uri uri = Uri.parse("rong://" + 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(); fragement.setUri(uri); } }
【Android 融云IM集成方法以及解决的一些问题】
文章图片
这里报错是正常的
- 最后就是具体的聊天页面了,这里需要自己写title页面,可以从Intent中获取一些数据。
import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import android.net.Uri; import android.os.Bundle; import io.rong.imkit.fragment.ConversationFragment; import io.rong.imlib.model.Conversation; public class ConversationActivity extends AppCompatActivity {//private Conversation.ConversationType mConversationType; //private String mTargetId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_conversation); //mTargetId = getIntent().getStringExtra("targetId"); //mConversationType = (Conversation.ConversationType) getIntent().getSerializableExtra("conversationType"); Uri data = https://www.songbingjia.com/android/getIntent().getData(); String title = getIntent().getData().getQueryParameter("title"); String targetId = getIntent().getData().getQueryParameter("targetId"); String conversation = getIntent().getData().getQueryParameter("conversation"); Conversation.ConversationType type= Conversation.ConversationType.CHATROOM; FragmentManager fragmentManage = getSupportFragmentManager(); ConversationFragment fragement = (ConversationFragment) fragmentManage.findFragmentById(R.id.conversation); //Uri uri = Uri.parse("rong://" + getApplicationInfo().packageName).buildUpon() //.appendPath("conversation").appendPath(type.getName().toLowerCase()) //.appendQueryParameter("targetId", targetId).build(); fragement.setUri(data); } }
文章图片
下面是遇到的一些问题
- 我项目的消息列表页面采用的是fragment+viewPage的方式,而官方提供的方式却是activity中的,而且我还需要在消息列表页面添加其他控件,所以我采用了fragment中套IM提供的fragment。
public class MessageFragment extends BaseFragment{String packageName; public MessageFragment(String packageName){ this.packageName=packageName; }@Override protected int provideContentViewId() { return R.layout.fragment_message_list; }@BindView(R2.id.vp_contain)FrameLayout vp_contain; @BindView(R2.id.toolbar)Toolbar toolbar; @Override public void initView(View rootView) { super.initView(rootView); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); Fragment homeFragment= setConversationView(); transaction.add(vp_contain.getId(), homeFragment); transaction.show(homeFragment).commit(); }private Fragment setConversationView() { ConversationListFragment conversationListFragment = new ConversationListFragment(); conversationListFragment.setAdapter(new ConversationListAdapterEx(RongContext.getInstance())); //自定义列表页面(下面有讲,不需要,可以删除) Uri uri = Uri.parse("rong://" + packageName).buildUpon().appendPath("activity_chat_main") .appendQueryParameter(Conversation.ConversationType.PRIVATE.getName(), "false") .appendQueryParameter(Conversation.ConversationType.GROUP.getName(), "false") .appendQueryParameter(Conversation.ConversationType.SYSTEM.getName(), "true").build(); conversationListFragment.setUri(uri); return conversationListFragment; } }
activity_conversation.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"> < TextView android:id="@+id/tv_title" android:text="用户名" android:textSize="30sp" android:gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="50dp"/> < fragment android:id="@+id/conversation" android:name="io.rong.imkit.fragment.ConversationFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> < /LinearLayout>
2.该IM最新版本好像只能获取ID信息,无法获取用户名,所以在消息列表页面,展示的是用户ID,而我想展示的是用户名。这就需要修改列表页面的数据了。而用户名需要从自己的服务器中获取,然后缓存在手机中,这需要考虑不同项目的情况。可以在查询对方手机号的时候,返回对方的ID以及用户名,也可以在本地没有找到的情况下,去请求自己的服务器。
import android.content.Context; import android.view.View; import android.view.ViewGroup; import io.rong.imkit.model.UIConversation; import io.rong.imkit.userInfoCache.RongUserInfoManager; import io.rong.imkit.widget.adapter.ConversationListAdapter; import io.rong.imlib.model.Conversation; import io.rong.imlib.model.UserInfo; public class ConversationListAdapterEx extends ConversationListAdapter { public ConversationListAdapterEx(Context context) { super(context); }@Override protected View newView(Context context, int position, ViewGroup group) { return super.newView(context, position, group); }@Override protected void bindView(View v, int position, UIConversation data) { if(data.getConversationType().equals(Conversation.ConversationType.DISCUSSION)) data.setUnreadType(UIConversation.UnreadRemindType.REMIND_ONLY); UserInfo userInfo =RongUserInfoManager.getInstance().getUserInfo(data.getUIConversationTitle()); if (userInfo!=null){ String s = userInfo.toString(); data.setUIConversationTitle(s); } super.bindView(v, position, data); } }
@Override public void getUserIdSuccess(UserBean user) { RongIM.getInstance().startConversation(getContext(), Conversation.ConversationType.PRIVATE,user.getUserId()+"", "悟空"); UserInfo userInfo = new UserInfo(user.getUserId()+"",user.getUserName(),null); RongUserInfoManager.getInstance().setUserInfo(userInfo); }
这里采用了IM提供的用户缓存工具:RongUserInfoManager.getInstance().getUserInfo(data.getUIConversationTitle()),需要在成功获取用户信息之后,保存到本地。
推荐阅读
- delphi7:Application.ProcessMessages的作用
- Android Service启动原理分析
- Android Studio导入项目报错/警告/变红
- (4 Android )实验项目_Android开发环境搭建
- flutter坑:Android license status unknown and also Android sdkmanager tool not found
- 使用Fiddler对APP进行弱网测试
- Java深入学习03(happens-before规则)
- 报错RuntimeError: Model class apps.user.models.User doesn't declare an explicit app_label and isn&
- Android开机自启动应用