您的位置:首页 > 其它

项目总结之即时通讯

2015-09-16 16:38 417 查看

项目总结之即时通讯

新项目尹始,项目有个模块称之为即时通讯,何谓即时通讯?通过与产品经理交流得知,做个类似QQ聊天方式的通讯工具。大白话就是让app的使用者之间能够相互聊天,发送消息、发送图片之类的。听到这,果断一头雾水外加一脸茫然,没搞过这玩意啊!有问题肯定要问大神啊!其实,百度上搜搜,及时通讯的第三方工具还是比较多的,比如:容联云通讯、亲加通讯云、融云等等。最后确定使用融云通讯,总体说来使用还是比较方便的。另外说一句,融云的服务真是快,有问题提工单,工程师回答速度快,可以很方便解决实际开发中的问题。作为总结,我们还是随便聊聊融云的使用吧!

第一步,使用第三方的东西肯定要去他们的官网注册一个开发者账号,步骤很简单,一步步填写,下一步就行。注意手机号的填写,还是要填写真实的,貌似有条规定,如果手机号为空号可能会导致他们不会给改用户下的app提供服务,所以为了安全起见还是填写真实的手机号码。注册链接地址

第二步:下载SDK,建议SDK别使用当前太低版本、因为有些功能可能不支持。下载SDK时,我们也要把官方提供的demo下载下来,毕竟这是第一手资料,官网提供的demo功能还是比较丰富的,如果应用要求的功能不是很多,demo里面提供的基本功能使应该能满足的。demo可能是托管在github上的,所以还要有个git账号。请自行注册,毕竟开发者还是应该多去上面看看大牛写的开源东西来学习。

第三步:注册应用,使用第三方的工具,不注册怎么用呢?个人中心填写下应用的基本情况应该没啥问题了。

简要的几个步骤,具体使用可以参照官方提供的帮助文档,官方文档地址戳这里

上面的弄好了,我们可以下载官方的demo来体验一把效果如何。总体来说还是不错的,下面我们直接切入我们的项目正题,我们项目比较简单,只需要提供单聊功能、讨论组功能、以及会话列表展示的功能,所以功能还是比较简单,功能使用官网的demo基本能搞定,当然中途还会遇到一些问题,稍后我们慢慢聊。

功能介绍

前沿简介

融云为不同层次应用提供了不同两个开发库,融云 SDK 包括两部分:IM 界面组件和 IM 通讯能力库。

IM 界面组件 - IMKit
IMKit 是融云 SDK 的核心特色之一。融云将即时通讯产品中最复杂的会话列表、聊天窗口、消息内容展现、会话设置等功能封装为组件,通过简短的代码,您就可以直接将以上界面集成到您的 App 产品中,省去大量的开发调试时间。融云同时支持业内最丰富的自定义界面组件功能,您可以针对自己界面需求自由设计开发。IMKit 的核心类在 Android 平台是 RongIM,在 iOS 平台是 RCIM,这两个类在今后的开发中和 IMKit 代表相同的意义。

IM 通讯能力库 - IMLib

IMLib 是不含界面的基础 IM 通讯能力库,封装了通信能力和会话、消息等对象。引用到 App 工程中后,需要开发者自己实现 UI 界面,相对较轻量,适用于对 UI 有较高订制需求的开发者。

IMLib 的核心类在 Android 平台是 RongIMClient,在 iOS 平台是 RCIMClient,这两个类在今后的开发中和 IMLib 代表相同的意义。

所以根据上面的介绍,在结合我们项目中的需求,我们肯定使用IMKit库进行开发,节省时间方便。

前奏

使用第三方的库,首先就需要进行第三方要求的初始化操作,这部分代码,基本直接copy官网提供的就可以,这样可以保证准确性。所以这里简要介绍需要我们处理的几个点。

1、Manifest.xml文件中:

(1)、添加user-permission权限,如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 获取机型信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />

<!-- 查看 Wi-Fi 状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 查看网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- 录音 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 控制振动器 -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 防止设备休眠 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<!--获取联系人信息,demo中演示发送通讯录消息-->
<uses-permission android:name="android.permission.READ_CONTACTS" />


(2)、添加融云必备的activity、服务、广播的声明。有几点需要修改:

android:host选项的值全部为自己应用的包名。例如:android:host=”com.dsw.infor”

meta-data标签中的appkey的值要改为自己应用申请的appkey

<!--begin rongcloud-->
<activity
android:name="io.rong.voipkit.activity.CallSideActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<data
android:host="io.rong.app"
android:pathPrefix="/VoIPCall"
android:scheme="rong" />
</intent-filter>
</activity>

