|
8 年之前 | |
---|---|---|
.. | ||
aars | 8 年之前 | |
assets | 8 年之前 | |
libs | 8 年之前 | |
res | 8 年之前 | |
src | 8 年之前 | |
AndroidManifest.xml | 8 年之前 | |
README.md | 8 年之前 | |
app.iml | 8 年之前 | |
build.gradle | 8 年之前 | |
debug.keystore | 8 年之前 | |
proguard.cfg | 8 年之前 | |
project.properties | 8 年之前 | |
release.keystore | 8 年之前 |
网易云通信 Demo 工程基于网易云通信 SDK,演示了 SDK 聊天、群组、白板、实时音视频等功能接口的使用方法。Demo 工程依赖于 UIKit 工程,UIKit 实现了基本的消息收发,群组服务以及通讯录等功能,包含有完整的界面显示。开发者可以直接调用UIKit 中的接口,来进行功能开发,加快开发速度。用户可参照该 Demo,将网易云通信 SDK 接入自己的 APP。
用户可在下载页面进行下载 Demo 源码工程。
总体环境需求:
如果你使用的 IDE 是 Android Studio,可直接在 IDE 中打开 Demo 工程,然后将工程目录下 gradle.properties 文件按照注释修改,就可以直接编译运行。
如果你使用的 IDE 是 Eclipse,可直接在 IDE 中打开工程,做如下修改后,即可编译运行。
由于 Demo 依赖于 UIKit 进行开发。分为 Demo 工程和 UIKit 工程。分别介绍这两个工程的源码结构。
网易云通信 Demo 实现了一个 IM 软件的所有基础功能,开发者可直接以 Demo 为基础开发自己的 IM 软件,也可以稍作修改,用于前期流程验证,也可以作为 SDK 开发的参考和指南。
在 AVChatActivity
的 oncreate 中,进行管理器的初始化工作
avChatUI = new AVChatUI(this, root, this);
if (!avChatUI.initiation()) {
this.finish();
return;
}
public boolean initiation() {
AVChatProfile.getInstance().setAVChatting(true);
avChatAudio = new AVChatAudio(root.findViewById(R.id.avchat_audio_layout), this, this);
avChatVideo = new AVChatVideo(context, root.findViewById(R.id.avchat_video_layout), this, this);
avChatSurface = new AVChatSurface(context, this, root.findViewById(R.id.avchat_surface_layout));
return true;
}
主流程:
1、传入参数,对方帐号和拨打的类型(AVChatType.AUDIO 或 AVChatType.VIDEO)。
avChatUI.outGoingCalling(receiverId, AVChatType.typeOfValue(state));
2、通知界面刷新,详见界面刷新 一节。
if (callTypeEnum == AVChatType.AUDIO) {
onCallStateChange(CallStateEnum.OUTGOING_AUDIO_CALLING);
} else {
onCallStateChange(CallStateEnum.OUTGOING_VIDEO_CALLING);
}
3、发起通话
/**
* 发起通话
* account 对方帐号
* callTypeEnum 通话类型:语音、视频
* videoParam 发起视频通话时传入,发起音频通话传null
* AVChatCallback 回调函数,返回AVChatInfo
*/
AVChatManager.getInstance().call(account, callTypeEnum, videoParam, new AVChatCallback<AVChatData>() {
@Override
public void onSuccess(AVChatData data) {
...
}
@Override
public void onFailed(int code) {
...
}
@Override
public void onException(Throwable exception) {
...
}
});
1、传入参数 AVChatData
avChatUI.inComingCalling(avChatData);
2、通知界面刷新,详见界面刷新 一节。
if (callTypeEnum == AVChatType.AUDIO) {
onCallStateChange(CallStateEnum.OUTGOING_AUDIO_CALLING);
} else {
onCallStateChange(CallStateEnum.OUTGOING_VIDEO_CALLING);
}
界面刷新,详细流程如下。 1、调用 onCallStateChange 2、如果界面没有进行过初始化,则进行界面初始化 findViews,并为各个按钮添加响应事件。 3、根据 CallStateEnum 判断界面布局设置和显隐性。
// 有来电,界面状态更新
onCallStateChange(CallStateEnum.INCOMING_AUDIO_CALLING);
// 判断来电类型,是音频或视频
if(CallStateEnum.isAudioMode(state))
findViews();
// 设置信息显示和界面布局
switch (state){
...
case INCOMING_AUDIO_CALLING://免费通话请求
setSwitchVideo(false);
showProfile();//对方的详细信息
showNotify(R.string.avchat_audio_call_request);
setMuteSpeakerHangupControl(false);
setRefuseReceive(true);
receiveTV.setText(R.string.avchat_pickup);
break;
...
}
AVChatAudio 和 AVChatVideo 中包含了挂断,拒绝,接受,禁音,开启扬声器,音视频切换和摄像头切换的操作。 按钮的点击响应事件,通过 AVChatUIListener 统一交给 AVChatUI 进行管理。示例如下:
// 初始化挂断按钮
hangup = mute_speaker_hangup.findViewById(R.id.avchat_audio_hangup);
hangup.setOnClickListener(this);
// 按钮响应事件处理
public void onClick(View v) {
switch (v.getId()) {
case R.id.avchat_audio_hangup:
listener.onHangUp();
break;
...
}
}
// 在AVChatUI的AVChatUIListener实现中,实现挂断或取消接口。
public void onHangUp() {
if (isCallEstablish.get()) {
hangUp(AVChatExitCode.HANGUP);
} else {
hangUp(AVChatExitCode.CANCEL);
}
}
问题:群通知新增的通知消息类型,可能会造成老版本崩溃。 原因:TeamNotificationHelper#buildUpdateTeamNotification 的 a.getUpdatedFields() 的 size 为0,造成 sb 的 length为0,会抛出 StringIndexOutOfBoundsException 错误。 解决方案:判断 sb 的length,参考demo。
网易云通信 demo 提供 Android 6.0 权限管理示例。相关方法的实现,在 uikit 的 permission 包中。
在需要相关权限的地方,发起申请并等待用户操作后的返回结果。具体实现方法:
private void requestBasicPermission() {
MPermission.with(MainActivity.this)
.addRequestCode(BASIC_PERMISSION_REQUEST_CODE)
.permissions(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
// ……
)
.request();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
MPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@OnMPermissionGranted(BASIC_PERMISSION_REQUEST_CODE)
public void onBasicPermissionSuccess(){
Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
}
@OnMPermissionDenied(BASIC_PERMISSION_REQUEST_CODE)
public void onBasicPermissionFailed(){
Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
}