package cn.rongcloud.im.ui.activity; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.FragmentTransaction; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Locale; import cn.rongcloud.im.R; import cn.rongcloud.im.SealAppContext; import cn.rongcloud.im.SealUserInfoManager; import cn.rongcloud.im.db.GroupMember; import cn.rongcloud.im.server.utils.NLog; import cn.rongcloud.im.server.utils.NToast; import cn.rongcloud.im.ui.fragment.ConversationFragmentEx; import cn.rongcloud.im.ui.widget.LoadingDialog; import io.rong.imkit.RongIM; import io.rong.imkit.fragment.UriFragment; import io.rong.imkit.userInfoCache.RongUserInfoManager; import io.rong.imlib.MessageTag; import io.rong.imlib.RongIMClient; import io.rong.imlib.TypingMessage.TypingStatus; import io.rong.imlib.model.Conversation; import io.rong.imlib.model.Discussion; import io.rong.imlib.model.PublicServiceProfile; import io.rong.imlib.model.UserInfo; import io.rong.message.TextMessage; import io.rong.message.VoiceMessage; //CallKit start 1 import io.rong.callkit.RongCallKit; //CallKit end 1 /** * 会话页面 * 1,设置 ActionBar title * 2,加载会话页面 * 3,push 和 通知 判断 */ public class ConversationActivity extends BaseActivity implements View.OnClickListener { private String TAG = ConversationActivity.class.getSimpleName(); /** * 对方id */ private String mTargetId; /** * 会话类型 */ private Conversation.ConversationType mConversationType; /** * title */ private String title; /** * 是否在讨论组内,如果不在讨论组内,则进入不到讨论组设置页面 */ private boolean isFromPush = false; private LoadingDialog mDialog; private SharedPreferences sp; private final String TextTypingTitle = "对方正在输入..."; private final String VoiceTypingTitle = "对方正在讲话..."; private Handler mHandler; public static final int SET_TEXT_TYPING_TITLE = 1; public static final int SET_VOICE_TYPING_TITLE = 2; public static final int SET_TARGET_ID_TITLE = 0; private Button mRightButton; @Override @TargetApi(23) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.conversation); sp = getSharedPreferences("config", MODE_PRIVATE); mDialog = new LoadingDialog(this); mRightButton = getHeadRightButton(); Intent intent = getIntent(); if (intent == null || intent.getData() == null) return; mTargetId = intent.getData().getQueryParameter("targetId"); //10000 为 Demo Server 加好友的 id,若 targetId 为 10000,则为加好友消息,默认跳转到 NewFriendListActivity // Demo 逻辑 if (mTargetId != null && mTargetId.equals("10000")) { startActivity(new Intent(ConversationActivity.this, NewFriendListActivity.class)); return; } mConversationType = Conversation.ConversationType.valueOf(intent.getData() .getLastPathSegment().toUpperCase(Locale.US)); title = intent.getData().getQueryParameter("title"); setActionBarTitle(mConversationType, mTargetId); if (mConversationType.equals(Conversation.ConversationType.GROUP)) { mRightButton.setBackground(getResources().getDrawable(R.drawable.icon2_menu)); } else if (mConversationType.equals(Conversation.ConversationType.PRIVATE) | mConversationType.equals(Conversation.ConversationType.PUBLIC_SERVICE) | mConversationType.equals(Conversation.ConversationType.DISCUSSION)) { mRightButton.setBackground(getResources().getDrawable(R.drawable.icon1_menu)); } else { mRightButton.setVisibility(View.GONE); mRightButton.setClickable(false); } mRightButton.setOnClickListener(this); isPushMessage(intent); mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { switch (msg.what) { case SET_TEXT_TYPING_TITLE: setTitle(TextTypingTitle); break; case SET_VOICE_TYPING_TITLE: setTitle(VoiceTypingTitle); break; case SET_TARGET_ID_TITLE: setActionBarTitle(mConversationType, mTargetId); break; default: break; } return true; } }); 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)) { int count = typingStatusSet.size(); //count表示当前会话中正在输入的用户数量,目前只支持单聊,所以判断大于0就可以给予显示了 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_TARGET_ID_TITLE); } } } }); SealAppContext.getInstance().pushActivity(this); //CallKit start 2 RongCallKit.setGroupMemberProvider(new RongCallKit.GroupMembersProvider() { @Override public ArrayList<String> getMemberList(String groupId, final RongCallKit.OnGroupMembersResult result) { getGroupMembersForCall(); mCallMemberResult = result; return null; } }); //CallKit end 2 } /** * 判断是否是 Push 消息,判断是否需要做 connect 操作 */ private void isPushMessage(Intent intent) { if (intent == null || intent.getData() == null) return; //push if (intent.getData().getScheme().equals("rong") && intent.getData().getQueryParameter("isFromPush") != null) { //通过intent.getData().getQueryParameter("push") 为true,判断是否是push消息 if (intent.getData().getQueryParameter("isFromPush").equals("true")) { //只有收到系统消息和不落地 push 消息的时候,pushId 不为 null。而且这两种消息只能通过 server 来发送,客户端发送不了。 //RongIM.getInstance().getRongIMClient().recordNotificationEvent(id); if (mDialog != null && !mDialog.isShowing()) { mDialog.show(); } isFromPush = true; enterActivity(); } else if (RongIM.getInstance().getCurrentConnectionStatus().equals(RongIMClient.ConnectionStatusListener.ConnectionStatus.DISCONNECTED)) { if (mDialog != null && !mDialog.isShowing()) { mDialog.show(); } if (intent.getData().getPath().contains("conversation/system")) { Intent intent1 = new Intent(mContext, MainActivity.class); intent1.putExtra("systemconversation", true); startActivity(intent1); SealAppContext.getInstance().popAllActivity(); return; } enterActivity(); } else { if (intent.getData().getPath().contains("conversation/system")) { Intent intent1 = new Intent(mContext, MainActivity.class); intent1.putExtra("systemconversation", true); startActivity(intent1); SealAppContext.getInstance().popAllActivity(); return; } enterFragment(mConversationType, mTargetId); } } else { if (RongIM.getInstance().getCurrentConnectionStatus().equals(RongIMClient.ConnectionStatusListener.ConnectionStatus.DISCONNECTED)) { if (mDialog != null && !mDialog.isShowing()) { mDialog.show(); } new Handler().postDelayed(new Runnable() { @Override public void run() { enterActivity(); } }, 300); } else { enterFragment(mConversationType, mTargetId); } } } /** * 收到 push 消息后,选择进入哪个 Activity * 如果程序缓存未被清理,进入 MainActivity * 程序缓存被清理,进入 LoginActivity,重新获取token * <p> * 作用:由于在 manifest 中 intent-filter 是配置在 ConversationActivity 下面,所以收到消息后点击notifacition 会跳转到 DemoActivity。 * 以跳到 MainActivity 为例: * 在 ConversationActivity 收到消息后,选择进入 MainActivity,这样就把 MainActivity 激活了,当你读完收到的消息点击 返回键 时,程序会退到 * MainActivity 页面,而不是直接退回到 桌面。 */ private void enterActivity() { String token = sp.getString("loginToken", ""); if (token.equals("default")) { NLog.e("ConversationActivity push", "push2"); startActivity(new Intent(ConversationActivity.this, LoginActivity.class)); SealAppContext.getInstance().popAllActivity(); } else { NLog.e("ConversationActivity push", "push3"); reconnect(token); } } private void reconnect(String token) { RongIM.connect(token, new RongIMClient.ConnectCallback() { @Override public void onTokenIncorrect() { Log.e(TAG, "---onTokenIncorrect--"); } @Override public void onSuccess(String s) { Log.i(TAG, "---onSuccess--" + s); NLog.e("ConversationActivity push", "push4"); if (mDialog != null) mDialog.dismiss(); enterFragment(mConversationType, mTargetId); } @Override public void onError(RongIMClient.ErrorCode e) { Log.e(TAG, "---onError--" + e); if (mDialog != null) mDialog.dismiss(); enterFragment(mConversationType, mTargetId); } }); } private ConversationFragmentEx fragment; /** * 加载会话页面 ConversationFragmentEx 继承自 ConversationFragment * * @param mConversationType 会话类型 * @param mTargetId 会话 Id */ private void enterFragment(Conversation.ConversationType mConversationType, String mTargetId) { fragment = new ConversationFragmentEx(); Uri uri = Uri.parse("rong://" + getApplicationInfo().packageName).buildUpon() .appendPath("conversation").appendPath(mConversationType.getName().toLowerCase()) .appendQueryParameter("targetId", mTargetId).build(); fragment.setUri(uri); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); //xxx 为你要加载的 id transaction.add(R.id.rong_content, fragment); transaction.commitAllowingStateLoss(); } /** * 设置会话页面 Title * * @param conversationType 会话类型 * @param targetId 目标 Id */ private void setActionBarTitle(Conversation.ConversationType conversationType, String targetId) { if (conversationType == null) return; if (conversationType.equals(Conversation.ConversationType.PRIVATE)) { setPrivateActionBar(targetId); } else if (conversationType.equals(Conversation.ConversationType.GROUP)) { setGroupActionBar(targetId); } else if (conversationType.equals(Conversation.ConversationType.DISCUSSION)) { setDiscussionActionBar(targetId); } else if (conversationType.equals(Conversation.ConversationType.CHATROOM)) { setTitle(title); } else if (conversationType.equals(Conversation.ConversationType.SYSTEM)) { setTitle(R.string.de_actionbar_system); } else if (conversationType.equals(Conversation.ConversationType.APP_PUBLIC_SERVICE)) { setAppPublicServiceActionBar(targetId); } else if (conversationType.equals(Conversation.ConversationType.PUBLIC_SERVICE)) { setPublicServiceActionBar(targetId); } else if (conversationType.equals(Conversation.ConversationType.CUSTOMER_SERVICE)) { setTitle(R.string.main_customer); } else { setTitle(R.string.de_actionbar_sub_defult); } } /** * 设置群聊界面 ActionBar * * @param targetId 会话 Id */ private void setGroupActionBar(String targetId) { if (!TextUtils.isEmpty(title)) { setTitle(title); } else { setTitle(targetId); } } /** * 设置应用公众服务界面 ActionBar */ private void setAppPublicServiceActionBar(String targetId) { if (targetId == null) return; RongIM.getInstance().getPublicServiceProfile(Conversation.PublicServiceType.APP_PUBLIC_SERVICE , targetId, new RongIMClient.ResultCallback<PublicServiceProfile>() { @Override public void onSuccess(PublicServiceProfile publicServiceProfile) { setTitle(publicServiceProfile.getName()); } @Override public void onError(RongIMClient.ErrorCode errorCode) { } }); } /** * 设置公共服务号 ActionBar */ private void setPublicServiceActionBar(String targetId) { if (targetId == null) return; RongIM.getInstance().getPublicServiceProfile(Conversation.PublicServiceType.PUBLIC_SERVICE , targetId, new RongIMClient.ResultCallback<PublicServiceProfile>() { @Override public void onSuccess(PublicServiceProfile publicServiceProfile) { setTitle(publicServiceProfile.getName()); } @Override public void onError(RongIMClient.ErrorCode errorCode) { } }); } /** * 设置讨论组界面 ActionBar */ private void setDiscussionActionBar(String targetId) { if (targetId != null) { RongIM.getInstance().getDiscussion(targetId , new RongIMClient.ResultCallback<Discussion>() { @Override public void onSuccess(Discussion discussion) { setTitle(discussion.getName()); } @Override public void onError(RongIMClient.ErrorCode e) { if (e.equals(RongIMClient.ErrorCode.NOT_IN_DISCUSSION)) { setTitle("不在讨论组中"); supportInvalidateOptionsMenu(); } } }); } else { setTitle("讨论组"); } } /** * 设置私聊界面 ActionBar */ private void setPrivateActionBar(String targetId) { if (!TextUtils.isEmpty(title)) { if (title.equals("null")) { if (!TextUtils.isEmpty(targetId)) { UserInfo userInfo = RongUserInfoManager.getInstance().getUserInfo(targetId); if (userInfo != null) { setTitle(userInfo.getName()); } } } else { setTitle(title); } } else { setTitle(targetId); } } /** * 根据 targetid 和 ConversationType 进入到设置页面 */ private void enterSettingActivity() { if (mConversationType == Conversation.ConversationType.PUBLIC_SERVICE || mConversationType == Conversation.ConversationType.APP_PUBLIC_SERVICE) { RongIM.getInstance().startPublicServiceProfile(this, mConversationType, mTargetId); } else { UriFragment fragment = (UriFragment) getSupportFragmentManager().getFragments().get(0); //得到讨论组的 targetId mTargetId = fragment.getUri().getQueryParameter("targetId"); if (TextUtils.isEmpty(mTargetId)) { NToast.shortToast(mContext, "讨论组尚未创建成功"); } Intent intent = null; if (mConversationType == Conversation.ConversationType.GROUP) { intent = new Intent(this, GroupDetailActivity.class); intent.putExtra("conversationType", Conversation.ConversationType.GROUP); } else if (mConversationType == Conversation.ConversationType.PRIVATE) { intent = new Intent(this, PrivateChatDetailActivity.class); intent.putExtra("conversationType", Conversation.ConversationType.PRIVATE); } else if (mConversationType == Conversation.ConversationType.DISCUSSION) { intent = new Intent(this, DiscussionDetailActivity.class); intent.putExtra("TargetId", mTargetId); startActivityForResult(intent, 166); return; } intent.putExtra("TargetId", mTargetId); if (intent != null) { startActivityForResult(intent, 500); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == 501) { SealAppContext.getInstance().popAllActivity(); } } @Override protected void onDestroy() { //CallKit start 3 RongCallKit.setGroupMemberProvider(null); //CallKit end 3 RongIMClient.setTypingStatusListener(null); SealAppContext.getInstance().popActivity(this); super.onDestroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (KeyEvent.KEYCODE_BACK == event.getKeyCode()) { if (fragment != null && !fragment.onBackPressed()) { if (isFromPush) { isFromPush = false; startActivity(new Intent(this, MainActivity.class)); SealAppContext.getInstance().popAllActivity(); } else { if (fragment.isLocationSharing()) { fragment.showQuitLocationSharingDialog(this); return true; } if (mConversationType.equals(Conversation.ConversationType.CHATROOM) || mConversationType.equals(Conversation.ConversationType.CUSTOMER_SERVICE)) { SealAppContext.getInstance().popActivity(this); } else { SealAppContext.getInstance().popActivity(this); } } } } return false; } private void hintKbTwo() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive() && getCurrentFocus() != null) { if (getCurrentFocus().getWindowToken() != null) { imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } } //CallKit start 4 private RongCallKit.OnGroupMembersResult mCallMemberResult; private void getGroupMembersForCall() { SealUserInfoManager.getInstance().getGroupMembers(mTargetId, new SealUserInfoManager.ResultCallback<List<GroupMember>>() { @Override public void onSuccess(List<GroupMember> groupMembers) { ArrayList<String> userIds = new ArrayList<>(); if (groupMembers != null) { for (GroupMember groupMember : groupMembers) { if (groupMember != null) { userIds.add(groupMember.getUserId()); } } } mCallMemberResult.onGotMemberList(userIds); } @Override public void onError(String errString) { mCallMemberResult.onGotMemberList(null); } }); } //CallKit end 4 @Override public void onClick(View v) { enterSettingActivity(); } @Override public void onHeadLeftButtonClick(View v) { if (fragment != null && !fragment.onBackPressed()) { if (fragment.isLocationSharing()) { fragment.showQuitLocationSharingDialog(this); return; } hintKbTwo(); if (isFromPush) { isFromPush = false; startActivity(new Intent(this, MainActivity.class)); } if (mConversationType.equals(Conversation.ConversationType.CHATROOM) || mConversationType.equals(Conversation.ConversationType.CUSTOMER_SERVICE)) { SealAppContext.getInstance().popActivity(this); } else { SealAppContext.getInstance().popAllActivity(); } } } }