<activity
android:name="io.rong.voipkit.activity.CalledSideActivity"
android:excludeFromRecents="true"
android:screenOrientation="portrait">

<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<data
android:host="io.rong.app"
android:pathPrefix="/VoIPAccept"
android:scheme="rong" />
</intent-filter>
</activity>

<service
android:name="io.rong.push.PushService"
android:process="io.rong.push" >
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />

<action android:name="io.rong.push" />
</intent-filter>
</service>
<service
android:name="io.rong.push.CommandService"
android:process="io.rong.push" > <!-- Waring: The name of the push process can't be changed!!! -->
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />

<action android:name="io.rong.command" />
</intent-filter>
</service>

<receiver
android:name="io.rong.push.PushReceiver"
android:process="io.rong.push" > <!-- Waring: The name of the push process can't be changed!!! -->
<intent-filter>
<action android:name="io.rong.imlib.action.push.heartbeat" />
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />

<data android:scheme="package" />
</intent-filter>
</receiver>

<activity
android:name="io.rong.imkit.tools.SelectPictureActivity"
android:screenOrientation="portrait" />
<activity
android:name="io.rong.imkit.tools.PreviewPictureActivity"
android:screenOrientation="portrait" />
<activity
android:name="io.rong.imkit.tools.RongWebviewActivity"
android:screenOrientation="portrait" />
<activity
android:name="io.rong.imkit.widget.provider.TakingPicturesActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait" />

<service
android:name="io.rong.imlib.ipc.RongService"
android:process=":ipc" >
</service>
<service android:name="io.rong.imlib.ReConnectService" />

<receiver android:name="io.rong.imlib.ConnectChangeReceiver" />
<receiver android:name="io.rong.imlib.ipc.PushMessageReceiver" >
<intent-filter>
<action android:name="io.rong.push.message" />
</intent-filter>
</receiver>
<receiver
android:name="io.rong.imlib.HeartbeatReceiver"
android:process=":ipc" />
<meta-data
android:name="RONG_CLOUD_APP_KEY"
android:value="z3v5yqkbv8v30" />

<!--end rongcloud-->


2、在我们的Application中进行初始化,执行RongIM.init(this);

代码如下:

public class App extends Application {

@Override
public void onCreate() {

super.onCreate();

/**
* 注意:
*
* IMKit SDK调用第一步 初始化
*
* context上下文
*
* 只有两个进程需要初始化,主进程和 push 进程
*/
if("io.rong.app".equals(getCurProcessName(getApplicationContext())) ||
"io.rong.push".equals(getCurProcessName(getApplicationContext()))) {

RongIM.init(this);
}
}

public static String getCurProcessName(Context context) {
int pid = android.os.Process.myPid();
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo appProcess : activityManager
.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
return appProcess.processName;
}
}
return null;
}
}


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");
}
});`


至此,我们已经完成所有的初始化工作。接下来就可以针对我们的需求进行开发了。

单聊功能

由于我们项目使用的IMKit包,所以使用起来很方便。简要介绍下单聊:

单聊是最基本的聊天界面,提供文字、表情、语音片段、图片、VoIP 等多种输入内容,解决 App 内用户的沟通瓶颈。会话关系由融云负责建立并保持,退出聊天界面或者离线后可以收到推送通知。

前提条件:

RongIM.init(this),接口已经执行。

RongIM.connect(….),接口已经执行且 onSuccess() 被回调。

会话 Activity 已经在 AndroidManifest.xml 文件中,配制了对应的 intent-filter,详见配置说明文档。

由于IMKit中融云提供的界面都是基于fragment,所以使用也是简单,我们只需要简单配置下我们的会话列表界面就可以了,比如:

<?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:background="#ffffff"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/relative_title"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@color/shenglvse"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_return"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:contentDescription="@null"
android:src="@drawable/back_icon" />

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center_vertical"
android:text="会话界面"
android:textColor="@color/white"
android:textSize="17sp" />
</RelativeLayout>
<fragment
android:id="@+id/conversaction"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="io.rong.imkit.fragment.ConversationFragment"
/>
</LinearLayout>


主要就是一定要包含:

<fragment
android:id="@+id/conversaction"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="io.rong.imkit.fragment.ConversationFragment"
/>


效果图如下:



布局搞好了,我们要创建一个ConversationActivity来进行显示。

public class ConversationActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.conversation);
ImageView iv_return = (ImageView) findViewById(R.id.iv_return);
iv_return.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
ConversationActivity.this.finish();
}
});
}
}


Activity创建好自然要在Manifest中进行声明

<activity
android:name="com.dsw.infor.activity.communication.ConversationActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="com.dsw.infor"
android:pathPrefix="/conversation/"
android:scheme="rong" />
</intent-filter>
</activity>


这些都配置好了,我们就可以指定用户在app中的唯一标识,比如id,来进入与该id用户进行单聊的界面。代码:

/**
* 启动单聊界面。
*
* @param context      应用上下文。
* @param targetUserId 要与之聊天的用户 Id。
* @param title        聊天的标题,如果传入空值,则默认显示与之聊天的用户名称。
*/
RongIM.getInstance().startPrivateChat(getActivity(), "9527", "标题");


建立讨论组

前提条件同单聊,主要介绍几个方法。

(1)、打开讨论组聊天窗口:

/**
* 启动讨论组聊天界面。
*
* @param context            应用上下文。
* @param targetDiscussionId 要聊天的讨论组 Id。
* @param title              聊天的标题,如果传入空值,则默认显示讨论组名称。
*/
RongIM.getInstance().startDiscussionChat(getActivity(), "9527", "标题");


(2)、创建讨论组会话并进入会话界面:

ArrayList<String> userIds = new ArrayList<String>();
userIds.add("101");//增加 userId。
userIds.add("102");//增加 userId。
userIds.add("103");//增加 userId

/**
* 创建讨论组会话并进入会话界面。
*
* @param context       应用上下文。
* @param targetUserIds 要与之聊天的讨论组用户 Id 列表。
* @param title         聊天的标题,如果传入空值,则默认显示与之聊天的用户名称。
*/
RongIM.getInstance().createDiscussionChat(getActivity(), userIds, "讨论组名称");


所以,我们可以根据我们通讯录中选择的用户,建立一个用户id的集合,然后就可以创建讨论组。

会话列表

会话列表的使用步骤与单聊基本相同,首先是配置布局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:background="#ffffff"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/relative_title"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@color/shenglvse"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_return"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:contentDescription="@null"
android:src="@drawable/back_icon_pressed" />

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center_vertical"
android:text="会话列表"
android:textColor="@color/white"
android:textSize="17sp" />
</RelativeLayout>
<fragment
android:id="@+id/conversaction_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="io.rong.imkit.fragment.ConversationListFragment"
/>

</LinearLayout>


然后创建ConversationListActivity来进行会话列表的展现。

public class ConversationListActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.conversation_list);
ImageView iv_return = (ImageView) findViewById(R.id.iv_return);
iv_return.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
ConversationListActivity.this.finish();
}
});
}
}


创建好之后,就是在Manifest文件中声明。

<activity
android:name="com.dsw.infor.activity.communication.ConversationListActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="com.dsw.infor"
android:pathPrefix="/conversationlist"
android:scheme="rong" />
</intent-filter>
</activity>


创建好后,我们点击按钮进入会话列表页面。

RongIM.getInstance().startConversationList(_this);


至此,所有的基本功能点在IMKit包中都能很快实现。接下来,我们说说我遇到的几个问题吧!

一、会话列表中展示单聊会话框的名称不对,只展示id

这种问题困扰我很久的,后来通过提工单才知道要实现UserInfoProvider接口,然后重写public UserInfo getUserInfo(String userId)方法。原因:用户之间的好友关系是我们来维护,所以在打开某个会话时候,我们需要告诉系统对应id的用户名称。



具体解决方法:

(1)、建立Friend实体,

public class Friend {

private String userId;

private String userName;

private String portraitUri;

public Friend(String userId,String userName,String portraitUri){
this.userId = userId;
this.userName = userName;
this.portraitUri = portraitUri;
}

public String getUserId() {
return userId;
}

public void setUserId(String userId) {
this.userId = userId;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPortraitUri() {
return portraitUri;
}

public void setPortraitUri(String portraitUri) {
this.portraitUri = portraitUri;
}
}


(2)根据我们的用户关系表建立一个用户的个人信息集合。

friendList = new ArrayList<Friend>();
for(int i=0;i<contactList.size();i++){
contact = contactList.get(i);
friend = new Friend(contact.getUser_Id()+"", contact.getContacts_Name(), "");
friendList.add(friend);
}


(3)重写public UserInfo getUserInfo(String userId),根据id返回用户信息。

@Override
public UserInfo getUserInfo(String userId) {
for (Friend i : friendList) {
if (i.getUserId().equals(userId)) {
return new UserInfo(i.getUserId(),i.getUserName(),Uri.parse(i.getPortraitUri()));
}
}
return null;
}


通过这样处理,我们的会话列表就会展示用户名称。

二、语音通话使用问题

1、语音通话无法使用,这是我们需要检查我们是否在Manifest文件中注册了相关的语音服务。如果注册了,我们是否将android:host的值修改为我们的包,基本就是这两方面的问题。

<activity
android:name="io.rong.voipkit.activity.CallSideActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="com.dsw.infor"
android:pathPrefix="/VoIPCall"
android:scheme="rong" />
</intent-filter>
</activity>
<activity
android:screenOrientation="portrait"
android:name="io.rong.voipkit.activity.CalledSideActivity"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="com.dsw.infor"
android:pathPrefix="/VoIPAccept"
android:scheme="rong"/>
</intent-filter>
</activity>


2、语音通话,名称显示融云客服,接收方显示张三。这个问题同样是我们用户的信息没有提供给融云,所以它就显示默认的了。解决办法同上面的会话列表显示id不显示名称问题。

三、初始化失败等一些问题

这类问题展现的很多,我也没有截图了,原因就是系统自带的v4包的版本比较低,导致达不到系统要求的v4包的要求,下载个高版本的v4包替换即可。下载地址。或者使用v7包。

四、创建讨论组的id怎么获取

我们上面提供的进入和创建讨论组的方法中,都没有获取讨论组id的信息,通过提工单,可以通过这个方法。

RongIM.getInstance().getRongIMClient().
createDiscussion(reason, list, new CreateDiscussionCallback() {

@Override
public void onSuccess(String discussId) {
RongIM.getInstance().startDiscussionChat(_this, discussId, reason);
Log.v("CreateDiscussion", "CreateDiscussion Success");
}

@Override
public void onError(ErrorCode errorCode) {
Log.v("CreateDiscussion", "CreateDiscussion Error,Code:" + errorCode);
}
});


会话界面底部的工具栏怎么定置,如拍照、定位等

这部分属于用户自己定置的功能,当然我们也可以使用一些融云提供好的服务。我们定制哪些功能,需要我们在Application的onCreate方法中进行执行。通过ExtendProvider定制扩展功能。

if("com.drision.militia_infor".equals(getCurProcessName(getApplicationContext())) ||
"io.rong.push".equals(getCurProcessName(getApplicationContext()))) {
RongIM.init(this);

//定义会话框中的功能选项
ExtendProvider [] ep = {
new ImageInputProvider(RongContext.getInstance()),
new NewCameraInputProviders(RongContext.getInstance()),
// 语音通话
new VoIPInputProvider(RongContext.getInstance()),
//注意图标要放在xhdpi目录下,不然不对齐
new ContactsProvider(RongContext.getInstance())};
RongIM.resetInputExtensionProvider(ConversationType.PRIVATE, ep);
}


我们定制了拍照、语音通话、图片选择、联系人四个工具。其中图片选择、语音通话时系统提供的,那么我们怎么实现我们自定义的。

实现自定义的,需要我们继承InputProvider.ExtendProvider来进行实现,然后定制到工具栏中。

下面我直接提出来源码:

1、拍照功能:

public class NewCameraInputProviders extends InputProvider.ExtendProvider {

HandlerThread mWorkThread;

Handler mUploadHandler;

@SuppressWarnings("unused")
private RongContext mContext;
private File photoFile;

public NewCameraInputProviders(RongContext context) {
super(context);
this.mContext = context;
// 来自融云demo
mWorkThread = new HandlerThread("RongDemo");
mWorkThread.start();
mUploadHandler = new Handler(mWorkThread.getLooper());

}

@Override
public Drawable obtainPluginDrawable(Context arg0) {
return arg0.getResources().getDrawable(R.drawable.rc_ic_camera);
}

@Override
public CharSequence obtainPluginTitle(Context arg0) {
return "拍照";
}

@Override
public void onPluginClick(View arg0) {
// 点击跳转至拍照
photoFile = new File(Environment.getExternalStorageDirectory()
+ "/my_camera/" + UUID.randomUUID() + ".jpg");// 图片储存路径
if (!photoFile.getParentFile().exists()) {
photoFile.getParentFile().mkdirs();
}
Intent intent = new Intent();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Log.e("TAG", "---requestCode-" + requestCode + "---resultCode--" + resultCode);
// 根据选择完毕的图片返回值,直接上传文件
if (requestCode == 1) {// 拍照
String localStrPath = photoFile.getPath();
byte[] compressBitmap = BitmapUtils.compressBitmap(480 * 480,
localStrPath);
if (null != compressBitmap) {
Bitmap bmPhoto = BitmapUtils.Bytes2Bimap(compressBitmap);
if (null != bmPhoto) {
String strTempPhotoPath;
try {
strTempPhotoPath = BitmapUtils.saveFile(bmPhoto,
UUID.randomUUID() + ".jpeg");
if (bmPhoto != null) {
bmPhoto.recycle();
bmPhoto = null;
}
if (null != strTempPhotoPath
&& !"".equals(strTempPhotoPath)) {
localStrPath = strTempPhotoPath;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
localStrPath = "file://" + localStrPath;
Uri pathUri = Uri.parse(localStrPath);
mUploadHandler.post(new MyRunnable(pathUri));
}
}
}

/**
* 用于显示文件的异步线程
*/
class MyRunnable implements Runnable {

Uri mUri;

public MyRunnable(Uri uri) {
mUri = uri;
}

@Override
public void run() {

// 封装image类型的IM消息
final ImageMessage content = ImageMessage.obtain(mUri, mUri);

if (RongIM.getInstance() != null
&& RongIM.getInstance().getRongIMClient() != null)
RongIM.getInstance()
.getRongIMClient()
.sendImageMessage(
getCurrentConversation().getConversationType(),
getCurrentConversation().getTargetId(),
content, null, null,
new RongIMClient.SendImageMessageCallback() {
@Override
public void onAttached(Message message) {

}

@Override
public void onError(Message message,
RongIMClient.ErrorCode errorCode) {

}

@Override
public void onSuccess(Message message) {

}

@Override
public void onProgress(Message message,
int i) {

}
});

}
}

}


2、联系人功能源码:

public class ContactsProvider extends InputProvider.ExtendProvider {

HandlerThread mWorkThread;
Handler mUploadHandler;
private int REQUEST_CONTACT = 20;

public ContactsProvider(RongContext context) {
super(context);
mWorkThread = new HandlerThread("RongDemo");
mWorkThread.start();
mUploadHandler = new Handler(mWorkThread.getLooper());
}

/**
* 设置展示的图标
* @param context
* @return
*/
@Override
public Drawable obtainPluginDrawable(Context context) {
return context.getResources().getDrawable(R.drawable.de_contacts);
}

/**
* 设置图标下的title
* @param context
* @return
*/
@Override
public CharSequence obtainPluginTitle(Context context) {
return "通讯录";
}

/**
* click 事件
* @param view
*/
@Override
public void onPluginClick(View view) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, REQUEST_CONTACT);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

if (resultCode != Activity.RESULT_OK)
return;

if (data.getData() != null && "content".equals(data.getData().getScheme())) {
mUploadHandler.post(new MyRunnable(data.getData()));
}

super.onActivityResult(requestCode, resultCode, data);
}

class MyRunnable implements Runnable {

Uri mUri;

public MyRunnable(Uri uri) {
mUri = uri;
}

@Override
public void run() {
String[] contact = getPhoneContacts(mUri);

String showMessage = contact[0] + "\n" + contact[1];
final TextMessage content = TextMessage.obtain(showMessage);

if (RongIM.getInstance().getRongIMClient() != null)
RongIM.getInstance().getRongIMClient().sendMessage(getCurrentConversation().getConversationType(), getCurrentConversation().getTargetId(), content, null, null, new RongIMClient.SendMessageCallback() {
@Override
public void onError(Integer integer, RongIMClient.ErrorCode errorCode) {
Log.d("ExtendProvider", "onError--" + errorCode);
}

@Override
public void onSuccess(Integer integer) {
Log.d("ExtendProvider", "onSuccess--" + integer);
}
});
}
}

private String[] getPhoneContacts(Uri uri) {

String[] contact = new String[2];
ContentResolver cr = getContext().getContentResolver();
Cursor cursor = cr.query(uri, null, null, null, null);
cursor.moveToFirst();
if (cursor != null) {
cursor.moveToFirst();
int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME);
contact[0] = cursor.getString(nameFieldColumnIndex);

String ContactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + ContactId, null, null);

if (phone != null) {
phone.moveToFirst();
contact[1] = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phone.close();
cursor.close();
}
return contact;
}
}


以上就是关于融云在项目中的使用,融云提供很多功能,希望以后有机会再深入研究吧!

简单demo下载地址

========================================

作者:mr_dsw 欢迎转载,与人分享是进步的源泉!

转载请保留地址:http://blog.csdn.net/mr_dsw
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: