浏览代码

修改腾讯IM直播部分问题

Pq 1 年之前
父节点
当前提交
09d5417fbc
共有 91 个文件被更改,包括 6568 次插入67 次删除
  1. 11 0
      BaseLibrary/src/main/java/com/cooleshow/base/common/AppManager.kt
  2. 1 0
      student/build.gradle
  3. 5 1
      student/src/main/java/com/cooleshow/student/ui/main/TalentStyleFragment.java
  4. 13 0
      tclive/src/main/AndroidManifest.xml
  5. 407 0
      tclive/src/main/java/com/daya/tclive/adapter/TTMessageAdapter.java
  6. 66 0
      tclive/src/main/java/com/daya/tclive/api/StudentAPIService.java
  7. 2 2
      tclive/src/main/java/com/daya/tclive/api/TeacherAPIService.java
  8. 45 0
      tclive/src/main/java/com/daya/tclive/bean/LiveRoomInfoBean.java
  9. 1 0
      tclive/src/main/java/com/daya/tclive/constants/ARouterConstace.java
  10. 12 0
      tclive/src/main/java/com/daya/tclive/constants/UrlConstants.java
  11. 116 0
      tclive/src/main/java/com/daya/tclive/contract/TTLiveRoomContract.java
  12. 61 0
      tclive/src/main/java/com/daya/tclive/helper/LiveRoomAddLikeHelper.java
  13. 53 0
      tclive/src/main/java/com/daya/tclive/helper/LiveRoomAnimatorHelper.java
  14. 3 1
      tclive/src/main/java/com/daya/tclive/manager/MessageManager.java
  15. 11 11
      tclive/src/main/java/com/daya/tclive/manager/TCIMSdkManager.java
  16. 1 1
      tclive/src/main/java/com/daya/tclive/message/BaseTIMMessageContent.java
  17. 49 40
      tclive/src/main/java/com/daya/tclive/presenter/TCLivePresenter.java
  18. 900 0
      tclive/src/main/java/com/daya/tclive/presenter/TTLiveRoomPresenter.java
  19. 4 2
      tclive/src/main/java/com/daya/tclive/ui/LiveApplyMicFragment.java
  20. 2360 0
      tclive/src/main/java/com/daya/tclive/ui/TCStudentLiveRoomActivity.java
  21. 3 5
      tclive/src/main/java/com/daya/tclive/ui/TCTeacherLiveRoomActivity.java
  22. 4 2
      tclive/src/main/java/com/daya/tclive/ui/TTLiveOnMicFragment.java
  23. 322 0
      tclive/src/main/java/com/daya/tclive/ui/floatPop/FloatWindowHelper.java
  24. 95 0
      tclive/src/main/java/com/daya/tclive/ui/floatPop/FloatingWindowService.java
  25. 57 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomCloseMicTipDialog.java
  26. 65 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomClosePageOnMicTipDialog.java
  27. 64 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomExitTipDialog2.java
  28. 51 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomInviteSeatMicTipDialog.java
  29. 145 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomMicManagerDialog.java
  30. 336 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomShopCarDialog.java
  31. 64 0
      tclive/src/main/java/com/daya/tclive/widget/dialog/OpenOverlayPermissionTipDialog.java
  32. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_end_tip.png
  33. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_loading_progress.png
  34. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_1.png
  35. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_2.png
  36. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_3.png
  37. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_4.png
  38. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_5.png
  39. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_6.png
  40. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_7.png
  41. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_8.png
  42. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_room_rest_bg.png
  43. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_voice_off.png
  44. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_live_voice_on.png
  45. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_mic_applying.png
  46. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_mic_conected.png
  47. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_mic_connecting.png
  48. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_mic_unconnect.png
  49. 二进制
      tclive/src/main/res/drawable-xhdpi/icon_video_orientation_convert.png
  50. 二进制
      tclive/src/main/res/drawable-xhdpi/tc_icon_add_like.png
  51. 二进制
      tclive/src/main/res/drawable-xhdpi/tc_icon_close_gray.png
  52. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_end_tip.png
  53. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_1.png
  54. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_2.png
  55. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_3.png
  56. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_4.png
  57. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_5.png
  58. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_6.png
  59. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_7.png
  60. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_8.png
  61. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_room_rest_bg.png
  62. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_voice_off.png
  63. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_live_voice_on.png
  64. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_mic_applying.png
  65. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_mic_conected.png
  66. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_mic_connecting.png
  67. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_mic_unconnect.png
  68. 二进制
      tclive/src/main/res/drawable-xxhdpi/icon_video_orientation_convert.png
  69. 二进制
      tclive/src/main/res/drawable-xxhdpi/tc_icon_add_like.png
  70. 二进制
      tclive/src/main/res/drawable-xxhdpi/tc_icon_close_gray.png
  71. 5 0
      tclive/src/main/res/drawable/shape_gray_14dp.xml
  72. 7 0
      tclive/src/main/res/drawable/shape_gray_14dp_border_white.xml
  73. 6 0
      tclive/src/main/res/drawable/shape_live_room_close_bt_bg.xml
  74. 5 0
      tclive/src/main/res/drawable/shape_live_room_close_cancel_bt_bg.xml
  75. 9 0
      tclive/src/main/res/drawable/shape_live_room_shop_car_top.xml
  76. 10 0
      tclive/src/main/res/drawable/shape_live_video_progress2.xml
  77. 430 0
      tclive/src/main/res/layout/ac_tt_liveroom_layout.xml
  78. 77 0
      tclive/src/main/res/layout/dialog_live_room_close_mic_layout.xml
  79. 77 0
      tclive/src/main/res/layout/dialog_live_room_close_page_layout.xml
  80. 80 0
      tclive/src/main/res/layout/dialog_live_room_exit_tip_layout2.xml
  81. 75 0
      tclive/src/main/res/layout/dialog_live_room_invite_mic_layout.xml
  82. 155 0
      tclive/src/main/res/layout/dialog_live_room_mic_manager_layout.xml
  83. 38 0
      tclive/src/main/res/layout/dialog_live_room_shop_car_layout.xml
  84. 80 0
      tclive/src/main/res/layout/tc_dialog_open_overlay_permission_tip_layout.xml
  85. 37 0
      tclive/src/main/res/layout/tc_item_live_room_camera_status_layout.xml
  86. 99 0
      tclive/src/main/res/layout/tc_item_live_room_status_layout.xml
  87. 27 0
      tclive/src/main/res/layout/tc_view_live_float_window_layout.xml
  88. 1 1
      tclive/src/main/res/layout/view_start_tc_live_layout.xml
  89. 0 0
      tclive/src/main/res/raw/tc_live_shop_car_anim.json
  90. 1 0
      tclive/src/main/res/values/colors.xml
  91. 22 1
      tclive/src/main/res/values/strings.xml

+ 11 - 0
BaseLibrary/src/main/java/com/cooleshow/base/common/AppManager.kt

@@ -57,4 +57,15 @@ class AppManager private constructor(){
         activityManager.killBackgroundProcesses(context.packageName)
         System.exit(0)
     }
+
+    /**
+     * 结束当前Activity(堆栈中最后一个压入的)
+     */
+    fun getTopActivity(): Activity? {
+        var activity: Activity? = null
+        if (activityStack!= null && !activityStack.isEmpty()) {
+            activity = activityStack.lastElement()
+        }
+        return activity
+    }
 }

+ 1 - 0
student/build.gradle

@@ -120,6 +120,7 @@ dependencies {
     implementation project(path: ':musictuner')
     implementation project(path: ':ffmpegCmd')
     implementation project(path: ':chatModule')
+    implementation project(path: ':tclive')
     implementation "com.alibaba:arouter-api:$rootProject.ext.android.arouter_api_version"
     kapt "com.alibaba:arouter-compiler:$rootProject.ext.android.arouter_api_version"
 

+ 5 - 1
student/src/main/java/com/cooleshow/student/ui/main/TalentStyleFragment.java

@@ -17,6 +17,7 @@ import com.cooleshow.student.adapter.HomeTalentStyleAdapter;
 import com.cooleshow.student.bean.HomeStyleBean;
 import com.cooleshow.student.databinding.FragmentHomeTalentLayoutBinding;
 import com.cooleshow.student.ui.live.LiveRoomActivity;
+import com.daya.tclive.constants.ARouterConstace;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -60,7 +61,10 @@ public class TalentStyleFragment extends BaseFragment<FragmentHomeTalentLayoutBi
                 if (position < mTalentStyleAdapter.getData().size()) {
                     HomeStyleBean.RowsBean item = mTalentStyleAdapter.getData().get(position);
                     if (TextUtils.equals(item.liveStatus, Constants.ON_LIVING_TAG)) {
-                        LiveRoomActivity.startLiveRoomActivity(getContext(), item.roomUid);
+                        ARouter.getInstance().build(ARouterConstace.ACTIVITY_TT_LIVE_ROOM)
+                                .withString("roomid_key",item.roomUid)
+                                .navigation();
+//                        LiveRoomActivity.startLiveRoomActivity(getContext(), item.roomUid);
                     } else {
                         ARouter.getInstance()
                                 .build(RouterPath.WebCenter.ACTIVITY_HTML)

+ 13 - 0
tclive/src/main/AndroidManifest.xml

@@ -9,6 +9,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-feature android:name="android.hardware.camera.autofocus" />
+    <uses-permission android:name="android.permission.REORDER_TASKS" />
 
     <application >
         <activity
@@ -17,6 +18,18 @@
             android:launchMode="singleTask"
             android:screenOrientation="portrait"
             android:windowSoftInputMode="adjustNothing" />
+
+        <activity
+            android:name=".ui.TCStudentLiveRoomActivity"
+            android:configChanges="orientation|screenSize|keyboardHidden"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustPan">
+            <intent-filter>
+                <action android:name="com.daya.studaya_android.ui.live.tt.TTLiveRoomActivity" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
     </application>
 
 </manifest>

+ 407 - 0
tclive/src/main/java/com/daya/tclive/adapter/TTMessageAdapter.java

@@ -0,0 +1,407 @@
+package com.daya.tclive.adapter;
+
+import android.content.Context;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.widgets.DensityUtil;
+import com.cooleshow.usercenter.helper.UserHelper;
+import com.daya.tclive.R;
+import com.daya.tclive.bean.SendUserInfo;
+import com.daya.tclive.bean.TTMessage;
+import com.daya.tclive.constants.LiveRoomMsgConstants;
+import com.daya.tclive.constants.MessageConstants;
+import com.daya.tclive.message.BaseTIMMessageContent;
+import com.daya.tclive.message.TCAddLikeMessage;
+import com.daya.tclive.message.TCChatModeControlMessage;
+import com.daya.tclive.message.TCChatRoomLocalMessage;
+import com.daya.tclive.message.TCSeatModerCtrlMessage;
+import com.daya.tclive.message.TCTextMessage;
+import com.daya.tclive.message.TCUserEnterMessage;
+import com.daya.tclive.message.TCUserSeatApplyMessage;
+import com.daya.tclive.message.TCUserSeatResponseMessage;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2022/3/31.
+ */
+public class TTMessageAdapter extends RecyclerView.Adapter {
+    private Context context;
+    private String roomAuthorId = "";
+    private ArrayList<TTMessage> mMessageList;
+    public static final int MESSAGE_TYPE_TEXT = -1;//文本消息
+    public static final int MESSAGE_TYPE_JOIN_ROOM = -2;//加入直播间
+    public static final int MESSAGE_TYPE_LOCAL_MSG = -3;//本地消息
+    public static final int MESSAGE_TYPE_ADD_LIKE_MSG = -4;//点赞消息
+    public static final int MESSAGE_TYPE_SEAT_CTRL_MSG = -5;//连麦控制消息
+    public static final int MESSAGE_TYPE_CHAT_CTRL_MSG = -6;//聊天控制消息
+    public static final int MESSAGE_TYPE_SEAT_APPLY_MSG = -7;//观众连麦申请
+    public static final int MESSAGE_TYPE_SEAT_RESPONSE_MSG = -8;//连麦响应消息
+    public static final int MESSAGE_TYPE_ON_SNAP_UP_MSG = -9;//xxx正在抢购
+    public static final String[] MSG_TAGS = new String[]{MessageConstants.TAG_TXT, MessageConstants.TAG_SEAT_MODE_CONTROL, MessageConstants.TAG_CHAT_MODE_CONTROL,
+            MessageConstants.TAG_USER_SEAT_APPLY, MessageConstants.TAG_USER_SEAT_RESPONSE, MessageConstants.TAG_LOCAL_TEXT};
+    public List<String> msgTags;
+
+    public TTMessageAdapter(Context context) {
+        this.context = context;
+        mMessageList = new ArrayList();
+        msgTags = Arrays.asList(MSG_TAGS);
+
+    }
+
+
+    public int getMessageSize() {
+        return mMessageList == null ? 0 : mMessageList.size();
+    }
+
+    public void addMessage(TTMessage message) {
+        if (message == null) {
+            return;
+        }
+        if (TextUtils.isEmpty(message.getObjectName())) {
+            return;
+        }
+        if (!msgTags.contains(message.getObjectName())) {
+            return;
+        }
+        if (message.getContent() instanceof TCUserSeatResponseMessage) {
+            TCUserSeatResponseMessage responseMessage = (TCUserSeatResponseMessage) message.getContent();
+            if (!TextUtils.equals(responseMessage.getAudienceId(), UserHelper.getUserId())) {
+                return;
+            }
+        }
+        if (message.getContent() instanceof TCUserSeatApplyMessage) {
+            TCUserSeatApplyMessage applyMessage = (TCUserSeatApplyMessage) message.getContent();
+            if (!TextUtils.equals(applyMessage.getAudienceId(), UserHelper.getUserId())) {
+                return;
+            }
+        }
+        mMessageList.add(message);
+        notifyDataSetChanged();
+    }
+
+    public void setRoomAuthorId(String roomAuthorId) {
+        this.roomAuthorId = roomAuthorId;
+    }
+
+    @NonNull
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        switch (viewType) {
+            case MESSAGE_TYPE_TEXT:
+            case MESSAGE_TYPE_LOCAL_MSG:
+                View view = LayoutInflater.from(context).inflate(R.layout.item_live_room_message_text, parent, false);
+                return new TextMessageHolder(view);
+            case MESSAGE_TYPE_ON_SNAP_UP_MSG:
+            case MESSAGE_TYPE_ADD_LIKE_MSG:
+            case MESSAGE_TYPE_JOIN_ROOM:
+                View joinView = LayoutInflater.from(context).inflate(R.layout.item_live_room_join_message_text, parent, false);
+                return new JoinRoomMessageHolder(joinView);
+            case MESSAGE_TYPE_SEAT_APPLY_MSG:
+            case MESSAGE_TYPE_SEAT_RESPONSE_MSG:
+            case MESSAGE_TYPE_CHAT_CTRL_MSG:
+            case MESSAGE_TYPE_SEAT_CTRL_MSG:
+                View modechangeView = LayoutInflater.from(context).inflate(R.layout.item_live_room_message_mode_change, parent, false);
+                return new ModeChangeMessageHolder(modechangeView);
+        }
+        return null;
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+        TTMessage message = mMessageList.get(position);
+        BaseTIMMessageContent baseContent = message.getContent();
+        if (baseContent == null) {
+            return;
+        }
+        String nickNameShow = "用户" + message != null ? message.getSenderUserId() : "";
+        switch (getItemViewType(position)) {
+            case MESSAGE_TYPE_LOCAL_MSG:
+                TextMessageHolder localMsgHolder = (TextMessageHolder) holder;
+                TCChatRoomLocalMessage localMsgContent = (TCChatRoomLocalMessage) message.getContent();
+                localMsgHolder.mTvText.setText(localMsgContent.getText());
+                localMsgHolder.mTvText.setTextColor(context.getResources().getColor(R.color.color_00d6c9));
+                break;
+            case MESSAGE_TYPE_TEXT:
+                TextMessageHolder textMessageHolder = (TextMessageHolder) holder;
+                TCTextMessage content = (TCTextMessage) message.getContent();
+                if (content == null) {
+                    break;
+                }
+                Log.i("pq", "textMessage:" + content.toString());
+                //昵称
+                String authorName = getNickName(message);
+                SpannableString spannableString;
+                if (content.getSendUserInfo() != null) {
+                    SendUserInfo userInfo = content.getSendUserInfo();
+                    if (TextUtils.equals(userInfo.getSendUserId(), roomAuthorId)) {
+                        //房间主讲人
+                        spannableString = getRoomAuthorTextStyleSpan(context.getString(R.string.live_msg_text_nickname, authorName), content.getText());
+                    } else {
+                        //其他
+                        spannableString = getNormalTextStyleSpan(context.getString(R.string.live_msg_text_nickname, authorName), content.getText());
+                    }
+                } else {
+                    spannableString = getNormalTextStyleSpan(context.getString(R.string.live_msg_text_nickname, authorName), content.getText());
+                }
+                textMessageHolder.mTvText.setText(spannableString);
+                break;
+
+            case MESSAGE_TYPE_JOIN_ROOM:
+                JoinRoomMessageHolder joinRoomMessageHolder = (JoinRoomMessageHolder) holder;
+                TCUserEnterMessage content1 = (TCUserEnterMessage) message.getContent();
+                String name = getNickName(message);
+                joinRoomMessageHolder.mTvText.setText(getNormalTextStyleSpan(name, "进入直播间"));
+                break;
+            case MESSAGE_TYPE_ADD_LIKE_MSG:
+                JoinRoomMessageHolder addLikeMessageHolder = (JoinRoomMessageHolder) holder;
+                TCAddLikeMessage addLikeContent = (TCAddLikeMessage) message.getContent();
+                String nick = getNickName(message);
+                int counts = addLikeContent.getCounts();
+                addLikeMessageHolder.mTvText.setText(getNormalTextStyleSpan(nick, context.getString(R.string.live_room_add_like_count_text_str, counts)));
+                break;
+            case MESSAGE_TYPE_SEAT_CTRL_MSG:
+                //连麦控制
+                ModeChangeMessageHolder seatModeChangeHolder = (ModeChangeMessageHolder) holder;
+                TCSeatModerCtrlMessage ctrlContent = (TCSeatModerCtrlMessage) message.getContent();
+                String nickName = getNickName(message);
+                boolean isEnableSeat = ctrlContent.isSeatBan();
+                String afterContent = isEnableSeat ? "关闭连麦" : "开启连麦";
+                seatModeChangeHolder.mIvIcon.setVisibility(View.VISIBLE);
+                seatModeChangeHolder.mTvText.setText(getNormalTextStyleSpan(nickName, afterContent));
+                break;
+            case MESSAGE_TYPE_CHAT_CTRL_MSG:
+                //聊天控制
+                ModeChangeMessageHolder chatModeChangeHolder = (ModeChangeMessageHolder) holder;
+                TCChatModeControlMessage chatModeContent = (TCChatModeControlMessage) message.getContent();
+                String nickName2 = getNickName(message);
+                boolean isEnableChat = chatModeContent.isChatBan();
+                String afterContent2 = isEnableChat ? "关闭聊天" : "开启聊天";
+                chatModeChangeHolder.mIvIcon.setVisibility(View.VISIBLE);
+                chatModeChangeHolder.mTvText.setText(getNormalTextStyleSpan(nickName2, afterContent2));
+                break;
+            case MESSAGE_TYPE_SEAT_APPLY_MSG:
+                ModeChangeMessageHolder seatApplyMsgHolder = (ModeChangeMessageHolder) holder;
+                TCUserSeatApplyMessage content2 = (TCUserSeatApplyMessage) message.getContent();
+                int type = content2.getType();
+                if (type == LiveRoomMsgConstants.MIC_ACTION_SEAT_BY_USER
+                        || type == LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_USER) {
+                    seatApplyMsgHolder.mIvIcon.setVisibility(View.GONE);
+                    seatApplyMsgHolder.mTvText.setPadding(DensityUtil.dp2px(context, 10), 0, DensityUtil.dp2px(context, 10), 0);
+                    if (!TextUtils.isEmpty(content2.getAudienceName())) {
+                        nickNameShow = content2.getAudienceName();
+                    }
+                } else {
+                    seatApplyMsgHolder.mIvIcon.setVisibility(View.VISIBLE);
+                    seatApplyMsgHolder.mTvText.setPadding(DensityUtil.dp2px(context, 5), 0, DensityUtil.dp2px(context, 10), 0);
+                    if (!TextUtils.isEmpty(content2.getTeacherName())) {
+                        nickNameShow = content2.getTeacherName();
+                    } else {
+                        nickNameShow = getNickName(message);
+                    }
+                }
+                String contentText = "";
+                if (type == LiveRoomMsgConstants.MIC_ACTION_SEAT_BY_USER) {
+                    //观众发起连麦申请
+                    contentText = "发起了连麦申请";
+                }
+                if (type == LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_USER) {
+                    //观众取消连麦申请
+                    contentText = "取消了连麦申请";
+                }
+
+                if (type == LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_CREATE) {
+                    //主讲人将观众抱下麦
+                    contentText = "断开连麦";
+                }
+
+                if (type == LiveRoomMsgConstants.MIC_ACTION_INVITE_SEAT_BY_CREATE) {
+                    //主讲人发起了连麦邀请
+                    contentText = "发起了连麦邀请";
+                }
+                if (type == LiveRoomMsgConstants.MIC_ACTION_CANCEL_INVITE_SEAT_BY_CREATE) {
+                    //主讲人取消了连麦邀请
+                    contentText = "取消了连麦邀请";
+                }
+                seatApplyMsgHolder.mTvText.setText(getNormalTextStyleSpan(nickNameShow, contentText));
+                break;
+            case MESSAGE_TYPE_SEAT_RESPONSE_MSG:
+                ModeChangeMessageHolder seatResponseMsgHolder = (ModeChangeMessageHolder) holder;
+                TCUserSeatResponseMessage responseContent = (TCUserSeatResponseMessage) message.getContent();
+                int responseType = responseContent.getType();
+                if (responseType == LiveRoomMsgConstants.MIC_RESPONSE_AGREE_BY_USER
+                        || responseType == LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE_BY_USER) {
+                    seatResponseMsgHolder.mIvIcon.setVisibility(View.GONE);
+                    seatResponseMsgHolder.mTvText.setPadding(DensityUtil.dp2px(context, 10), 0, DensityUtil.dp2px(context, 10), 0);
+                    if (!TextUtils.isEmpty(responseContent.getAudienceName())) {
+                        nickNameShow = responseContent.getAudienceName();
+                    }
+                } else {
+                    seatResponseMsgHolder.mIvIcon.setVisibility(View.VISIBLE);
+                    seatResponseMsgHolder.mTvText.setPadding(DensityUtil.dp2px(context, 5), 0, DensityUtil.dp2px(context, 10), 0);
+                    if (!TextUtils.isEmpty(responseContent.getTeacherName())) {
+                        nickNameShow = responseContent.getTeacherName();
+                    }
+                }
+                String responseContentText = "";
+                if (responseType == LiveRoomMsgConstants.MIC_RESPONSE_AGREE) {
+                    //主讲人同意观众上麦申请
+                    responseContentText = "同意了连麦申请";
+                }
+                if (responseType == LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE) {
+                    //主讲人不同意观众上麦申请
+                    responseContentText = "取消了连麦申请";
+                }
+                if (responseType == LiveRoomMsgConstants.MIC_RESPONSE_AGREE_BY_USER) {
+                    //观众同意了连麦邀请
+                    responseContentText = "同意了连麦邀请";
+                }
+                if (responseType == LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE_BY_USER) {
+                    //观众取消了连麦邀请
+                    responseContentText = "取消了连麦邀请";
+                }
+                seatResponseMsgHolder.mTvText.setText(getNormalTextStyleSpan(nickNameShow, responseContentText));
+                break;
+            case MESSAGE_TYPE_ON_SNAP_UP_MSG:
+                JoinRoomMessageHolder onSnapUpHolder = (JoinRoomMessageHolder) holder;
+                String lastName = getNickName(message);
+                onSnapUpHolder.mTvText.setText(getNormalTextStyleSpan(lastName, " 正在抢购"));
+                break;
+
+        }
+    }
+
+
+    private String getNickName(TTMessage message, String defaultName) {
+        if (!TextUtils.isEmpty(defaultName)) {
+            return defaultName;
+        }
+        return getNickName(message);
+    }
+
+    private String getNickName(TTMessage message) {
+        //昵称
+        String name = "用户";
+        BaseTIMMessageContent content = message.getContent();
+        if (content.getSendUserInfo() != null) {
+            name = "用户" + content.getSendUserInfo().getSendUserId();
+            if (!TextUtils.isEmpty(content.getSendUserInfo().getSendUserName())) {
+                name = content.getSendUserInfo().getSendUserName();
+            }
+        }
+        return name;
+    }
+
+    @Override
+    public int getItemCount() {
+        return mMessageList != null ? mMessageList.size() : 0;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        TTMessage message = mMessageList.get(position);
+        String objectName = message.getObjectName();
+        if (TextUtils.equals(objectName, MessageConstants.TAG_TXT)) {
+            //文本消息
+            return MESSAGE_TYPE_TEXT;
+        }
+        if (TextUtils.equals(objectName, MessageConstants.TAG_USER_ENTER)) {
+            //进入房间消息
+            return MESSAGE_TYPE_JOIN_ROOM;
+        }
+
+        if (TextUtils.equals(objectName, MessageConstants.TAG_LOCAL_TEXT)) {
+            //本地消息
+            return MESSAGE_TYPE_LOCAL_MSG;
+        }
+//
+        if (TextUtils.equals(objectName, MessageConstants.TAG_ADD_LIKE)) {
+            //点赞消息
+            return MESSAGE_TYPE_ADD_LIKE_MSG;
+        }
+        if (TextUtils.equals(objectName, MessageConstants.TAG_SEAT_MODE_CONTROL)) {
+            //连麦控制
+            return MESSAGE_TYPE_SEAT_CTRL_MSG;
+        }
+//
+        if (TextUtils.equals(objectName, MessageConstants.TAG_CHAT_MODE_CONTROL)) {
+            //聊天控制
+            return MESSAGE_TYPE_CHAT_CTRL_MSG;
+        }
+//
+        if (TextUtils.equals(objectName, MessageConstants.TAG_USER_SEAT_APPLY)) {
+            //连麦相关
+            return MESSAGE_TYPE_SEAT_APPLY_MSG;
+        }
+        if (TextUtils.equals(objectName, MessageConstants.TAG_USER_SEAT_RESPONSE)) {
+            //连麦响应相关
+            return MESSAGE_TYPE_SEAT_RESPONSE_MSG;
+        }
+        if (TextUtils.equals(objectName, MessageConstants.TAG_USER_SNAPPING_UP)) {
+            //正在抢购
+            return MESSAGE_TYPE_ON_SNAP_UP_MSG;
+        }
+        return super.getItemViewType(position);
+    }
+
+
+    private static class TextMessageHolder extends RecyclerView.ViewHolder {
+
+        private final TextView mTvText;
+
+        public TextMessageHolder(@NonNull View itemView) {
+            super(itemView);
+            mTvText = itemView.findViewById(R.id.tv_text);
+        }
+    }
+
+    private static class ModeChangeMessageHolder extends RecyclerView.ViewHolder {
+
+        private final TextView mTvText;
+        private final ImageView mIvIcon;
+
+        public ModeChangeMessageHolder(@NonNull View itemView) {
+            super(itemView);
+            mTvText = itemView.findViewById(R.id.tv_text);
+            mIvIcon = itemView.findViewById(R.id.iv_icon);
+        }
+    }
+
+    private static class JoinRoomMessageHolder extends RecyclerView.ViewHolder {
+
+        private final TextView mTvText;
+
+        public JoinRoomMessageHolder(@NonNull View itemView) {
+            super(itemView);
+            mTvText = itemView.findViewById(R.id.tv_text);
+        }
+    }
+
+    private SpannableString getNormalTextStyleSpan(String startStr, String contentText) {
+        return UiUtils.diffColorString(startStr
+                , contentText
+                , context.getResources().getColor(R.color.color_00d6c9)
+                , context.getResources().getColor(R.color.white));
+    }
+
+    private SpannableString getRoomAuthorTextStyleSpan(String nickName, String contentText) {
+        return UiUtils.diffColorString(nickName
+                , contentText
+                , context.getResources().getColor(R.color.color_00d6c9)
+                , context.getResources().getColor(R.color.white)
+                , context.getResources().getDrawable(R.drawable.icon_live_msg_room_author));
+    }
+}

+ 66 - 0
tclive/src/main/java/com/daya/tclive/api/StudentAPIService.java

@@ -0,0 +1,66 @@
+package com.daya.tclive.api;
+
+import com.cooleshow.base.data.net.BaseResponse;
+import com.daya.tclive.bean.FriendInfoBean;
+import com.daya.tclive.bean.LiveCourseTimeInfo;
+import com.daya.tclive.bean.LiveRoomInfoBean;
+
+import io.reactivex.rxjava3.core.Observable;
+import okhttp3.RequestBody;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.Header;
+import retrofit2.http.POST;
+import retrofit2.http.Query;
+
+/**
+ * Author by pq, Date on 2023/8/14.
+ */
+public interface StudentAPIService {
+    String student = "api-student/";
+    /**
+     * 查询直播房间信息
+     *
+     * @param roomUid
+     * @return
+     */
+    @GET(student + "imLiveBroadcastRoom/queryRoom")
+    Observable<BaseResponse<LiveRoomInfoBean>> getLiveRoomInfo(@Query("roomUid") String roomUid);
+
+    @GET(student + "teacherCourseSchedule/liveCourseScheduleTime")
+    Observable<BaseResponse<LiveCourseTimeInfo>> getLiveCourseInfo(@Query("courseScheduleId") String courseScheduleId);
+
+    /**
+     * 同步服务端连麦模式 是否连麦 0:允许连麦 1禁止连麦模式
+     *
+     * @return
+     */
+    @GET(student + "imLiveBroadcastRoom/whetherMic")
+    Observable<BaseResponse<Object>> syncMicMode(@Query("roomUid") String roomUid, @Query("whetherMic") int whetherMic);
+
+    /**
+     * 通知加入直播房间成功
+     *
+     * @return
+     */
+    @GET(student + "imLiveBroadcastRoom/joinRoom")
+    Observable<BaseResponse<Object>> notifyJoinRoomAction(@Query("roomUid") String roomUid, @Query("userId") String userId,@Query("microphoneFlag") boolean microphoneFlag);
+
+
+    /**
+     * 通知离开直播房间
+     *
+     * @return
+     */
+    @POST(student+"user/statusImUser")
+    Observable<BaseResponse<Object>> notifyLeaveRoomAction(@Body RequestBody body);
+
+    /**
+     * 查询friend信息
+     *
+     * @return
+     */
+    @GET(student + "imGroup/queryFriendDetail")
+    Observable<BaseResponse<FriendInfoBean>> queryFriendDetail(@Query("userId") String userId);
+
+}

+ 2 - 2
tclive/src/main/java/com/daya/tclive/api/TeacherAPIService.java

@@ -24,7 +24,7 @@ public interface TeacherAPIService {
      * @param roomUid
      * @return
      */
-    @GET(teacher + "liveRoom/speakerCheckRoomInfo")
+    @GET(teacher + "imLiveBroadcastRoom/queryRoom")
     Observable<BaseResponse<LiveRoomInfoBean>> getLiveRoomInfo(@Query("roomUid") String roomUid);
 
     @GET(teacher + "teacherCourseSchedule/liveCourseScheduleTime")
@@ -53,7 +53,7 @@ public interface TeacherAPIService {
      *
      * @return
      */
-    @POST("api-im/user/statusImUser")
+    @POST(teacher+"user/statusImUser")
     Observable<BaseResponse<Object>> notifyLeaveRoomAction(@Body RequestBody body);
 
 

+ 45 - 0
tclive/src/main/java/com/daya/tclive/bean/LiveRoomInfoBean.java

@@ -40,12 +40,16 @@ public class LiveRoomInfoBean implements Parcelable {
     public String roomTitle;
     public String roomUid;
     public String speakerId;
+    public String speakerImUserId;
     public String speakerName;
     public String speakerPic;
     public int subjectId;
     public String type;
     private LiveRoomConfigBean liveRoomConfig;
     private String userSig;
+    private String os;
+
+    public int blacklistFlag;//当前登录人是否是黑名单用户 0否 1是
 
     public LiveRoomConfigBean getLiveRoomConfig() {
         return liveRoomConfig;
@@ -55,6 +59,18 @@ public class LiveRoomInfoBean implements Parcelable {
         this.liveRoomConfig = liveRoomConfig;
     }
 
+    public String getOs() {
+        return os;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+
+    public String getRoomId() {
+        return roomUid;
+    }
     public String getUserSig() {
         return userSig;
     }
@@ -267,4 +283,33 @@ public class LiveRoomInfoBean implements Parcelable {
             return new LiveRoomInfoBean[size];
         }
     };
+
+
+    @Override
+    public String toString() {
+        return "LiveRoomInfoBean{" +
+                "courseGroupId=" + courseGroupId +
+                ", courseId=" + courseId +
+                ", coverPic='" + coverPic + '\'' +
+                ", likeNum=" + likeNum +
+                ", liveEndTime='" + liveEndTime + '\'' +
+                ", liveRemark='" + liveRemark + '\'' +
+                ", liveStartTime='" + liveStartTime + '\'' +
+                ", liveState=" + liveState +
+                ", lookNum=" + lookNum +
+                ", roomState=" + roomState +
+                ", roomTitle='" + roomTitle + '\'' +
+                ", roomUid='" + roomUid + '\'' +
+                ", speakerId='" + speakerId + '\'' +
+                ", speakerImUserId='" + speakerImUserId + '\'' +
+                ", speakerName='" + speakerName + '\'' +
+                ", speakerPic='" + speakerPic + '\'' +
+                ", subjectId=" + subjectId +
+                ", type='" + type + '\'' +
+                ", liveRoomConfig=" + liveRoomConfig +
+                ", userSig='" + userSig + '\'' +
+                ", os='" + os + '\'' +
+                ", blacklistFlag=" + blacklistFlag +
+                '}';
+    }
 }

+ 1 - 0
tclive/src/main/java/com/daya/tclive/constants/ARouterConstace.java

@@ -5,4 +5,5 @@ package com.daya.tclive.constants;
  */
 public class ARouterConstace {
     public static final String ACTIVITY_TC_LIVE_ROOM_TEACHER    = "/live/ui/TCTeacherLiveRoomActivity";
+    public static final String ACTIVITY_TT_LIVE_ROOM    = "/live/ui/TCStudentLiveRoomActivity";
 }

+ 12 - 0
tclive/src/main/java/com/daya/tclive/constants/UrlConstants.java

@@ -0,0 +1,12 @@
+package com.daya.tclive.constants;
+
+/**
+ * Author by pq, Date on 2023/8/15.
+ */
+public class UrlConstants {
+    private static String shopCarWebUrl = "";
+
+    public static final String getShopCarWebUrl() {
+        return shopCarWebUrl;
+    }
+}

+ 116 - 0
tclive/src/main/java/com/daya/tclive/contract/TTLiveRoomContract.java

@@ -0,0 +1,116 @@
+package com.daya.tclive.contract;
+
+import com.cooleshow.base.presenter.view.BaseView;
+import com.daya.tclive.bean.FriendInfoBean;
+import com.daya.tclive.bean.LiveRoomInfoBean;
+import com.daya.tclive.bean.TTMessage;
+import com.daya.tclive.message.TCKickOutUserMessage;
+import com.daya.tclive.message.TCLiveForceKickMessage;
+import com.daya.tclive.message.TCSyncAddLikeMessage;
+import com.daya.tclive.message.TCUserEnterMessage;
+import com.daya.tclive.message.TCUserLogOutUnNormalMessage;
+import com.daya.tclive.message.TCUserSeatApplyMessage;
+import com.daya.tclive.message.TCUserSeatResponseMessage;
+import com.daya.tclive.message.TCUserSnappingUpMessage;
+import com.tencent.trtc.TRTCStatistics;
+
+import java.util.Base64;
+import java.util.Map;
+
+/**
+ * Author by pq, Date on 2022/3/29.
+ */
+public interface TTLiveRoomContract {
+    interface View extends BaseView {
+        void getRoomInfoSuccess(LiveRoomInfoBean roomInfo);
+
+        void getRoomInfoError(Throwable throwable);
+
+        void connectIMError(int errorCode,String errorMsg);
+
+        void loginIMSuccess();
+
+        void joinGroupSuccess();
+
+        void joinGroupError(int code,String des);
+
+        void addMessageContent(TTMessage ttMessage);
+
+        void changeMicControlMode(boolean isEnableMic);
+
+        void switchChatMode(boolean isEnableChat);
+
+        void liveRoomOffline();
+
+        void receiveJoinMessage(TCUserEnterMessage joinRoomMessage);
+
+        void receiveSnapUpMessage(TCUserSnappingUpMessage rcOnSnappingUpMessage);
+
+        void liveGoodsChange(String goodsContent);
+
+        void onAddLikeMessage(TCSyncAddLikeMessage addLikeMessage);
+
+        void syncMemberCount(int count);
+
+        void onUserKickOutMsg(TCKickOutUserMessage userKickOutMessage);
+
+        void seatResponse(TCUserSeatResponseMessage rcUserSeatResponseMessage);
+
+        void onInviteSeatMic(TCUserSeatApplyMessage seatApplyMessage);
+
+        void onUserUnusualLogout(TCUserLogOutUnNormalMessage loginOutUnusualMessage);
+
+        void onLivePause();
+
+        void changeBlackUserStatus(String userId, boolean b);
+
+        void onUnderAllMic();
+
+        void onRefuseAllMicApply();
+
+        void onUserStartPublish();
+
+        void enterLiveRoomSuccess();
+
+        void enterLiveRoomError();
+
+        void onExitRoomSuccess();
+
+        void onStopPublishing();
+
+        void onPublishSuccess();
+
+        void onRemoteUserEnterRoom(String userId);
+
+        void onRemoteUserLeaveRoom(String userId, int reason);
+
+        void onStatistics(TRTCStatistics statistics);
+
+        void getFriendInfoSuccess(FriendInfoBean data);
+
+        void receiveSEIMsg(String userId, byte[] data);
+
+        void onGroupAttributeChanged(String groupID, Map<String, String> groupAttributeMap);
+
+        void getAllGroupAttributesSuccess(Object o);
+
+        void onUserVideoAvailable(String userId, boolean available);
+
+        void onUserSubStreamAvailable(String userId, boolean available);
+
+        void onGroupCounterChanged(String groupID, String key, long newValue);
+
+        void getAllGroupCounterSuccess(Map<String, Long> map);
+
+        void onMicStatusControl(String userId, boolean muteMic);
+
+        void onUserAudioAvailable(String userId, boolean available);
+
+        void onLiveForceKick(TCLiveForceKickMessage messageContent);
+
+    }
+
+    interface Presenter {
+        void getRoomInfo(String roomId);
+    }
+}

+ 61 - 0
tclive/src/main/java/com/daya/tclive/helper/LiveRoomAddLikeHelper.java

@@ -0,0 +1,61 @@
+package com.daya.tclive.helper;
+
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * Author by pq, Date on 2022/4/11.
+ */
+public class LiveRoomAddLikeHelper {
+    private volatile static LiveRoomAddLikeHelper mHelper;
+    // 两次点击按钮之间的点击间隔不能少于200毫秒
+    private static final int MIN_CLICK_DELAY_TIME = 200;
+    private static Handler sHandler = new Handler(Looper.getMainLooper());
+
+    private LiveRoomAddLikeHelper() {
+
+    }
+
+    public static LiveRoomAddLikeHelper getInstance() {
+        if (mHelper == null) {
+            synchronized (LiveRoomAddLikeHelper.class) {
+                if (mHelper == null) {
+                    mHelper = new LiveRoomAddLikeHelper();
+                }
+            }
+        }
+        return mHelper;
+    }
+
+    private static long lastClickTime;
+    private int tempAddLikeCount = 0;
+
+    public void handleClick(OnAddLikeResultCallBack addLikeResultCallBack) {
+        lastClickTime = System.currentTimeMillis();
+        sHandler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                long currentTime = System.currentTimeMillis();
+                if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) {
+                    tempAddLikeCount += 1;
+                    if (addLikeResultCallBack != null) {
+                        addLikeResultCallBack.onResult(tempAddLikeCount);
+                    }
+                    tempAddLikeCount = 0;
+                } else {
+                    tempAddLikeCount += 1;
+                }
+            }
+        }, MIN_CLICK_DELAY_TIME + 10);
+    }
+
+    public interface OnAddLikeResultCallBack {
+        void onResult(int count);
+    }
+
+    public void release() {
+        if (sHandler != null) {
+            sHandler.removeCallbacksAndMessages(null);
+        }
+    }
+}

+ 53 - 0
tclive/src/main/java/com/daya/tclive/helper/LiveRoomAnimatorHelper.java

@@ -6,9 +6,16 @@ import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.LinearInterpolator;
+import android.widget.ImageView;
+
+import com.daya.tclive.R;
 
 import java.util.ArrayList;
+import java.util.Random;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
 
 /**
  * Author by pq, Date on 2022/4/7.
@@ -18,6 +25,12 @@ public class LiveRoomAnimatorHelper {
     private ArrayList<View> animaViews = new ArrayList<>();
     private ArrayList<AnimatorSet> animations = new ArrayList<>();
 
+    private static final int[] addLikeIcons = new int[]{R.drawable.icon_live_room_add_like_1,
+            R.drawable.icon_live_room_add_like_2, R.drawable.icon_live_room_add_like_3,
+            R.drawable.icon_live_room_add_like_4, R.drawable.icon_live_room_add_like_5,
+            R.drawable.icon_live_room_add_like_6, R.drawable.icon_live_room_add_like_7,
+            R.drawable.icon_live_room_add_like_8};
+
 
     private LiveRoomAnimatorHelper() {
 
@@ -34,6 +47,46 @@ public class LiveRoomAnimatorHelper {
         return mHelper;
     }
 
+    public void startAddLikeAnimation(Context context, ViewGroup viewGroup) {
+        ImageView imageView = new ImageView(context);
+        Random random = new Random();
+        int i = random.nextInt(8);
+        imageView.setImageResource(addLikeIcons[i]);
+        imageView.setId(View.generateViewId());
+        ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
+        View targetView = viewGroup.findViewById(R.id.icon_add_like);
+        layoutParams.leftToLeft = targetView.getId();
+        layoutParams.rightToRight = targetView.getId();
+        layoutParams.bottomToTop = targetView.getId();
+        viewGroup.addView(imageView, layoutParams);
+        animaViews.add(imageView);
+        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 20f, 0f, -20f, 0f, 20f, 0f, -20f);
+        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, -600f);
+        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageView, "alpha", 1.0f, 0.2f);
+        AnimatorSet animatorSet = new AnimatorSet();
+        LinearInterpolator linearInterpolator = new LinearInterpolator();
+        animatorSet.setInterpolator(linearInterpolator);
+        animatorSet.play(objectAnimator).with(objectAnimator2).with(objectAnimator3);
+        animatorSet.setDuration(2000);
+        animatorSet.start();
+        animations.add(animatorSet);
+        animatorSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                if (viewGroup != null) {
+                    viewGroup.removeView(imageView);
+                }
+                if (animaViews != null) {
+                    animaViews.remove(imageView);
+                }
+                if (animations != null) {
+                    animations.remove(animatorSet);
+                }
+            }
+        });
+    }
+
     public void startBarrageViewAnimation(Context context, View targetView) {
         targetView.setVisibility(View.VISIBLE);
         ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(targetView, "translationX", -300, 0f);

+ 3 - 1
tclive/src/main/java/com/daya/tclive/manager/MessageManager.java

@@ -26,8 +26,10 @@ import java.util.List;
 import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import io.reactivex.rxjava3.annotations.NonNull;
 import io.reactivex.rxjava3.core.Observable;
+import io.reactivex.rxjava3.core.Scheduler;
 import io.reactivex.rxjava3.functions.Function;
 import io.reactivex.rxjava3.functions.Predicate;
+import io.reactivex.rxjava3.schedulers.Schedulers;
 import io.reactivex.rxjava3.subjects.PublishSubject;
 
 
@@ -186,7 +188,7 @@ public class MessageManager extends V2TIMAdvancedMsgListener {
      */
     public @NonNull
     Observable<TTMessage> obMessageReceiveByRoomId(String roomId) {
-        return messageSubject.observeOn(AndroidSchedulers.mainThread()).
+        return messageSubject.subscribeOn(Schedulers.io()).
                 filter(new Predicate<MessageWrapperModel>() {
                     @Override
                     public boolean test(MessageWrapperModel messageWrapperModel) {

+ 11 - 11
tclive/src/main/java/com/daya/tclive/manager/TCIMSdkManager.java

@@ -206,17 +206,17 @@ public class TCIMSdkManager {
         MessageManager.getInstance().release();
 
         V2TIMManager.getInstance().removeIMSDKListener(v2TIMSDKListener);
-        V2TIMManager.getInstance().logout(new V2TIMCallback() {
-            @Override
-            public void onSuccess() {
-                Log.i("imsdk", "logout success");
-            }
-
-            @Override
-            public void onError(int code, String desc) {
-                Log.i("imsdk", "logout failure, code:" + code + ", desc:" + desc);
-            }
-        });
+//        V2TIMManager.getInstance().logout(new V2TIMCallback() {
+//            @Override
+//            public void onSuccess() {
+//                Log.i("imsdk", "logout success");
+//            }
+//
+//            @Override
+//            public void onError(int code, String desc) {
+//                Log.i("imsdk", "logout failure, code:" + code + ", desc:" + desc);
+//            }
+//        });
 //        unInit();
     }
 }

+ 1 - 1
tclive/src/main/java/com/daya/tclive/message/BaseTIMMessageContent.java

@@ -30,7 +30,7 @@ public abstract class BaseTIMMessageContent implements Parcelable {
         String sendUserName = jsonObject.optString("sendUserName");
         String avatarUrl = jsonObject.optString("avatarUrl");
 
-        if (!TextUtils.isEmpty(sendUserId) && !TextUtils.isEmpty(sendUserName)) {
+        if (!TextUtils.isEmpty(sendUserId)) {
             info = new SendUserInfo(sendUserId, sendUserName, avatarUrl);
             setSendUserInfo(info);
         }

+ 49 - 40
tclive/src/main/java/com/daya/tclive/presenter/TCLivePresenter.java

@@ -265,33 +265,40 @@ public class TCLivePresenter extends BasePresenter<TCLiveRoomContract.TCLiveRoom
 
     public void connectIM(String roomId, String userId, String userSig) {
         int loginStatus = V2TIMManager.getInstance().getLoginStatus();
-        if (loginStatus != V2TIM_STATUS_LOGINED && loginStatus != V2TIM_STATUS_LOGINING) {
-            //既不是已登录和登录中状态,则登录
-            this.roomId = roomId;
-            getView().showLoading();
-            V2TIMManager.getInstance().login(userId, userSig, new V2TIMCallback() {
-                @Override
-                public void onSuccess() {
-                    Log.i("TTLiveRoomActivity", "login IM success");
-                    if (getView() != null) {
-                        getView().loginIMSuccess();
-                    }
-                    registerListener(roomId);
-                }
+        this.roomId = roomId;
+        if (loginStatus == V2TIM_STATUS_LOGINED) {
+            handleLoginSuccessEvent();
+            return;
+        }
+        //既不是已登录和登录中状态,则登录
+        LOG.i("connectIM roomId:" + roomId);
+        getView().showLoading();
+        V2TIMManager.getInstance().login(userId, userSig, new V2TIMCallback() {
+            @Override
+            public void onSuccess() {
+                Log.i("TTLiveRoomActivity", "login IM success");
+                handleLoginSuccessEvent();
+            }
 
-                @Override
-                public void onError(int code, String desc) {
-                    // 如果返回以下错误码,表示使用 UserSig 已过期,请您使用新签发的 UserSig 进行再次登录。
-                    // 1. ERR_USER_SIG_EXPIRED(6206)
-                    // 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)
-                    // 注意:其他的错误码,请不要在这里调用登录接口,避免 IM SDK 登录进入死循环。
-                    Log.i("TTLiveRoomActivity", "connectIM failure, code:" + code + ", desc:" + desc);
-                    if (getView() != null) {
-                        getView().connectIMError(code, desc);
-                    }
+            @Override
+            public void onError(int code, String desc) {
+                // 如果返回以下错误码,表示使用 UserSig 已过期,请您使用新签发的 UserSig 进行再次登录。
+                // 1. ERR_USER_SIG_EXPIRED(6206)
+                // 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)
+                // 注意:其他的错误码,请不要在这里调用登录接口,避免 IM SDK 登录进入死循环。
+                Log.i("TTLiveRoomActivity", "connectIM failure, code:" + code + ", desc:" + desc);
+                if (getView() != null) {
+                    getView().connectIMError(code, desc);
                 }
-            });
+            }
+        });
+    }
+
+    private void handleLoginSuccessEvent() {
+        if (getView() != null) {
+            getView().loginIMSuccess();
         }
+        registerListener(roomId);
     }
 
     public void joinIMGroup(String targetId) {
@@ -323,6 +330,7 @@ public class TCLivePresenter extends BasePresenter<TCLiveRoomContract.TCLiveRoom
 
 
     public void sendTextMessage(String message) {
+        LOG.i("sendTextMessage roomId:" + roomId);
         if (!TextUtils.isEmpty(roomId)) {
             MessageManager.getInstance().sendTextMessage(roomId, message);
         }
@@ -334,6 +342,7 @@ public class TCLivePresenter extends BasePresenter<TCLiveRoomContract.TCLiveRoom
     }
 
     public void setObMessageListener(String roomId) {
+        LOG.i("setObMessageListener roomId:" + roomId);
         if (disposablesManager.size() != 0) {
             return;
         }
@@ -756,22 +765,22 @@ public class TCLivePresenter extends BasePresenter<TCLiveRoomContract.TCLiveRoom
      * @param roomUid
      */
     public void syncAddLikeNum(String addLikeNum, String roomUid) {
-        addSubscribe(create(TeacherAPIService.class).syncAddLikeNum(addLikeNum, roomUid), new DisposableObserver() {
-            @Override
-            public void onNext(Object o) {
-
-            }
-
-            @Override
-            public void onError(Throwable e) {
-
-            }
-
-            @Override
-            public void onComplete() {
-
-            }
-        });
+//        addSubscribe(create(TeacherAPIService.class).syncAddLikeNum(addLikeNum, roomUid), new DisposableObserver() {
+//            @Override
+//            public void onNext(Object o) {
+//
+//            }
+//
+//            @Override
+//            public void onError(Throwable e) {
+//
+//            }
+//
+//            @Override
+//            public void onComplete() {
+//
+//            }
+//        });
     }
 
     public void notifyCloseLiveRoomAction(String roomId) {

+ 900 - 0
tclive/src/main/java/com/daya/tclive/presenter/TTLiveRoomPresenter.java

@@ -0,0 +1,900 @@
+package com.daya.tclive.presenter;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.cooleshow.base.data.net.BaseResponse;
+import com.cooleshow.base.presenter.BasePresenter;
+import com.cooleshow.base.rx.BaseObserver;
+import com.cooleshow.base.utils.RequestBodyUtil;
+import com.cooleshow.usercenter.helper.UserHelper;
+import com.daya.tclive.api.StudentAPIService;
+import com.daya.tclive.bean.FriendInfoBean;
+import com.daya.tclive.bean.ImUserState;
+import com.daya.tclive.bean.LiveRoomInfoBean;
+import com.daya.tclive.bean.TTMessage;
+import com.daya.tclive.callback.ResultCallback;
+import com.daya.tclive.constants.ClassRoomConstants;
+import com.daya.tclive.constants.LiveRoomMsgConstants;
+import com.daya.tclive.constants.MessageConstants;
+import com.daya.tclive.constants.TTLiveConfig;
+import com.daya.tclive.contract.TTLiveRoomContract;
+import com.daya.tclive.helper.TTLiveHelper;
+import com.daya.tclive.manager.MessageManager;
+import com.daya.tclive.manager.TCIMSdkManager;
+import com.daya.tclive.manager.TCSdkManager;
+import com.daya.tclive.manager.TRTCSdkManager;
+import com.daya.tclive.message.BaseTIMMessageContent;
+import com.daya.tclive.message.TCBlackUserBlockMessage;
+import com.daya.tclive.message.TCBlackUserUnBlockMessage;
+import com.daya.tclive.message.TCChatModeControlMessage;
+import com.daya.tclive.message.TCChatRoomLocalMessage;
+import com.daya.tclive.message.TCControlUserMicStatusCMessage;
+import com.daya.tclive.message.TCKickOutUserMessage;
+import com.daya.tclive.message.TCLiveForceKickMessage;
+import com.daya.tclive.message.TCLiveGoodsChangeMessage;
+import com.daya.tclive.message.TCLiveRoomMemberNumMessage;
+import com.daya.tclive.message.TCSeatModerCtrlMessage;
+import com.daya.tclive.message.TCSyncAddLikeMessage;
+import com.daya.tclive.message.TCUserEnterMessage;
+import com.daya.tclive.message.TCUserLeaveMessage;
+import com.daya.tclive.message.TCUserLogOutUnNormalMessage;
+import com.daya.tclive.message.TCUserMicStatusChangeMessage;
+import com.daya.tclive.message.TCUserSeatApplyMessage;
+import com.daya.tclive.message.TCUserSeatDownMessage;
+import com.daya.tclive.message.TCUserSeatResponseMessage;
+import com.daya.tclive.message.TCUserSnappingUpMessage;
+import com.google.gson.Gson;
+import com.tencent.imsdk.v2.V2TIMCallback;
+import com.tencent.imsdk.v2.V2TIMGroupListener;
+import com.tencent.imsdk.v2.V2TIMGroupMemberInfo;
+import com.tencent.imsdk.v2.V2TIMManager;
+import com.tencent.imsdk.v2.V2TIMValueCallback;
+import com.tencent.rtmp.ui.TXCloudVideoView;
+import com.tencent.trtc.TRTCCloudDef;
+import com.tencent.trtc.TRTCCloudListener;
+import com.tencent.trtc.TRTCStatistics;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.core.Observer;
+import io.reactivex.rxjava3.disposables.Disposable;
+import io.reactivex.rxjava3.functions.Consumer;
+import io.reactivex.rxjava3.observers.DisposableObserver;
+import io.reactivex.rxjava3.schedulers.Schedulers;
+import okhttp3.RequestBody;
+
+import static com.tencent.imsdk.v2.V2TIMManager.V2TIM_STATUS_LOGINED;
+import static com.tencent.imsdk.v2.V2TIMManager.V2TIM_STATUS_LOGINING;
+
+/**
+ * Author by pq, Date on 2023/2/22.
+ */
+public class TTLiveRoomPresenter extends BasePresenter<TTLiveRoomContract.View> implements TTLiveRoomContract.Presenter {
+    private final static String TAG = "TTLiveRoomPresenter";
+    private String roomId;
+    private List<Disposable> disposablesManager = new ArrayList<>();//监听管理器
+    private TRTCCloudListener mCloudListener = new TRTCCloudListener() {
+        @Override
+        public void onEnterRoom(long result) {
+            if (result > 0) {
+                Log.d(TAG, "Enter room succeed");
+                if (getView() != null) {
+                    getView().enterLiveRoomSuccess();
+                }
+            } else {
+                Log.d(TAG, "Enter room failed");
+                if (getView() != null) {
+                    getView().enterLiveRoomError();
+                }
+            }
+        }
+
+        @Override
+        public void onExitRoom(int reason) {
+            super.onExitRoom(reason);
+            if (getView() != null) {
+                getView().onExitRoomSuccess();
+            }
+        }
+
+        @Override
+        public void onStopPublishing(int err, String errMsg) {
+            super.onStopPublishing(err, errMsg);
+            Log.i(TAG, "onStopPublishing:" + err + "--errMsg:" + errMsg);
+            if (getView() != null) {
+                getView().onStopPublishing();
+            }
+        }
+
+        @Override
+        public void onStartPublishing(int err, String errMsg) {
+            Log.i(TAG, "onStartPublishing:" + err + "--errMsg:" + errMsg);
+            if (getView() != null) {
+                getView().onPublishSuccess();
+            }
+        }
+
+        @Override
+        public void onRemoteUserEnterRoom(String userId) {
+            if (getView() != null) {
+                getView().onRemoteUserEnterRoom(userId);
+            }
+        }
+
+        @Override
+        public void onRemoteUserLeaveRoom(String userId, int reason) {
+            if (getView() != null) {
+                getView().onRemoteUserLeaveRoom(userId, reason);
+            }
+        }
+
+        @Override
+        public void onUserAudioAvailable(String userId, boolean available) {
+            super.onUserAudioAvailable(userId, available);
+            if (getView() != null) {
+                getView().onUserAudioAvailable(userId, available);
+            }
+        }
+
+        @Override
+        public void onRecvSEIMsg(String userId, byte[] data) {
+            super.onRecvSEIMsg(userId, data);
+            if (getView() != null) {
+                getView().receiveSEIMsg(userId, data);
+            }
+        }
+
+        @Override
+        public void onError(int errCode, String errMsg, Bundle extraInfo) {
+            super.onError(errCode, errMsg, extraInfo);
+            Log.i(TAG, "onError:" + errCode + "--errMsg:" + errMsg);
+        }
+
+        @Override
+        public void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality, ArrayList<TRTCCloudDef.TRTCQuality> remoteQuality) {
+            super.onNetworkQuality(localQuality, remoteQuality);
+
+        }
+
+        @Override
+        public void onStatistics(TRTCStatistics statistics) {
+            super.onStatistics(statistics);
+            if (getView() != null) {
+                getView().onStatistics(statistics);
+            }
+        }
+
+        @Override
+        public void onUserVideoAvailable(String userId, boolean available) {
+            if (getView() != null) {
+                getView().onUserVideoAvailable(userId, available);
+            }
+        }
+
+        @Override
+        public void onUserSubStreamAvailable(String userId, boolean available) {
+            if (getView() != null) {
+                getView().onUserSubStreamAvailable(userId, available);
+            }
+        }
+    };
+
+    private V2TIMGroupListener mGroupListener = new V2TIMGroupListener() {
+        @Override
+        public void onGroupAttributeChanged(String groupID, Map<String, String> groupAttributeMap) {
+            if (getView() != null) {
+                Log.i("pq", "onGroupAttributeChanged");
+                getView().onGroupAttributeChanged(groupID, groupAttributeMap);
+            }
+        }
+
+        @Override
+        public void onGroupCounterChanged(String groupID, String key, long newValue) {
+            super.onGroupCounterChanged(groupID, key, newValue);
+            if (getView() != null) {
+                getView().onGroupCounterChanged(groupID, key, newValue);
+            }
+        }
+
+        @Override
+        public void onMemberLeave(String groupID, V2TIMGroupMemberInfo member) {
+            super.onMemberLeave(groupID, member);
+            Log.i("pq", "onMemberLeave:" + member.getUserID());
+        }
+    };
+
+
+    public void init(Context context, String roomId) {
+        if (getView() != null) {
+            getView().showLoading();
+        }
+        //初始化直播SDK
+        TRTCSdkManager.getInstance().init(context.getApplicationContext(), mCloudListener);
+        TCSdkManager.getInstance().init(context.getApplicationContext(), TTLiveConfig.SDK_URL, TTLiveConfig.SDK_KEY);
+        getRoomInfo(roomId);
+        this.roomId = roomId;
+    }
+
+    @Override
+    public void getRoomInfo(String roomId) {
+        addSubscribe(create(StudentAPIService.class).getLiveRoomInfo(roomId), new BaseObserver<LiveRoomInfoBean>(getView()) {
+            @Override
+            protected void onSuccess(LiveRoomInfoBean data) {
+                Log.i("TTLiveRoomActivity", "getRoomInfo success" + data);
+                if (getView() != null) {
+                    getView().getRoomInfoSuccess(data);
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                super.onError(e);
+                e.printStackTrace();
+                if (getView() != null) {
+                    getView().getRoomInfoError(e);
+                }
+            }
+        });
+    }
+
+    public void connectIM(String userId, String userSig) {
+        int loginStatus = V2TIMManager.getInstance().getLoginStatus();
+        Log.i("TTLiveRoomActivity", "login to IM :" + loginStatus);
+        if (loginStatus == V2TIM_STATUS_LOGINED) {
+            handleLoginSuccessEvent();
+            return;
+        }
+        //既不是已登录和登录中状态,则登录
+        V2TIMManager.getInstance().login(userId, userSig, new V2TIMCallback() {
+            @Override
+            public void onSuccess() {
+                Log.i("TTLiveRoomActivity", "login IM success");
+                handleLoginSuccessEvent();
+            }
+
+            @Override
+            public void onError(int code, String desc) {
+                // 如果返回以下错误码,表示使用 UserSig 已过期,请您使用新签发的 UserSig 进行再次登录。
+                // 1. ERR_USER_SIG_EXPIRED(6206)
+                // 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)
+                // 注意:其他的错误码,请不要在这里调用登录接口,避免 IM SDK 登录进入死循环。
+                Log.i("TTLiveRoomActivity", "connectIM failure, code:" + code + ", desc:" + desc);
+                if (getView() != null) {
+                    getView().connectIMError(code, desc);
+                }
+            }
+        });
+    }
+
+    private void handleLoginSuccessEvent() {
+        if (getView() != null) {
+            getView().loginIMSuccess();
+        }
+        registerListener();
+    }
+
+    private void registerListener() {
+        setObMessageListener(roomId);
+        MessageManager.getInstance().register();
+    }
+
+    public void createGroup(String targetId) {
+        V2TIMManager.getInstance().createGroup(V2TIMManager.GROUP_TYPE_AVCHATROOM, targetId, "安卓测试群", new V2TIMValueCallback<String>() {
+            @Override
+            public void onSuccess(String s) {
+                // 创建群组成功
+                Log.i("pq", "createGroup success");
+            }
+
+            @Override
+            public void onError(int code, String desc) {
+                // 创建群组失败
+                Log.i("pq", "createGroup onError:" + code + "--" + desc);
+            }
+        });
+    }
+
+    public void joinGroup(String targetId) {
+        Log.i("pq", "joinGroup :" + targetId);
+        TCIMSdkManager.getInstance().joinGroup(targetId, new ResultCallback<Boolean>() {
+            @Override
+            public void onSuccess(Boolean aBoolean) {
+                if (getView() != null && aBoolean) {
+                    sendDefaultMessage();
+                    getView().joinGroupSuccess();
+                }
+            }
+
+            @Override
+            public void onFail(int errorCode, String errorStr) {
+                Log.i("pq", "joinGroup errorCode:" + errorCode + "--" + errorStr);
+                if (getView() != null) {
+                    getView().joinGroupError(errorCode, errorStr);
+                }
+            }
+        });
+    }
+
+    public void sendDefaultMessage() {
+        TCChatRoomLocalMessage tips = new TCChatRoomLocalMessage();
+        tips.setText("欢迎进入直播课堂,请遵守相关法规,禁止传播低俗、暴力等不良信息。为孩子创造健康绿色的学习环境。");
+        sendMessage(tips, true);
+    }
+
+    public void sendTextMessage(String message) {
+        if (!TextUtils.isEmpty(roomId)) {
+            MessageManager.getInstance().sendTextMessage(roomId, message);
+        }
+    }
+
+
+    public void sendMessage(BaseTIMMessageContent messageContent, boolean isShowLocation) {
+        if (!TextUtils.isEmpty(roomId)) {
+            MessageManager.getInstance().sendMessage(roomId, isShowLocation, messageContent);
+        }
+    }
+
+
+    public void setObMessageListener(String roomId) {
+        if (disposablesManager.size() != 0) {
+            return;
+        }
+        Disposable subscribe = MessageManager.getInstance()
+                .obMessageReceiveByRoomId(roomId)
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<TTMessage>() {
+                    @Override
+                    public void accept(TTMessage message) {
+                        BaseTIMMessageContent content = message.getContent();
+//                        //将消息显示到列表上
+                        if (TTLiveHelper.isShowingMessage(content)) {
+                            if (null != getView()) {
+                                getView().addMessageContent(message);
+                            }
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_USER_SNAPPING_UP)) {
+                            //抢购消息
+                            if (null != getView() && message.getContent() != null) {
+                                TCUserSnappingUpMessage rcOnSnappingUpMessage = (TCUserSnappingUpMessage) message.getContent();
+                                getView().receiveSnapUpMessage(rcOnSnappingUpMessage);
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_USER_ENTER)) {
+                            //加入房间消息
+                            if (null != getView() && message.getContent() != null) {
+                                TCUserEnterMessage joinRoomMessage = (TCUserEnterMessage) message.getContent();
+                                getView().receiveJoinMessage(joinRoomMessage);
+                            }
+                            return;
+                        }
+
+                        //以下为行为消息
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_LIVE_ROOM_FINISH)) {
+                            //直播间关闭
+                            if (null != getView()) {
+                                getView().liveRoomOffline();
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_CHAT_MODE_CONTROL)) {
+                            //聊天模式控制消息
+                            if (message.getContent() != null) {
+                                TCChatModeControlMessage tcChatModeControlMessage = (TCChatModeControlMessage) message.getContent();
+                                if (getView() != null && tcChatModeControlMessage != null) {
+                                    getView().switchChatMode(tcChatModeControlMessage.isChatBan());
+                                }
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_LIVE_GOODS_CHANGE)) {
+                            //直播间商品变化
+                            if (message.getContent() != null) {
+                                TCLiveGoodsChangeMessage liveGoodsChangeMessage = (TCLiveGoodsChangeMessage) message.getContent();
+                                if (getView() != null && liveGoodsChangeMessage != null) {
+                                    getView().liveGoodsChange(liveGoodsChangeMessage.getGoodsContent());
+                                }
+                            }
+                            return;
+                        }
+
+                        //连麦模式控制消息
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_SEAT_MODE_CONTROL)) {
+                            if (message.getContent() != null) {
+                                TCSeatModerCtrlMessage userSeatsCtrlMessage = (TCSeatModerCtrlMessage) message.getContent();
+                                if (getView() != null && userSeatsCtrlMessage != null) {
+                                    getView().changeMicControlMode(userSeatsCtrlMessage.isSeatBan());
+                                }
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_SYNC_ADD_LIKE_COUNT)) {
+                            //同步点赞消息
+                            TCSyncAddLikeMessage addLikeMessage = (TCSyncAddLikeMessage) content;
+                            if (getView() != null) {
+                                getView().onAddLikeMessage(addLikeMessage);
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_SYNC_MEMBER_COUNT)) {
+                            //同步成员数量
+                            if (null != getView()) {
+                                TCLiveRoomMemberNumMessage rcChatRoomMemberNumMessage = (TCLiveRoomMemberNumMessage) content;
+                                getView().syncMemberCount(rcChatRoomMemberNumMessage.getCount());
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_KICK_OUT_TARGET_USER)) {
+                            //用户被踢出房间消息
+                            if (null != getView()) {
+                                TCKickOutUserMessage userKickOutMessage = (TCKickOutUserMessage) content;
+                                getView().onUserKickOutMsg(userKickOutMessage);
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_USER_SEAT_RESPONSE)) {
+                            //连麦回复消息
+                            if (null != getView()) {
+                                TCUserSeatResponseMessage rcUserSeatResponseMessage = (TCUserSeatResponseMessage) content;
+                                if (rcUserSeatResponseMessage == null || TextUtils.isEmpty(rcUserSeatResponseMessage.getAudienceId())) {
+                                    return;
+                                }
+                                if (TextUtils.equals(rcUserSeatResponseMessage.getAudienceId(), UserHelper.getImUserId())) {
+                                    getView().seatResponse(rcUserSeatResponseMessage);
+                                }
+                                return;
+                            }
+                        }
+
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_USER_SEAT_APPLY)) {
+                            //主播邀请上麦
+                            TCUserSeatApplyMessage seatApplyMessage = (TCUserSeatApplyMessage) content;
+                            if (getView() != null) {
+                                getView().onInviteSeatMic(seatApplyMessage);
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_KICK_OUT_TARGET_USER)) {
+                            //观众异常退出消息
+                            TCUserLogOutUnNormalMessage loginOutUnusualMessage = (TCUserLogOutUnNormalMessage) content;
+                            if (getView() != null) {
+                                getView().onUserUnusualLogout(loginOutUnusualMessage);
+                            }
+                            return;
+                        }
+
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_LIVE_PAUSE)) {
+                            //暂停直播,进行下麦操作
+                            if (getView() != null) {
+                                getView().onLivePause();
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_BLOCK_BLACK_USER)) {
+                            //添加黑名单用户
+                            TCBlackUserBlockMessage blackUserBlockMessage = (TCBlackUserBlockMessage) content;
+                            if (getView() != null) {
+                                getView().changeBlackUserStatus(blackUserBlockMessage.getUserId(), true);
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_UN_BLOCK_BLACK_USER)) {
+                            //解除黑名单用户
+                            TCBlackUserUnBlockMessage userUnBlockMessage = (TCBlackUserUnBlockMessage) content;
+                            if (getView() != null) {
+                                getView().changeBlackUserStatus(userUnBlockMessage.getUserId(), false);
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_LIVE_UNDER_ALL_MIC)) {
+                            //全部下麦消息
+                            if (getView() != null) {
+                                getView().onUnderAllMic();
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_LIVE_REFUSE_ALL_MIC_APPLY)) {
+                            //拒绝全部连麦
+                            if (getView() != null) {
+                                getView().onRefuseAllMicApply();
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_TEACHER_START_LIVE)) {
+                            //拒绝全部连麦
+                            if (getView() != null) {
+                                getView().onUserStartPublish();
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_CONTROL_USER_MIC_STATUS)) {
+                            //麦克风控制模式
+                            TCControlUserMicStatusCMessage controlUserMicStatusCMessage = (TCControlUserMicStatusCMessage) content;
+                            if (getView() != null) {
+                                getView().onMicStatusControl(controlUserMicStatusCMessage.getUserId(), controlUserMicStatusCMessage.isMuteMic());
+                            }
+                            return;
+                        }
+
+                        if (TextUtils.equals(message.getObjectName(), MessageConstants.TAG_FORCED_KICK)) {
+                            //强制T人
+                            if (message.getContent() != null && null != getView()) {
+                                TCLiveForceKickMessage messageContent = (TCLiveForceKickMessage) message.getContent();
+                                getView().onLiveForceKick(messageContent);
+                                return;
+                            }
+                        }
+                    }
+                });
+        disposablesManager.add(subscribe);
+    }
+
+
+    public void handleAction(int action, Object... object) {
+        switch (action) {
+            case LiveRoomMsgConstants.ACTION_SEND_JOIN_ROOM:
+                //发送加入房间成功消息
+                TCUserEnterMessage userEnterMessage = new TCUserEnterMessage();
+                sendMessage(userEnterMessage, true);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_ADD_LIKE_COUNT:
+                //发送点赞数量
+//                TCAddLikeMessage addLikeMessage = new TCAddLikeMessage();
+//                long addLikeCount = (int) object[0];
+//                addLikeMessage.setCounts(addLikeCount);
+//                sendMessage(addLikeMessage, false);
+
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_LEAVE_ROOM:
+                //退出直播间消息
+                TCUserLeaveMessage rcUserLeaveRoomMessage = new TCUserLeaveMessage();
+                sendMessage(rcUserLeaveRoomMessage, false);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_SEAT_APPLY:
+                //申请连麦
+                TCUserSeatApplyMessage rcUserSeatApplyMessage = new TCUserSeatApplyMessage();
+                rcUserSeatApplyMessage.setType(LiveRoomMsgConstants.MIC_ACTION_SEAT_BY_USER);
+                if (object != null && object.length > 1) {
+//                    rcUserSeatApplyMessage.setTeacherId(currentRoomInfo.speakerId);
+//                    rcUserSeatApplyMessage.setTeacherName(currentRoomInfo.speakerName);
+                    rcUserSeatApplyMessage.setTeacherId((String) object[0]);
+                    rcUserSeatApplyMessage.setTeacherName((String) object[1]);
+                }
+                rcUserSeatApplyMessage.setAudienceAvatar(UserHelper.getUserAvatar());
+                rcUserSeatApplyMessage.setAudienceId(UserHelper.getUserId());
+                rcUserSeatApplyMessage.setAudienceName(UserHelper.getUserName());
+                sendMessage(rcUserSeatApplyMessage, true);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_APPLY:
+                //取消连麦申请
+                TCUserSeatApplyMessage cancelApplyMessage = new TCUserSeatApplyMessage();
+                cancelApplyMessage.setType(LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_USER);
+                if (object != null && object.length > 1) {
+//                    rcUserSeatApplyMessage.setTeacherId(currentRoomInfo.speakerId);
+//                    rcUserSeatApplyMessage.setTeacherName(currentRoomInfo.speakerName);
+                    cancelApplyMessage.setTeacherId((String) object[0]);
+                    cancelApplyMessage.setTeacherName((String) object[1]);
+                }
+                cancelApplyMessage.setAudienceId(UserHelper.getUserId());
+                cancelApplyMessage.setAudienceName(UserHelper.getUserName());
+                sendMessage(cancelApplyMessage, true);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_DOWN_SEAT_MIC:
+                //观众下麦消息
+                TCUserSeatDownMessage rcUserMicLeaveMessage = new TCUserSeatDownMessage();
+                rcUserMicLeaveMessage.setAudienceId(UserHelper.getUserId());
+                rcUserMicLeaveMessage.setAudienceName(UserHelper.getUserName());
+                sendMessage(rcUserMicLeaveMessage, false);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_AGREE_RESPONSE:
+                //被邀请上麦->观众同意上麦
+                TCUserSeatResponseMessage rcUserSeatResponseMessage = new TCUserSeatResponseMessage();
+                rcUserSeatResponseMessage.setType(LiveRoomMsgConstants.MIC_RESPONSE_AGREE_BY_USER);
+                if (object != null && object.length > 1) {
+//                    rcUserSeatApplyMessage.setTeacherId(currentRoomInfo.speakerId);
+//                    rcUserSeatApplyMessage.setTeacherName(currentRoomInfo.speakerName);
+                    rcUserSeatResponseMessage.setTeacherId((String) object[0]);
+                    rcUserSeatResponseMessage.setTeacherName((String) object[1]);
+                }
+                rcUserSeatResponseMessage.setAudienceId(UserHelper.getUserId());
+                rcUserSeatResponseMessage.setAudienceName(UserHelper.getUserName());
+                sendMessage(rcUserSeatResponseMessage, true);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_DISAGREE_RESPONSE:
+                //被邀请上麦->观众不同意上麦
+                TCUserSeatResponseMessage disAgreeSeatResponseMessage = new TCUserSeatResponseMessage();
+                disAgreeSeatResponseMessage.setType(LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE_BY_USER);
+                if (object != null && object.length > 1) {
+//                    rcUserSeatApplyMessage.setTeacherId(currentRoomInfo.speakerId);
+//                    rcUserSeatApplyMessage.setTeacherName(currentRoomInfo.speakerName);
+                    disAgreeSeatResponseMessage.setTeacherId((String) object[0]);
+                    disAgreeSeatResponseMessage.setTeacherName((String) object[1]);
+                }
+                disAgreeSeatResponseMessage.setAudienceId(UserHelper.getUserId());
+                disAgreeSeatResponseMessage.setAudienceName(UserHelper.getUserName());
+                sendMessage(disAgreeSeatResponseMessage, true);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_ON_SNAP_UP:
+                //发送正在抢购消息
+                TCUserSnappingUpMessage rcOnSnappingUpMessage = new TCUserSnappingUpMessage();
+                sendMessage(rcOnSnappingUpMessage, true);
+                break;
+            case LiveRoomMsgConstants.ACTION_SEND_MIC_STATUS_CHANGE:
+                TCUserMicStatusChangeMessage micStatusChangeMessage = new TCUserMicStatusChangeMessage();
+                if (object != null && object.length > 1) {
+                    micStatusChangeMessage.setUserId((String) object[0]);
+                    micStatusChangeMessage.setMuteMic((Boolean) object[1]);
+                }
+                sendMessage(micStatusChangeMessage, false);
+                break;
+        }
+
+    }
+
+    /**
+     * 因全部拒绝连麦消息没有携带id相关参数,所以本地造一个拒绝连麦的消息插入到消息列表
+     */
+    public void buildResponseMessage(String userId, String speakerId, String speakerName) {
+        TCUserSeatResponseMessage responseMessage = new TCUserSeatResponseMessage();
+        responseMessage.setType(LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE);
+        responseMessage.setTeacherId(speakerId);
+        responseMessage.setTeacherName(speakerName);
+        responseMessage.setAudienceId(userId);
+        responseMessage.setAudienceName(UserHelper.getUserName());
+        TTMessage message = TTMessage.obtain(responseMessage);
+        message.setObjectName(MessageConstants.TAG_USER_SEAT_RESPONSE);
+        getView().addMessageContent(message);
+    }
+
+    /**
+     * 因全部拒绝连麦消息没有携带id相关参数,所以本地造一个拒绝连麦的消息插入到消息列表
+     */
+    public void buildUnderMicResponseMessage(String userId, String speakerId, String speakerName) {
+        TCUserSeatApplyMessage responseMessage = new TCUserSeatApplyMessage();
+        responseMessage.setType(LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_CREATE);
+        responseMessage.setTeacherId(speakerId);
+        responseMessage.setTeacherName(speakerName);
+        responseMessage.setAudienceId(userId);
+        responseMessage.setAudienceName(UserHelper.getUserName());
+        TTMessage message = TTMessage.obtain(responseMessage);
+        message.setObjectName(MessageConstants.TAG_USER_SEAT_APPLY);
+        getView().addMessageContent(message);
+    }
+
+    public void notifyJoinRoomAction(String roomId, String userId) {
+        //主进程调用,因为BaseObserver onStart show了loading控件,防止在子线程创建
+        if (TextUtils.isEmpty(roomId) || TextUtils.isEmpty(userId)) {
+            return;
+        }
+        addSubscribe(create(StudentAPIService.class).notifyJoinRoomAction(roomId, userId, true), new DisposableObserver() {
+            @Override
+            public void onNext(Object o) {
+                //通知服务端加入成功即可,无须关注结果
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                e.printStackTrace();
+            }
+
+            @Override
+            public void onComplete() {
+
+            }
+        });
+    }
+
+    public void getUserInfoByUserId(String userId) {
+        addSubscribe(create(StudentAPIService.class).queryFriendDetail(userId), new DisposableObserver<BaseResponse<FriendInfoBean>>() {
+            @Override
+            public void onNext(BaseResponse<FriendInfoBean> friendInfoBeanBaseResponse) {
+                if (getView() != null && friendInfoBeanBaseResponse != null) {
+                    getView().getFriendInfoSuccess(friendInfoBeanBaseResponse.getData());
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                e.printStackTrace();
+            }
+
+            @Override
+            public void onComplete() {
+
+            }
+        });
+    }
+
+    public void notifyLeaveRoomAction() {
+        handleAction(LiveRoomMsgConstants.ACTION_SEND_LEAVE_ROOM);
+        ImUserState imUserState = new ImUserState();
+        imUserState.setStatus(ImUserState.ACTION_LEAVE_LIVE_ROOM);
+        imUserState.setUserid(UserHelper.getUserId());
+        imUserState.setOs("Android");
+        ArrayList<ImUserState> imUserStates = new ArrayList();
+        imUserStates.add(imUserState);
+        RequestBody body = RequestBodyUtil.convertToRequestBodyJson(new Gson().toJson(imUserStates));
+        create(StudentAPIService.class).notifyLeaveRoomAction(body)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Observer<BaseResponse<Object>>() {
+                    @Override
+                    public void onSubscribe(Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(BaseResponse<Object> objectBaseResponse) {
+                        //通知服务端离开即可,无须关注结果
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+
+                    }
+
+                    @Override
+                    public void onComplete() {
+                        //通知服务端离开即可,无须关注结果
+                    }
+                });
+    }
+
+    public void joinMic(String userId, String userSig) {
+        TRTCSdkManager.getInstance().enterRoom(TTLiveConfig.getSDK_AppID(), userId, roomId, userSig);
+    }
+
+    public void startPublish(String userId) {
+        TRTCSdkManager.getInstance().startLocalAudio();
+//        TRTCSdkManager.getInstance().startPublish("");
+    }
+
+    public void startMainRemoteView(String speakerId, boolean isPc, TXCloudVideoView txCloudVideoView) {
+        TRTCSdkManager.getInstance().startRemoteView(speakerId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, txCloudVideoView);
+        setMainRemoteViewParams(speakerId, isPc);
+    }
+
+    public void setMainRemoteViewParams(String speakerId, boolean isPc) {
+        TRTCSdkManager.getInstance().setRemoteRenderParams(speakerId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, isPc ? TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FIT : TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL, TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_DISABLE);
+    }
+
+    public void startSubRemoteView(String speakerId, boolean isPc, TXCloudVideoView txCloudVideoView) {
+        TRTCSdkManager.getInstance().startRemoteView(speakerId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB, txCloudVideoView);
+        setSubRemoteViewParams(speakerId, isPc);
+    }
+
+    public void setMicrophoneDisable(boolean isDisable) {
+        //disable true 关闭麦克风 false 打开麦克风
+        TRTCSdkManager.getInstance().setMicrophoneDisable(isDisable);
+    }
+
+    public void setSubRemoteViewParams(String speakerId, boolean isPc) {
+        TRTCSdkManager.getInstance().setRemoteRenderParams(speakerId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB, isPc ? TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FIT : TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL, TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_DISABLE);
+    }
+
+    public void stopAllRemoteView(String speakerId) {
+        stopMainRemoteView(speakerId);
+        stopSubRemoteView(speakerId);
+    }
+
+    public void stopMainRemoteView(String speakerId) {
+        TRTCSdkManager.getInstance().stopRemoteView(speakerId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
+    }
+
+    public void stopSubRemoteView(String speakerId) {
+        TRTCSdkManager.getInstance().stopRemoteView(speakerId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB);
+    }
+
+    public void exitRoom() {
+        TRTCSdkManager.getInstance().exitRoom();
+    }
+
+    public void bindGroupListener() {
+        TCIMSdkManager.getInstance().addGroupListener(mGroupListener);
+    }
+
+    public void release() {
+        if (mGroupListener != null) {
+            TCIMSdkManager.getInstance().removeGroupListener(mGroupListener);
+        }
+    }
+
+    public void updateGroupAddLike(String groupId, long counter) {
+        TCIMSdkManager.getInstance().increaseGroupCounter(groupId, TTLiveConfig.LIVE_ROOM_LIKES_KEY, counter, new V2TIMValueCallback() {
+            @Override
+            public void onSuccess(Object o) {
+
+            }
+
+            @Override
+            public void onError(int i, String s) {
+
+            }
+        });
+    }
+
+    public void getAllGroupCounter(String groupId) {
+        TCIMSdkManager.getInstance().getGroupCounter(groupId, new V2TIMValueCallback<Map<String, Long>>() {
+            @Override
+            public void onSuccess(Map<String, Long> map) {
+                if (getView() != null) {
+                    getView().getAllGroupCounterSuccess(map);
+                }
+            }
+
+            @Override
+            public void onError(int i, String s) {
+
+            }
+        });
+    }
+
+    public void getAllGroupAttributes(String groupId) {
+        TCIMSdkManager.getInstance().getGroupAttributes(groupId, new V2TIMValueCallback() {
+            @Override
+            public void onSuccess(Object o) {
+                if (getView() != null) {
+                    getView().getAllGroupAttributesSuccess(o);
+                }
+            }
+
+            @Override
+            public void onError(int i, String s) {
+
+            }
+        });
+    }
+
+    public void muteTRTC(boolean isMute) {
+        TRTCSdkManager.getInstance().muteAll(isMute);
+    }
+
+    public void config3AParamsFromSubject(String subjectId) {
+        if (TextUtils.equals(subjectId, ClassRoomConstants.SUBJECT_ID_SAX)) {
+            //萨克斯
+            TRTCSdkManager.getInstance().config3AParams(45, 100, 0);
+            return;
+        }
+
+        if (TextUtils.equals(subjectId, ClassRoomConstants.SUBJECT_ID_TROMBONE)) {
+            //长号
+            TRTCSdkManager.getInstance().config3AParams(45, 100, 0);
+            return;
+        }
+
+        if (TextUtils.equals(subjectId, ClassRoomConstants.SUBJECT_ID_TENOR_HORN)) {
+            //次中音号
+            TRTCSdkManager.getInstance().config3AParams(80, 100, 0);
+            return;
+        }
+
+        if (TextUtils.equals(subjectId, ClassRoomConstants.SUBJECT_ID_TRUMPET)) {
+            //小号
+            TRTCSdkManager.getInstance().config3AParams(50, 100, 0);
+            return;
+        }
+    }
+}

+ 4 - 2
tclive/src/main/java/com/daya/tclive/ui/LiveApplyMicFragment.java

@@ -128,8 +128,10 @@ public class LiveApplyMicFragment extends BaseFragment<TcFgLiveApplyMicLayoutBin
      * @param applyListData
      */
     public void refresh(ArrayList<User> applyListData) {
-        mAdapter.getData().clear();
-        mAdapter.setList(applyListData);
+        if (mAdapter != null) {
+            mAdapter.getData().clear();
+            mAdapter.setList(applyListData);
+        }
     }
 
     public void setOnEventListener(LiveMicOnEventListener listener) {

+ 2360 - 0
tclive/src/main/java/com/daya/tclive/ui/TCStudentLiveRoomActivity.java

@@ -0,0 +1,2360 @@
+package com.daya.tclive.ui;
+
+import android.Manifest;
+import android.animation.ObjectAnimator;
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.airbnb.lottie.LottieAnimationView;
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.alibaba.android.arouter.launcher.ARouter;
+import com.bumptech.glide.Glide;
+import com.cooleshow.base.ui.activity.BaseMVPActivity;
+import com.cooleshow.base.utils.AppUtils;
+import com.cooleshow.base.utils.GsonUtils;
+import com.cooleshow.base.utils.LOG;
+import com.cooleshow.base.utils.PermissionUtils;
+import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.widgets.DensityUtil;
+import com.cooleshow.base.widgets.DialogUtil;
+import com.cooleshow.base.widgets.InputBar;
+import com.cooleshow.base.widgets.dialog.CommonConfirmDialog;
+import com.cooleshow.base.widgets.dialog.InputBarDialog;
+import com.cooleshow.usercenter.helper.UserHelper;
+import com.daya.tclive.R;
+import com.daya.tclive.adapter.TTMessageAdapter;
+import com.daya.tclive.bean.FriendInfoBean;
+import com.daya.tclive.bean.LiveRoomInfoBean;
+import com.daya.tclive.bean.LiveStatusSEMIMsg;
+import com.daya.tclive.bean.SendUserInfo;
+import com.daya.tclive.bean.TTMessage;
+import com.daya.tclive.bean.TTUserInfo;
+import com.daya.tclive.constants.ARouterConstace;
+import com.daya.tclive.constants.LiveRoomMsgConstants;
+import com.daya.tclive.constants.TTLiveConfig;
+import com.daya.tclive.contract.TTLiveRoomContract;
+import com.daya.tclive.databinding.AcTtLiveroomLayoutBinding;
+import com.daya.tclive.helper.LiveMemberHelper;
+import com.daya.tclive.helper.LiveMessageHelper;
+import com.daya.tclive.helper.LiveRoomAddLikeHelper;
+import com.daya.tclive.helper.LiveRoomAnimatorHelper;
+import com.daya.tclive.helper.TTLiveHelper;
+import com.daya.tclive.manager.TCIMSdkManager;
+import com.daya.tclive.manager.TRTCSdkManager;
+import com.daya.tclive.message.TCKickOutUserMessage;
+import com.daya.tclive.message.TCLiveForceKickMessage;
+import com.daya.tclive.message.TCSyncAddLikeMessage;
+import com.daya.tclive.message.TCUserEnterMessage;
+import com.daya.tclive.message.TCUserLogOutUnNormalMessage;
+import com.daya.tclive.message.TCUserSeatApplyMessage;
+import com.daya.tclive.message.TCUserSeatResponseMessage;
+import com.daya.tclive.message.TCUserSnappingUpMessage;
+import com.daya.tclive.presenter.TTLiveRoomPresenter;
+import com.daya.tclive.ui.floatPop.FloatWindowHelper;
+import com.daya.tclive.ui.floatPop.FloatingWindowService;
+import com.daya.tclive.widget.TTLiveRoomMicIconView;
+import com.daya.tclive.widget.dialog.LiveRoomCloseMicTipDialog;
+import com.daya.tclive.widget.dialog.LiveRoomClosePageOnMicTipDialog;
+import com.daya.tclive.widget.dialog.LiveRoomExitTipDialog2;
+import com.daya.tclive.widget.dialog.LiveRoomInviteSeatMicTipDialog;
+import com.daya.tclive.widget.dialog.LiveRoomMicManagerDialog;
+import com.daya.tclive.widget.dialog.LiveRoomShopCarDialog;
+import com.daya.tclive.widget.dialog.OpenOverlayPermissionTipDialog;
+import com.gyf.immersionbar.ImmersionBar;
+import com.tbruyelle.rxpermissions3.RxPermissions;
+import com.tencent.imsdk.v2.V2TIMManager;
+import com.tencent.imsdk.v2.V2TIMSDKListener;
+import com.tencent.imsdk.v2.V2TIMUserFullInfo;
+import com.tencent.imsdk.v2.V2TIMUserStatus;
+import com.tencent.live2.V2TXLiveDef;
+import com.tencent.live2.V2TXLivePlayer;
+import com.tencent.live2.V2TXLivePlayerObserver;
+import com.tencent.live2.impl.V2TXLivePlayerImpl;
+import com.tencent.rtmp.ui.TXCloudVideoView;
+import com.tencent.trtc.TRTCStatistics;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.constraintlayout.widget.Group;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import static com.tencent.live2.V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0;
+
+/**
+ * Author by pq, Date on 2023/2/22.
+ */
+@Route(path = ARouterConstace.ACTIVITY_TT_LIVE_ROOM)
+public class TCStudentLiveRoomActivity extends BaseMVPActivity<AcTtLiveroomLayoutBinding,TTLiveRoomPresenter> implements TTLiveRoomContract.View, View.OnClickListener {
+    public static final String TAG = "TTLiveRoomActivity";
+
+    ConstraintLayout content_view;
+    TXCloudVideoView mVideoView;
+    FrameLayout flVideoContainer;
+    ConstraintLayout csVideoContainer;
+    Group mGroupViews;
+    FrameLayout mFlJoinBarrage;
+    ImageView mIvClose;
+    FrameLayout mFlSnapUpBarrage;
+    ImageView mIvSwitchVideoOrientation;
+    ImageView mIvSwitchVideoOrientationFull;
+    ConstraintLayout cs_header_info;
+    FrameLayout msgContainer;
+    TextView tv_input;
+    FrameLayout fl_input;
+    RecyclerView mRecyclerMsg;
+    ConstraintLayout mViewLiveStatus;
+    ConstraintLayout viewLiveCameraStatus;
+    ImageView mIvLiveStatusCameraCenterIcon;
+    TextView mTvLiveCameraStatusTipText;
+    ImageView mIvLiveStatusCenterIcon;
+    TextView mTvLiveStatusTipText;
+    TextView mTvJoinBarrage;
+    TextView mTvSnapUpBarrage;
+    TextView mTvAddLikeCount;
+    TextView mTvNumPeople;
+    ImageView iv_mic;
+    LottieAnimationView mViewShopCarAnim;
+    ImageView mIvShopCar;
+    ImageView mIvAvatar;
+    TextView mTvRoomCreateName;
+    ImageView mIvVoiceSwitch;
+    Group group_tip;
+    Group group_loading;
+    TextView tv_retry;
+    TextView tv_loading;
+    TTLiveRoomMicIconView mLlMicContainer;
+    TXCloudVideoView subVideoView;
+    private ServiceConnection serviceConnection;
+    public static final int SEND_SHOW_FLOAT_WINDOW_TIME = 1000;//退到后台以后检查是否显示悬浮窗等待时长
+    public static final int SEND_APP_BACKGROUND_MSG = 1001;//退到后台消息
+    public static final int SEND_JUMP_OTHER_PAGE_MSG = 1002;//页面切换消息(购物车详情页等等)
+    public static final int OPEN_SHOP_CAR_DIALOG = 1003;//打开购物车
+
+
+    public static final int LIVE_STATUS_IS_REST = 1;//休息一下,马上回来
+    public static final int LIVE_STATUS_IS_CLOSE_VIDEO = 2;//主持人关闭画面
+    public static final int LIVE_STATUS_IS_OFFLINE = 3;//直播已结束
+    public static final int LIVE_STATUS_LOADING = 4;//直播加载中
+    public static final int LIVE_STATUS_ERROR = 5;//直播加载中出错
+    private static final String ROOMID_KEY = "roomid_key";
+    private static final String SUBJECT_ID_KEY = "subject_id_key";
+    private String mRoomId = "";
+    private String mUserId = "";
+    private ObjectAnimator hideHeaderInfoAnim;
+    private ObjectAnimator showHeaderInfoAnim;
+    private boolean isEnableChat = false;//默认不禁止
+    private boolean isEnableMic = false;//默认不禁止
+    private boolean isEnableAll = false;//默认不禁止 黑名单状态
+    private boolean isPcClientLive = true;//默认为PC端直播
+    private boolean isMuteAllMic = false;//默认为不禁止麦克风
+    private boolean isNeedRefresh = false;//是否需要重新刷新房间信息
+    private boolean liveIsFinish = false;//直播间是否已结束
+    private boolean liveIsPause = false;//直播间是否已暂停
+    private long currentAddLikeCount = 0;//当前点赞数量
+    private int currentSeatStatus = LiveRoomMsgConstants.MIC_STATUS_NORMAL;//1未连麦,2连麦中,3连麦成功
+    private LiveRoomInfoBean roomInfo;
+    private InputBarDialog mInputBarDialog;
+    private LiveRoomMicManagerDialog mMicManagerDialog;
+    private LiveRoomInviteSeatMicTipDialog mInviteSeatMicTipDialog;
+    private LiveRoomShopCarDialog mShopCarDialog;
+    private V2TXLivePlayer mMLivePlayer;
+    private boolean isMuteAll = false;//是否静音
+    private boolean isConnectImFailed = false;//IM状态是否异常
+    private boolean isOnResume = true;
+    private Handler mHandler = new Handler(Looper.myLooper()) {
+        @Override
+        public void handleMessage(@NonNull android.os.Message msg) {
+            if (msg.what == SEND_APP_BACKGROUND_MSG) {
+                //APP切换后台 isOnResume要等于false
+                //开启悬浮窗
+                if (!isOnResume && AppUtils.isApplicationInBackground(TCStudentLiveRoomActivity.this)) {
+                    startFloatWindowService();
+                }
+                return;
+            }
+            if (msg.what == SEND_JUMP_OTHER_PAGE_MSG) {
+                //跳转其他页面时候
+                //开启悬浮窗
+                if (isOnResume) {
+                    //如果页面onResume了,就不开启service
+                    return;
+                }
+                startFloatWindowService();
+                return;
+            }
+
+            if (msg.what == OPEN_SHOP_CAR_DIALOG) {
+                showShopCarDialog();
+                return;
+            }
+        }
+    };
+
+    private V2TIMSDKListener mTIMSDKListener = new V2TIMSDKListener() {
+        @Override
+        public void onConnecting() {
+            super.onConnecting();
+            Log.i(TAG, "onConnecting");
+        }
+
+        @Override
+        public void onConnectSuccess() {
+            super.onConnectSuccess();
+            Log.i(TAG, "onConnectSuccess");
+            if (isConnectImFailed) {
+                if (isOnMic()) {
+                    handleCloseMicEvent();
+                }
+                presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_JOIN_ROOM);
+                presenter.notifyJoinRoomAction(mRoomId, mUserId);
+                presenter.getAllGroupAttributes(mRoomId);
+                presenter.getAllGroupCounter(mRoomId);
+                play();
+            }
+            isConnectImFailed = false;
+        }
+
+        @Override
+        public void onConnectFailed(int code, String error) {
+            super.onConnectFailed(code, error);
+            Log.i(TAG, "onConnectFailed");
+            isConnectImFailed = true;
+            showLiveStatusView(LIVE_STATUS_ERROR);
+        }
+
+        @Override
+        public void onKickedOffline() {
+            super.onKickedOffline();
+            Log.i(TAG, "onKickedOffline");
+            finish();
+        }
+
+        @Override
+        public void onUserSigExpired() {
+            super.onUserSigExpired();
+            Log.i(TAG, "onUserSigExpired");
+            finish();
+        }
+
+        @Override
+        public void onSelfInfoUpdated(V2TIMUserFullInfo info) {
+            super.onSelfInfoUpdated(info);
+            Log.i(TAG, "onSelfInfoUpdated");
+        }
+
+        @Override
+        public void onUserStatusChanged(List<V2TIMUserStatus> userStatusList) {
+            super.onUserStatusChanged(userStatusList);
+
+            String myselfUserID = V2TIMManager.getInstance().getLoginUser();
+            for (V2TIMUserStatus item : userStatusList) {
+                Log.i(TAG, "onUserStatusChanged");
+                if (item.getUserID().equals(myselfUserID)) {
+                    // 自己的状态发生变更
+                    int statusType = item.getStatusType();
+                    Log.i(TAG, "onUserStatusChanged statusType:" + statusType);
+                    if (statusType == V2TIMUserStatus.V2TIM_USER_STATUS_OFFLINE) {
+
+                    }
+                } else {
+                    // 其他人的状态发生变更
+                }
+            }
+        }
+    };
+    private TTMessageAdapter mMessageAdapter;
+    private LinearLayoutManager mLinearLayoutManager;
+    private boolean isAutoScrollToLast = true;
+    private boolean anchorIsOnline = false;//主播是否在线
+    private LiveRoomCloseMicTipDialog mRoomCloseMicTipDialog;
+    private LiveRoomClosePageOnMicTipDialog mLiveRoomClosePageOnMicTipDialog;
+    private String subjectId;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected AcTtLiveroomLayoutBinding getLayoutView() {
+        return AcTtLiveroomLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected void initView() {
+        setStatusBarColor();
+        content_view = viewBinding.contentView;
+        mVideoView= viewBinding.videoView;
+        flVideoContainer= viewBinding.flVideoContainer;
+        csVideoContainer= viewBinding.csVideoContainer;
+        mGroupViews= viewBinding.groupViews;
+        mFlJoinBarrage= viewBinding.flJoinBarrage;
+        mIvClose = viewBinding.ivClose;
+        mFlSnapUpBarrage = viewBinding.flSnapUpBarrage;
+        mIvSwitchVideoOrientation = viewBinding.ivSwitchVideoOrientation;
+        mIvSwitchVideoOrientationFull = viewBinding.ivSwitchVideoOrientationFull;
+        cs_header_info = viewBinding.csHeaderInfo;
+        msgContainer = viewBinding.flRecyclerContainer;
+        tv_input = viewBinding.tvInput;
+        fl_input = viewBinding.flInput;
+        mRecyclerMsg = viewBinding.recyclerMsg;
+        mViewLiveStatus = viewBinding.viewLiveStatus.csRoot;
+        viewLiveCameraStatus = viewBinding.viewLiveStatus.csRoot;
+        mIvLiveStatusCameraCenterIcon = viewBinding.viewLiveCameraStatus.ivCameraCenterIcon;
+        mTvLiveCameraStatusTipText = viewBinding.viewLiveCameraStatus.tvLiveCameraStatusTipText;
+        mIvLiveStatusCenterIcon = viewBinding.viewLiveStatus.ivCenterIcon;
+        mTvLiveStatusTipText = viewBinding.viewLiveStatus.tvLiveStatusTipText;
+        mTvJoinBarrage = viewBinding.tvJoinBarrage;
+        mTvSnapUpBarrage = viewBinding.tvSnapUpBarrage;
+        mTvAddLikeCount = viewBinding.tvAddLikeCount;
+        mTvNumPeople = viewBinding.tvNumPeople;
+        iv_mic = viewBinding.ivMic;
+        mViewShopCarAnim = viewBinding.viewShopCarAnim;
+        mIvShopCar = viewBinding.ivShopCar;
+        mIvAvatar = viewBinding.ivAvatar;
+        mTvRoomCreateName = viewBinding.tvRoomAuthorName;
+        mIvVoiceSwitch = viewBinding.ivVoiceSwitch;
+        group_tip = viewBinding.viewLiveStatus.groupTip;
+        group_loading = viewBinding.viewLiveStatus.groupLoading;
+        tv_retry = viewBinding.viewLiveStatus.tvRetry;
+        tv_loading = viewBinding.viewLiveStatus.tvLoading;
+        mLlMicContainer = viewBinding.llMicContainer;
+        subVideoView = viewBinding.subVideoView;
+
+        mRoomId = getIntent().getStringExtra(ROOMID_KEY);
+        if (getIntent().hasExtra(SUBJECT_ID_KEY)) {
+            subjectId = getIntent().getStringExtra(SUBJECT_ID_KEY);
+        }
+        if (TextUtils.isEmpty(mRoomId)) {
+            ToastUtil.getInstance().show(this, "房间id不可为空");
+            finish();
+            return;
+        }
+        mMessageAdapter = new TTMessageAdapter(this);
+        mLinearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
+        mRecyclerMsg.setLayoutManager(mLinearLayoutManager);
+        mRecyclerMsg.setAdapter(mMessageAdapter);
+    }
+
+    public void setStatusBarColor() {
+        ImmersionBar.with(this)
+                .keyboardEnable(false)//为了防止软键盘顶起底部布局
+                .transparentStatusBar()
+                .statusBarDarkFont(false, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
+                .autoDarkModeEnable(false)
+                .flymeOSStatusBarFontColor(R.color.white)  //修改flyme OS状态栏字体颜色
+                .init();  //必须调用方可沉浸
+
+    }
+
+    @Override
+    public void initData() {
+        super.initData();
+        initIMSdk();
+        mUserId = UserHelper.getImUserId();
+        //创建 player 对象
+        mMLivePlayer = new V2TXLivePlayerImpl(this);
+        mMLivePlayer.setRenderFillMode(V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill);
+        // 设置画面渲染方向
+        mMLivePlayer.setRenderRotation(V2TXLiveRotation0);
+        //关键 player 对象与界面 view
+        mMLivePlayer.setRenderView(mVideoView);
+        mMLivePlayer.enableReceiveSeiMessage(true, TTLiveConfig.DEFAULT_PAYLOAD_TYPE);
+        presenter.init(this,mRoomId);
+        initListener();
+    }
+
+    private void initIMSdk() {
+        TCIMSdkManager.getInstance().init(getApplication());
+    }
+
+    private void initListener() {
+        initViewClickListener();
+        TCIMSdkManager.getInstance().addEventListener(mTIMSDKListener);
+
+        mRecyclerMsg.addOnScrollListener(new RecyclerView.OnScrollListener() {
+            @Override
+            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+                super.onScrollStateChanged(recyclerView, newState);
+                if (mLinearLayoutManager == null || mMessageAdapter == null) {
+                    return;
+                }
+                int lastCompletelyVisibleItemPosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
+                if (lastCompletelyVisibleItemPosition == mMessageAdapter.getMessageSize() - 1) {
+                    isAutoScrollToLast = true;
+                } else {
+                    isAutoScrollToLast = false;
+                }
+            }
+        });
+        mMLivePlayer.setObserver(new V2TXLivePlayerObserver() {
+            @Override
+            public void onError(V2TXLivePlayer player, int code, String msg, Bundle extraInfo) {
+                super.onError(player, code, msg, extraInfo);
+                Log.i("pq", "play error:code=" + code + "---msg:" + msg + "---Bundle:" + extraInfo.toString());
+                if (anchorIsOnline) {
+                    showLiveStatusView(LIVE_STATUS_ERROR);
+                }
+            }
+
+            @Override
+            public void onWarning(V2TXLivePlayer player, int code, String msg, Bundle extraInfo) {
+                super.onWarning(player, code, msg, extraInfo);
+                Log.i("pq", "play onWarning:code=" + code + "---msg:" + msg + "---Bundle:" + extraInfo.toString());
+            }
+
+            @Override
+            public void onConnected(V2TXLivePlayer player, Bundle extraInfo) {
+                super.onConnected(player, extraInfo);
+                Log.i("pq", "play onConnected:" + extraInfo.toString());
+            }
+
+            @Override
+            public void onRenderVideoFrame(V2TXLivePlayer player, V2TXLiveDef.V2TXLiveVideoFrame videoFrame) {
+                super.onRenderVideoFrame(player, videoFrame);
+                Log.i("pq", "play onRenderVideoFrame:" + videoFrame);
+                hideLiveStatus();
+            }
+
+            @Override
+            public void onVideoLoading(V2TXLivePlayer player, Bundle extraInfo) {
+                super.onVideoLoading(player, extraInfo);
+                Log.i("pq", "play onVideoLoading:" + extraInfo.toString());
+            }
+
+            @Override
+            public void onVideoPlaying(V2TXLivePlayer player, boolean firstPlay, Bundle extraInfo) {
+                super.onVideoPlaying(player, firstPlay, extraInfo);
+                Log.i("pq", "play onVideoPlaying:" + extraInfo.toString() + "---isFirstPlay:" + firstPlay);
+                hideLiveStatus();
+            }
+
+            @Override
+            public void onReceiveSeiMessage(V2TXLivePlayer player, int payloadType, byte[] data) {
+                super.onReceiveSeiMessage(player, payloadType, data);
+                Log.i("pq", "play onReceiveSeiMessage:length" + data.length + "---" + payloadType + "---data:" + new String(data));
+                if (data != null && data.length > 0) {
+                    parseSeiMessage(new String(data));
+                }
+            }
+
+            @Override
+            public void onStatisticsUpdate(V2TXLivePlayer player, V2TXLiveDef.V2TXLivePlayerStatistics statistics) {
+                super.onStatisticsUpdate(player, statistics);
+//                Log.i("pq", "play videoBitrate:" + statistics.videoBitrate);
+//                Log.i("pq", "play audioBitrate:" + statistics.audioBitrate);
+//                Log.i("pq", "play videoPacketLoss:" + statistics.videoPacketLoss);
+//                Log.i("pq", "play audioPacketLoss:" + statistics.audioPacketLoss);
+//                Log.i("pq", "play videoBlockRate:" + statistics.videoBlockRate);
+//                Log.i("pq", "play aul dioBlockRate:" + statistics.audioBlockRate);
+//                Log.i("pq", "play videoTotalBlockTime:" + statistics.videoTotalBlockTime);
+//                Log.i("pq", "play audioTotalBlockTime:" + statistics.audioTotalBlockTime);
+//                Log.i("pq", "play rtt:" + statistics.rtt);
+            }
+        });
+
+        mLlMicContainer.setOnEventListener(new TTLiveRoomMicIconView.OnEventListener() {
+            @Override
+            public void getUserInfoByUserId(String userId) {
+                if (presenter != null) {
+                    presenter.getUserInfoByUserId(userId);
+                }
+            }
+
+            @Override
+            public void onMicStatusUpdate(String userId, String currentMicStatus) {
+                boolean isOpen = !TextUtils.equals(currentMicStatus, TTLiveConfig.LIVE_ROOM_MIC_STATUS_ON_VALUE);
+                changeMicStatus(userId, isOpen);
+            }
+        });
+    }
+
+    private void changeMicStatus(String userId, boolean isOpenCloseMode) {
+        mLlMicContainer.post(new Runnable() {
+            @Override
+            public void run() {
+                if (isOpenCloseMode) {
+                    //开启闭麦模式
+                    mLlMicContainer.updateTargetUserMicStatus(userId, TTLiveConfig.LIVE_ROOM_MIC_STATUS_ON_VALUE);
+                    presenter.setMicrophoneDisable(true);
+                    presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_MIC_STATUS_CHANGE, mUserId, true);
+                } else {
+                    //关闭闭麦模式
+                    mLlMicContainer.updateTargetUserMicStatus(userId, TTLiveConfig.LIVE_ROOM_MIC_STATUS_OFF_VALUE);
+                    presenter.setMicrophoneDisable(false);
+                    presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_MIC_STATUS_CHANGE, mUserId, false);
+                }
+            }
+        });
+    }
+
+    private void parseSeiMessage(String s) {
+        try {
+            Log.i("pq", "parseSeiMessage:" + s);
+            LiveStatusSEMIMsg semiMsg = GsonUtils.fromJson(s, LiveStatusSEMIMsg.class);
+            List<LiveStatusSEMIMsg.UserStatusBean> seatUser = semiMsg.getSeatUser();
+            mLlMicContainer.refreshAll(seatUser);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void notifyMicContainerDel(String userId) {
+        mLlMicContainer.post(new Runnable() {
+            @Override
+            public void run() {
+                mLlMicContainer.deleteMicUser(userId);
+            }
+        });
+    }
+
+    private void notifyMicContainerAdd(String userId) {
+        Log.i("pq", "notifyMicContainerAdd:" + userId);
+        List<String> seatUser = new ArrayList<>();
+        seatUser.add(userId);
+        mLlMicContainer.addOnMicUser(seatUser);
+    }
+
+    private void hideLiveStatus() {
+        if (mViewLiveStatus != null) {
+            mViewLiveStatus.setVisibility(View.GONE);
+        }
+    }
+
+    private void hideLiveCameraStatus() {
+        if (viewLiveCameraStatus != null) {
+            viewLiveCameraStatus.setVisibility(View.GONE);
+        }
+    }
+
+    private void initViewClickListener(){
+        viewBinding.ivClose.setOnClickListener(this);
+        viewBinding.ivSwitchVideoOrientation.setOnClickListener(this);
+        viewBinding.flInput.setOnClickListener(this);
+        viewBinding.ivMic.setOnClickListener(this);
+        viewBinding.iconAddLike.setOnClickListener(this);
+        viewBinding.ivSwitchVideoOrientationFull.setOnClickListener(this);
+        viewBinding.viewLiveStatus.csRoot.setOnClickListener(this);
+        viewBinding.viewShopCarAnim.setOnClickListener(this);
+        viewBinding.flVideoContainer.setOnClickListener(this);
+        viewBinding.ivVoiceSwitch.setOnClickListener(this);
+        viewBinding.viewLiveStatus.tvRetry.setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View view) {
+        int id = view.getId();
+        if (id == viewBinding.viewLiveStatus.csRoot.getId()) {
+            return;
+        }
+        if (id == R.id.iv_close) {
+            if (currentSeatStatus != LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
+                showPageCloseOnMicTipDialog();
+            } else {
+                close();
+            }
+            return;
+        }
+        if (id == R.id.iv_switch_video_orientation) {
+            //切换横竖屏
+            if (UiUtils.isFastClick()) {
+                return;
+            }
+            if (mShopCarDialog != null && mShopCarDialog.isShowing()) {
+                return;
+            }
+            changeOrientation();
+            return;
+        }
+
+        if (id == R.id.iv_switch_video_orientation_full) {
+            //横屏切换竖屏
+            changeOrientation();
+            return;
+        }
+        if (id == R.id.fl_input) {
+            //底部输入框
+            showInputDialog();
+            return;
+        }
+        if (id == R.id.iv_mic) {
+            //连麦
+            toCheckMicPermission();
+            return;
+        }
+
+        if (id == R.id.icon_add_like) {
+            if (checkAddLikeMode()) {
+                return;
+            }
+            //点赞
+            LiveRoomAddLikeHelper.getInstance().handleClick(new LiveRoomAddLikeHelper.OnAddLikeResultCallBack() {
+                @Override
+                public void onResult(int count) {
+                    if (presenter != null) {
+                        presenter.updateGroupAddLike(mRoomId, count);
+//                        presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_ADD_LIKE_COUNT, count);
+                    }
+                }
+            });
+            LiveRoomAnimatorHelper.getInstance().startAddLikeAnimation(TCStudentLiveRoomActivity.this, content_view);
+            return;
+        }
+
+        if (id == R.id.view_shop_car_anim) {
+            if (liveIsFinish) {
+                ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
+                return;
+            }
+            //购物车
+            if (isFullScreen()) {
+                changeOrientation();
+                android.os.Message message = android.os.Message.obtain();
+                message.what = OPEN_SHOP_CAR_DIALOG;
+                mHandler.sendMessageDelayed(message, 500);
+            } else {
+                showShopCarDialog();
+            }
+            return;
+        }
+
+        if (id == R.id.fl_video_container) {
+            //点击隐藏头部信息
+            if (isFullScreen()) {
+                //全屏模式下
+                handleHeaderAnim();
+            }
+            return;
+        }
+
+        if (id == R.id.iv_voice_switch) {
+//            //静音
+            if (isMuteAll) {
+                this.isMuteAll = false;
+                mIvVoiceSwitch.setImageResource(R.drawable.icon_live_voice_on);
+                muteAll(false);
+            } else {
+                mIvVoiceSwitch.setImageResource(R.drawable.icon_live_voice_off);
+                this.isMuteAll = true;
+                muteAll(true);
+            }
+        }
+
+        if (id == R.id.tv_retry) {
+            play();
+            return;
+        }
+    }
+
+    @SuppressLint("CheckResult")
+    private void toCheckMicPermission() {
+        new RxPermissions(this)
+                .request(Manifest.permission.RECORD_AUDIO,
+                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
+                .subscribe(permission -> {
+                    if (permission) {
+                        handleMicClick();
+                    } else {
+                        DialogUtil.showInCenter(getSupportFragmentManager(), com.cooleshow.base.R.layout.common_popu, (holder, dialog) -> {
+                            TextView tvTitle = holder.getView(com.cooleshow.base.R.id.tv_title);
+                            TextView tvContent = holder.getView(com.cooleshow.base.R.id.tv_content);
+                            TextView btncancel = holder.getView(com.cooleshow.base.R.id.btn_cancel);
+                            TextView btnCommit = holder.getView(com.cooleshow.base.R.id.btn_commit);
+                            tvTitle.setText("提示");
+                            tvContent.setText("连麦需要麦克风、储存权限,去设置?");
+                            btncancel.setOnClickListener(view1 -> {
+                                dialog.dismiss();
+                            });
+                            btnCommit.setOnClickListener(view1 -> {
+                                PermissionUtils.toSelfSetting(getApplicationContext());
+                                dialog.dismiss();
+                            });
+                        });
+                    }
+                });
+    }
+
+    private void handleMicClick() {
+        if (!isOnMic()) {
+            //非连麦中才判断模式
+            if (checkMicMode()) {
+                return;
+            }
+            if (isConnectImFailed) {
+                //连接状态异常,暂停连麦
+                return;
+            }
+        }
+        showMicManagerDialog();
+    }
+
+    /**
+     * 是否静音全部
+     *
+     * @param isMute
+     */
+    private void muteAll(boolean isMute) {
+        mMLivePlayer.setPlayoutVolume(isMute ? 0 : 100);
+        if (presenter != null) {
+            presenter.muteTRTC(isMute);
+        }
+    }
+
+    private void showPageCloseOnMicTipDialog() {
+        if (mLiveRoomClosePageOnMicTipDialog == null) {
+            mLiveRoomClosePageOnMicTipDialog = new LiveRoomClosePageOnMicTipDialog(this);
+            mLiveRoomClosePageOnMicTipDialog.setConfirmClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    finish();
+                }
+            });
+        }
+        if (!mLiveRoomClosePageOnMicTipDialog.isShowing()) {
+            mLiveRoomClosePageOnMicTipDialog.show();
+        }
+        mLiveRoomClosePageOnMicTipDialog.setTitle("提示");
+        mLiveRoomClosePageOnMicTipDialog.setContent("连麦中,是否退出房间?");
+    }
+
+    private void close() {
+        //断开连接,结束页面
+        onBackPressed();
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (liveIsFinish) {
+            super.onBackPressed();
+            return;
+        }
+        if (isFullScreen()) {
+            changeOrientation();
+        } else {
+            boolean permissionOverlay = FloatWindowHelper.requestOverlayPermission(this);
+            if (!permissionOverlay) {
+                showOpenOverlayPermissionTipDialog();
+            } else {
+                showExitLiveTipDialog();
+            }
+        }
+    }
+
+    private void showOpenOverlayPermissionTipDialog() {
+        OpenOverlayPermissionTipDialog overlayPermissionTipDialog = new OpenOverlayPermissionTipDialog(this);
+        overlayPermissionTipDialog.setConfirmClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                overlayPermissionTipDialog.dismiss();
+                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
+                startActivityForResult(intent, FloatWindowHelper.REQUEST_OVERLAY_CODE);
+            }
+        });
+        overlayPermissionTipDialog.show();
+        overlayPermissionTipDialog.setCancelClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                overlayPermissionTipDialog.dismiss();
+                finish();
+            }
+        });
+    }
+
+    /**
+     * 退出直播间提示弹窗
+     */
+    private void showExitLiveTipDialog() {
+        LiveRoomExitTipDialog2 liveRoomExitTipDialog2 = new LiveRoomExitTipDialog2(this);
+        liveRoomExitTipDialog2.setConfirmClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finish();
+            }
+        });
+        liveRoomExitTipDialog2.show();
+    }
+
+    private void showInputDialog() {
+        if (roomInfo == null) {
+            return;
+        }
+        if (checkChatMode()) return;
+        if (mInputBarDialog == null) {
+            mInputBarDialog = new InputBarDialog(TCStudentLiveRoomActivity.this, new InputBar.InputBarListener() {
+                @Override
+                public boolean onClickSend(String message) {
+                    //发送消息
+                    if (checkChatMode()) {
+                        return false;
+                    }
+                    if (TextUtils.isEmpty(message)) {
+                        ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "消息不能为空");
+                        return false;
+                    }
+                    if (message.length() > TTLiveConfig.LIVE_MAX_INPUT_TEXT_LENGTH) {
+                        ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "聊天消息需在40个字以内哦");
+                        return false;
+                    }
+                    if (LiveMessageHelper.isQuickAction()) {
+                        ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您说话太快啦");
+                        return false;
+                    }
+                    sendTextMessage(message);
+                    return true;
+                }
+
+
+                @Override
+                public boolean onClickEmoji() {
+                    return false;
+                }
+            });
+
+            mInputBarDialog.setOnShowListener(new DialogInterface.OnShowListener() {
+                @Override
+                public void onShow(DialogInterface dialog) {
+                    if (mInputBarDialog != null) {
+                        mInputBarDialog.showInput();
+                    }
+                }
+            });
+        }
+        if (!mInputBarDialog.isShowing()) {
+            mInputBarDialog.show();
+        }
+    }
+
+    private void sendTextMessage(String message) {
+        presenter.sendTextMessage(message);
+    }
+
+    /**
+     * 检查点赞按钮是否可用
+     *
+     * @return
+     */
+    private boolean checkAddLikeMode() {
+        if (liveIsFinish) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
+            return true;
+        }
+
+//        if (isEnableAll) {
+//            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
+//            return true;
+//        }
+
+        if (isConnectImFailed) {
+            //连接状态异常,暂停点赞
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "网络连接状态异常");
+            return true;
+        }
+        return false;
+    }
+
+    private void changeOrientation() {
+        int currentOrientation = getCurrentOrientation();
+        boolean isNeedFullScreen = currentOrientation != Configuration.ORIENTATION_LANDSCAPE;
+        if (isNeedFullScreen) {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        } else {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        }
+    }
+
+    private void startFloatWindowService() {
+        boolean hasPermission = FloatWindowHelper.requestOverlayPermission(this);
+        if (hasPermission) {
+            Intent intent = new Intent(this, FloatingWindowService.class);
+            initServiceConnection();
+            intent.putExtra("isPc", isPcClientLive);
+            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+        }
+    }
+
+    private void initServiceConnection() {
+        if (serviceConnection == null) {
+            serviceConnection = new ServiceConnection() {
+                @Override
+                public void onServiceConnected(ComponentName name, IBinder service) {
+                    if (service instanceof FloatingWindowService.MyBinder) {
+                        FloatingWindowService.MyBinder mBinder = (FloatingWindowService.MyBinder) service;
+                        ArrayList<View> list = new ArrayList();
+                        list.add(getVideoView());
+                        mBinder.addTTVideoView(list);
+                        mBinder.setOnEventListener(new FloatingWindowService.OnEventListener() {
+                            @Override
+                            public void onServiceDestroy() {
+                                if (flVideoContainer != null) {
+                                    flVideoContainer.addView(getVideoView());
+                                }
+                            }
+
+                            @Override
+                            public void onUnbindService() {
+                                muteAll(true);
+                                unbindService();
+                            }
+                        });
+                    }
+                }
+
+                @Override
+                public void onServiceDisconnected(ComponentName name) {
+                    if (flVideoContainer != null) {
+                        flVideoContainer.addView(getVideoView());
+                    }
+                }
+            };
+        }
+    }
+
+    /**
+     * 销毁悬浮窗service
+     */
+    private void unbindService() {
+        if (serviceConnection != null) {
+            try {
+                boolean isExist = AppUtils.isServiceWork(this, FloatingWindowService.CLASS_PATH);
+                if (isExist) {
+                    unbindService(serviceConnection);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public View getVideoView() {
+        return csVideoContainer;
+    }
+
+
+    private boolean isFullScreen() {
+        return getCurrentOrientation() == Configuration.ORIENTATION_LANDSCAPE;
+    }
+
+
+    private int getCurrentOrientation() {
+        return getResources().getConfiguration().orientation;
+    }
+
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        //改变videoView容器布局尺寸
+        resetVideoContainer(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
+    }
+
+
+    private void resetVideoContainer(boolean isFullScreen) {
+        if (isFullScreen) {
+            if (isPcClientLive) {
+                //隐藏消息列表
+                mGroupViews.setVisibility(View.GONE);
+                mIvClose.setVisibility(View.GONE);
+                //隐藏弹幕消息
+                mFlJoinBarrage.clearAnimation();
+                mFlJoinBarrage.setVisibility(View.GONE);
+                mFlSnapUpBarrage.clearAnimation();
+                mFlSnapUpBarrage.setVisibility(View.GONE);
+                //隐藏竖屏全屏按钮
+                mIvSwitchVideoOrientation.setVisibility(View.GONE);
+                mIvSwitchVideoOrientationFull.setVisibility(View.VISIBLE);
+            } else {
+                //不是PC端直播
+                mIvSwitchVideoOrientation.setVisibility(View.GONE);
+                mIvSwitchVideoOrientationFull.setVisibility(View.GONE);
+            }
+            ConstraintSet set = new ConstraintSet();
+            set.clone(content_view);
+            set.clear(flVideoContainer.getId());
+            if (!isPcClientLive) {
+                //如果是非PC端直播,还需要设置下消息列表控件位置
+                set.clear(msgContainer.getId());
+                set.connect(msgContainer.getId(), ConstraintSet.TOP, R.id.view_center, ConstraintSet.BOTTOM, DensityUtil.dp2px(TCStudentLiveRoomActivity.this, 50));
+                set.connect(msgContainer.getId(), ConstraintSet.LEFT, content_view.getId(), ConstraintSet.LEFT, 0);
+                set.connect(msgContainer.getId(), ConstraintSet.RIGHT, content_view.getId(), ConstraintSet.RIGHT, 0);
+                set.connect(msgContainer.getId(), ConstraintSet.BOTTOM, fl_input.getId(), ConstraintSet.TOP, DensityUtil.dp2px(TCStudentLiveRoomActivity.this, 10));
+            }
+            set.connect(flVideoContainer.getId(), ConstraintSet.TOP, content_view.getId(), ConstraintSet.TOP, 0);
+            set.connect(flVideoContainer.getId(), ConstraintSet.LEFT, content_view.getId(), ConstraintSet.LEFT, 0);
+            set.connect(flVideoContainer.getId(), ConstraintSet.RIGHT, content_view.getId(), ConstraintSet.RIGHT, 0);
+            set.connect(flVideoContainer.getId(), ConstraintSet.BOTTOM, content_view.getId(), ConstraintSet.BOTTOM, 0);
+            set.applyTo(content_view);
+        } else {
+            //pc端直播,控制居中显示,以及videoview容器的宽高
+            if (cs_header_info.getTranslationY() != 0) {
+                //还原显示头部信息
+                handleHeaderAnim();
+            }
+            if (isPcClientLive) {
+                mGroupViews.setVisibility(View.VISIBLE);
+                mIvClose.setVisibility(View.VISIBLE);
+                mIvSwitchVideoOrientation.setVisibility(View.VISIBLE);
+                mIvSwitchVideoOrientationFull.setVisibility(View.GONE);
+            }
+
+            ConstraintSet set = new ConstraintSet();
+            set.clone(content_view);
+            set.clear(flVideoContainer.getId());
+            set.connect(flVideoContainer.getId(), ConstraintSet.TOP, cs_header_info.getId(), ConstraintSet.BOTTOM, DensityUtil.dp2px(TCStudentLiveRoomActivity.this, 121));
+            set.connect(flVideoContainer.getId(), ConstraintSet.LEFT, content_view.getId(), ConstraintSet.LEFT, 0);
+            set.connect(flVideoContainer.getId(), ConstraintSet.RIGHT, content_view.getId(), ConstraintSet.RIGHT, 0);
+            int maxHeightAtRatio16_9 = UiUtils.getMaxHeightAtRatio16_9(TCStudentLiveRoomActivity.this);
+            set.constrainHeight(flVideoContainer.getId(), maxHeightAtRatio16_9);
+            set.applyTo(content_view);
+        }
+    }
+
+    private void handleHeaderAnim() {
+        float animOffset = cs_header_info.getTranslationY();
+        if (animOffset == 0) {
+            //隐藏头部信息
+            int bottom = cs_header_info.getBottom();
+            if (hideHeaderInfoAnim == null) {
+                hideHeaderInfoAnim = ObjectAnimator.ofFloat(cs_header_info, "translationY", 0, -bottom);
+                hideHeaderInfoAnim.setDuration(500);
+            }
+            hideHeaderInfoAnim.start();
+        } else {
+            //显示头部信息
+            if (showHeaderInfoAnim == null) {
+                showHeaderInfoAnim = ObjectAnimator.ofFloat(cs_header_info, "translationY", animOffset, 0);
+                showHeaderInfoAnim.setDuration(500);
+            }
+            showHeaderInfoAnim.start();
+        }
+    }
+
+    /**
+     * 控制聊天模式
+     *
+     * @param isEnableChat
+     */
+    @Override
+    public void switchChatMode(boolean isEnableChat) {
+        //控制聊天模式
+        Log.i("pq", "聊天禁止:" + isEnableChat);
+        this.isEnableChat = isEnableChat;
+    }
+
+    @Override
+    public void changeMicControlMode(boolean isEnableMic) {
+        //禁止连麦模式
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        Log.i("pq", "receive mic mode control msg 禁麦模式:" + isEnableMic);
+        this.isEnableMic = isEnableMic;
+        if (isEnableMic && isOnApplyMic()) {
+            handleCloseMicEvent();
+        }
+    }
+
+    @Override
+    public void liveRoomOffline() {
+        //关闭直播间
+        ToastUtil.getInstance().show(this, "直播已结束");
+        this.liveIsFinish = true;
+        //取消连麦
+        if (mMicManagerDialog != null) {
+            mMicManagerDialog.dismiss();
+        }
+        presenter.exitRoom();
+        showLiveStatusView(LIVE_STATUS_IS_OFFLINE);
+        hideDialog();
+    }
+
+    @Override
+    public void receiveJoinMessage(TCUserEnterMessage joinRoomMessage) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (joinRoomMessage == null) {
+            return;
+        }
+        if (isCanShowBarrage()) {
+            mTvJoinBarrage.setText(getString(R.string.enter_live_tip_str, TTLiveHelper.getMessageName(joinRoomMessage)));
+            showBarrageViewAnim(mFlJoinBarrage);
+        }
+    }
+
+    /**
+     * 显示弹幕消息
+     */
+    private void showBarrageViewAnim(View targetView) {
+        if (mFlJoinBarrage.getVisibility() == View.VISIBLE || mFlSnapUpBarrage.getVisibility() == View.VISIBLE) {
+            return;
+        }
+        LiveRoomAnimatorHelper.getInstance().startBarrageViewAnimation(this, targetView);
+        hideBarrageView();
+    }
+
+    /**
+     * 隐藏弹幕消息
+     */
+    private void hideBarrageView() {
+        mHandler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                if (mFlJoinBarrage != null) {
+                    mFlJoinBarrage.setVisibility(View.GONE);
+                }
+                if (mFlSnapUpBarrage != null) {
+                    mFlSnapUpBarrage.setVisibility(View.GONE);
+                }
+            }
+        }, TTLiveConfig.LIVE_HIDE_BARRAGE_VIEW_TIME);
+    }
+
+    /**
+     * 判断是否显示弹幕消息
+     *
+     * @return
+     */
+    private boolean isCanShowBarrage() {
+        if (isFullScreen()) {
+            return false;
+        }
+        return mFlJoinBarrage.getVisibility() != View.VISIBLE && mFlSnapUpBarrage.getVisibility() != View.VISIBLE;
+    }
+
+    @Override
+    public void receiveSnapUpMessage(TCUserSnappingUpMessage onSnappingUpMessage) {
+        //收到抢购消息
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (onSnappingUpMessage == null) {
+            return;
+        }
+        if (isCanShowBarrage()) {
+            mTvSnapUpBarrage.setText(getString(R.string.live_snap_up_tip_str, TTLiveHelper.getMessageName(onSnappingUpMessage)));
+            showBarrageViewAnim(mFlSnapUpBarrage);
+        }
+    }
+
+    @Override
+    public void liveGoodsChange(String goodsContent) {
+        //直播间商品发生变化
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (mShopCarDialog != null) {
+            mShopCarDialog.changeGoods(goodsContent);
+        }
+    }
+
+    @Override
+    public void onAddLikeMessage(TCSyncAddLikeMessage addLikeMessage) {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (addLikeMessage == null) {
+            return;
+        }
+        SendUserInfo sendUserInfo = addLikeMessage.getSendUserInfo();
+        if (sendUserInfo != null && isOwn(sendUserInfo.getSendUserId())) {
+            return;
+        }
+//        if (addLikeMessage != null) {
+//            if (mTvAddLikeCount != null) {
+//                currentAddLikeCount = addLikeMessage.getCount();
+//                updateAddLikeCountView();
+//            }
+//        }
+    }
+
+    private void updateAddLikeCountView(long count) {
+        this.currentAddLikeCount = count;
+        if (mTvAddLikeCount != null) {
+            mTvAddLikeCount.setText(getString(R.string.live_room_add_like_count_str, LiveMemberHelper.getStarsCountText(currentAddLikeCount)));
+        }
+    }
+
+    @Override
+    public void syncMemberCount(int count) {
+        //同步成员数量
+        Log.i("pq", "syncMemberCount" + count);
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+//        setPeopleCount(String.valueOf(count));
+    }
+
+    public void setPeopleCount(String count) {
+        if (mTvNumPeople != null) {
+            mTvNumPeople.setText(String.format(Locale.getDefault(), "%s人", LiveMemberHelper.getMemberCountText(count)));
+        }
+    }
+
+    @Override
+    public void onUserKickOutMsg(TCKickOutUserMessage userKickOutMessage) {
+        //用户被踢出消息
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (userKickOutMessage == null || !isOwn(userKickOutMessage.getTargetId())) {
+            return;
+        }
+        String targetId = userKickOutMessage.getTargetId();
+        Log.i("pq", "receive kickOut msg targetId:" + targetId);
+        finish();
+    }
+
+    private boolean isOwn(String targetUserId) {
+        return TextUtils.equals(mUserId, targetUserId);
+    }
+
+    @Override
+    public void seatResponse(TCUserSeatResponseMessage rcUserSeatResponseMessage) {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (rcUserSeatResponseMessage == null || !isOwn(rcUserSeatResponseMessage.getAudienceId())) {
+            return;
+        }
+        if (rcUserSeatResponseMessage != null) {
+            int type = rcUserSeatResponseMessage.getType();
+            if (type == LiveRoomMsgConstants.MIC_RESPONSE_AGREE) {
+                //主播同意
+//                ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "主播同意连麦");
+                if (presenter != null) {
+                    presenter.joinMic(mUserId, roomInfo.getUserSig());
+                }
+                return;
+            }
+            if (type == LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE) {
+                //主播拒绝
+                updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
+                ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.create_refuse_seat_tip));
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void onInviteSeatMic(TCUserSeatApplyMessage seatApplyMessage) {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (seatApplyMessage == null || !isOwn(seatApplyMessage.getAudienceId())) {
+            return;
+        }
+        if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_INVITE_SEAT_BY_CREATE) {
+            //主讲人邀请观众上麦
+            showInviteSeatDialog();
+            return;
+
+        }
+        if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_CANCEL_INVITE_SEAT_BY_CREATE) {
+            //主讲人取消邀请观众上麦
+            if (mInviteSeatMicTipDialog != null) {
+                mInviteSeatMicTipDialog.dismiss();
+            }
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.create_recall_seat_invite_tip));
+            return;
+        }
+
+        if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_CREATE) {
+            //主讲人讲观众抱下麦
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "主讲人断开连麦");
+            if (presenter != null) {
+                presenter.exitRoom();
+            }
+        }
+    }
+
+    private void showShopCarDialog() {
+        if (mShopCarDialog == null) {
+            mShopCarDialog = new LiveRoomShopCarDialog(this);
+            mShopCarDialog.setOnEventListener(new LiveRoomShopCarDialog.OnEventListener() {
+                @Override
+                public void onOpenDetail(String url) {
+                    mShopCarDialog.dismiss();
+                    //发送XXX正在抢购消息
+                    presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_ON_SNAP_UP);
+//                    sendShowFloatWindowAction(SEND_JUMP_OTHER_PAGE_MSG);
+//                    ARouter.getInstance()
+//                            .build(ARouterConstace.ACTIVITY_HTML)
+//                            .withString(ARouterConstace.URL, url)
+//                            .withString(ARouterConstace.TITLE, "商品详情")
+//                            .navigation();
+                }
+            });
+        }
+        if (!mShopCarDialog.isShowing()) {
+            mShopCarDialog.show();
+        }
+        mShopCarDialog.setRoomId(mRoomId);
+    }
+
+    private void showInviteSeatDialog() {
+        if (mInviteSeatMicTipDialog == null) {
+            mInviteSeatMicTipDialog = new LiveRoomInviteSeatMicTipDialog(this);
+            mInviteSeatMicTipDialog.setCancelable(false);
+            mInviteSeatMicTipDialog.setCanceledOnTouchOutside(false);
+            mInviteSeatMicTipDialog.setViewClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (v.getId() == R.id.tv_sure) {
+                        //被邀请连麦->同意连麦
+                        if (presenter != null && roomInfo != null) {
+                            if (!checkMicMode2()) {
+                                presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_AGREE_RESPONSE, getSpeakerId(), getSpeakerName());
+                                presenter.joinMic(mUserId, roomInfo.getUserSig());
+                            }
+                        }
+                    }
+                    if (v.getId() == R.id.tv_cancel) {
+                        //被邀请连麦->拒绝连麦
+                        if (presenter != null) {
+                            presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_DISAGREE_RESPONSE, getSpeakerId(), getSpeakerName());
+                        }
+                        //重置一下连麦状态
+                        handleCloseMicEvent();
+                    }
+                    mInviteSeatMicTipDialog.dismiss();
+                }
+            });
+        }
+        if (!mInviteSeatMicTipDialog.isShowing()) {
+            mInviteSeatMicTipDialog.show();
+        }
+        String defaultNick = "主讲人";
+        if (roomInfo != null && !TextUtils.isEmpty(roomInfo.speakerName)) {
+            defaultNick = roomInfo.speakerName;
+        }
+        mInviteSeatMicTipDialog.setContent(defaultNick);
+    }
+
+    @Override
+    public void onUserUnusualLogout(TCUserLogOutUnNormalMessage loginOutUnusualMessage) {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (loginOutUnusualMessage == null || !isOwn(loginOutUnusualMessage.getTargetId())) {
+            return;
+        }
+        ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播加载异常,请退出重试");
+        Log.i("pq", "unusual logout");
+        finish();
+    }
+
+    @Override
+    public void showLoading() {
+        showLiveStatusView(LIVE_STATUS_LOADING);
+    }
+
+    @Override
+    public void hideLoading() {
+        hideLiveStatus();
+    }
+
+    @Override
+    public void onLivePause() {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        showLiveStatusView(LIVE_STATUS_IS_REST);
+        this.liveIsPause = true;
+//        ToastUtil.getInstance().show(this, getString(R.string.live_is_pause_str));
+        handleCloseMicEvent();
+        if (mMicManagerDialog != null) {
+            mMicManagerDialog.dismiss();
+        }
+    }
+
+    @Override
+    public void changeBlackUserStatus(String userId, boolean isAddBlack) {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (isOwn(userId)) {
+            isEnableAll = isAddBlack;
+            if (isEnableAll) {
+                //取消连麦
+                if (currentSeatStatus != LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
+                    handleCloseMicEvent();
+                }
+            }
+            updateInputTip();
+        }
+    }
+
+    private void updateInputTip() {
+        if (tv_input == null) {
+            return;
+        }
+        if (isEnableAll) {
+            tv_input.setText(getString(R.string.unable_input_tip_str));
+        } else {
+            tv_input.setText(getString(R.string.live_input_tips_str));
+        }
+    }
+
+    @Override
+    public void onUnderAllMic() {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (isOnMic()) {
+            if (presenter != null) {
+                presenter.exitRoom();
+            }
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.down_mic_by_create_tip));
+            if (presenter != null && roomInfo != null) {
+                presenter.buildUnderMicResponseMessage(mUserId, roomInfo.speakerId, roomInfo.speakerName);
+            }
+        }
+    }
+
+
+    @Override
+    public void onRefuseAllMicApply() {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (mMicManagerDialog != null) {
+            mMicManagerDialog.dismiss();
+        }
+        if (isOnApplyMic()) {
+            updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.create_refuse_seat_tip));
+            if (roomInfo != null) {
+                presenter.buildResponseMessage(mUserId, roomInfo.speakerId, roomInfo.speakerName);
+            }
+        }
+    }
+
+    @Override
+    public void onUserStartPublish() {
+        if (!checkActivityExist()) {
+            return;
+        }
+    }
+
+    @Override
+    public void enterLiveRoomSuccess() {
+        //重置记录状态,等待回调触发准确值
+        hasMainStream = false;
+        hasSubStream = false;
+        if (mMLivePlayer != null) {
+            mMLivePlayer.stopPlay();
+        }
+        config3AParamsIfNeed();
+        muteAll(isMuteAll);
+        updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS);
+        if (mMicManagerDialog != null) {
+            mMicManagerDialog.dismiss();
+        }
+        presenter.startPublish(mUserId);
+        notifyMicContainerAdd(mUserId);
+        changeMicStatus(mUserId, isMuteAllMic);
+    }
+
+    private void config3AParamsIfNeed() {
+        if (!TextUtils.isEmpty(subjectId)) {
+            presenter.config3AParamsFromSubject(subjectId);
+        }
+    }
+
+    private boolean hasMainStream = false;//是否有主路流
+    private boolean hasSubStream = false;//是否有辅路流
+
+    @Override
+    public void onUserVideoAvailable(String userId, boolean available) {
+        if (TextUtils.equals(userId, getSpeakerId())) {
+            Log.i(TAG, "onUserVideoAvailable:" + available);
+            hasMainStream = available;
+            startRemote();
+        }
+    }
+
+    @Override
+    public void onUserSubStreamAvailable(String userId, boolean available) {
+        if (TextUtils.equals(userId, getSpeakerId())) {
+            Log.i(TAG, "onUserSubStreamAvailable:" + available);
+            hasSubStream = available;
+            startRemote();
+        }
+    }
+
+
+    public void startRemote() {
+        if (hasMainStream && hasSubStream) {
+            //主辅流都有的情况
+            subVideoView.setVisibility(View.VISIBLE);
+            presenter.startMainRemoteView(getSpeakerId(), isPcClientLive, subVideoView);
+            presenter.startSubRemoteView(getSpeakerId(), isPcClientLive, mVideoView);
+            return;
+        }
+        if (hasMainStream) {
+            //主流情况
+            subVideoView.setVisibility(View.GONE);
+            presenter.stopSubRemoteView(getSpeakerId());
+
+            presenter.startMainRemoteView(getSpeakerId(), isPcClientLive, mVideoView);
+            return;
+        }
+        if (hasSubStream) {
+            //单辅流情况
+            subVideoView.setVisibility(View.GONE);
+            presenter.stopMainRemoteView(getSpeakerId());
+            presenter.startSubRemoteView(getSpeakerId(), isPcClientLive, mVideoView);
+            return;
+        }
+    }
+
+    @Override
+    public void enterLiveRoomError() {
+
+    }
+
+    @Override
+    public void onExitRoomSuccess() {
+        Log.i("pq", "onExitRoomSuccess");
+        currentSeatStatus = LiveRoomMsgConstants.MIC_STATUS_NORMAL;
+        updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
+        if (!TextUtils.isEmpty(mUserId)) {
+            notifyMicContainerDel(mUserId);
+        }
+        if (presenter != null) {
+            presenter.stopAllRemoteView(getSpeakerId());
+            presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_DOWN_SEAT_MIC);
+        }
+        play();
+    }
+
+    @Override
+    public void onStopPublishing() {
+
+    }
+
+    @Override
+    public void onPublishSuccess() {
+        updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS);
+        if (mMicManagerDialog != null) {
+            mMicManagerDialog.dismiss();
+        }
+    }
+
+    @Override
+    public void onRemoteUserEnterRoom(String userId) {
+        if (!TextUtils.equals(userId, getSpeakerId())) {
+            Log.i("pq", "onRemoteUserEnterRoom:" + userId);
+            notifyMicContainerAdd(userId);
+        }
+    }
+
+    @Override
+    public void onRemoteUserLeaveRoom(String userId, int reason) {
+        if (!TextUtils.equals(userId, getSpeakerId())) {
+            Log.i("pq", "onRemoteUserLeaveRoom:" + userId);
+            notifyMicContainerDel(userId);
+        }
+    }
+
+    @Override
+    public void onStatistics(TRTCStatistics statistics) {
+
+    }
+
+    @Override
+    public void getFriendInfoSuccess(FriendInfoBean friendInfoBean) {
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (mLlMicContainer != null && friendInfoBean != null) {
+            String friendAvatar = "";
+            if (friendInfoBean.friend != null) {
+                friendAvatar = friendInfoBean.friend.avatar;
+            }
+            mLlMicContainer.updateTargetUserInfo(new TTUserInfo(friendInfoBean.friendId, friendInfoBean.friendNickname, !TextUtils.isEmpty(friendAvatar) ? Uri.parse(friendAvatar) : null));
+        }
+    }
+
+    @Override
+    public void receiveSEIMsg(String userId, byte[] data) {
+        if (TextUtils.equals(userId, getSpeakerId())) {
+//            parseSeiMessage(new String(data));
+        }
+    }
+
+    @Override
+    public void onGroupAttributeChanged(String groupID, Map<String, String> groupAttributeMap) {
+        if (TextUtils.equals(groupID, mRoomId)) {
+            JSONObject jsonObject = new JSONObject(groupAttributeMap);
+            parseGroupAttribute(jsonObject);
+        }
+    }
+
+    @Override
+    public void onGroupCounterChanged(String groupID, String key, long newValue) {
+        if (TextUtils.equals(groupID, mRoomId)) {
+            if (TextUtils.equals(TTLiveConfig.LIVE_ROOM_LIKES_KEY, key)) {
+                //点赞数同步
+                Log.i("pq", "likes newValue:" + newValue);
+                updateAddLikeCountView(newValue);
+            }
+        }
+    }
+
+    @Override
+    public void getAllGroupCounterSuccess(Map<String, Long> map) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (map != null && map.size() > 0) {
+            //获取群点赞数
+            if (map.containsKey(TTLiveConfig.LIVE_ROOM_LIKES_KEY)) {
+                Long result = map.get(TTLiveConfig.LIVE_ROOM_LIKES_KEY);
+                if (result != null) {
+                    updateAddLikeCountView(result);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onMicStatusControl(String userId, boolean muteMic) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (!isOwn(userId)) {
+            return;
+        }
+        ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, muteMic ? "主讲人已将您的麦克风关闭" : "主讲人已将您的麦克风开启");
+        changeMicStatus(userId, muteMic);
+    }
+
+    @Override
+    public void onUserAudioAvailable(String userId, boolean available) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (mLlMicContainer != null) {
+            mLlMicContainer.updateTargetUserMicStatus(userId, available ? TTLiveConfig.LIVE_ROOM_MIC_STATUS_OFF_VALUE : TTLiveConfig.LIVE_ROOM_MIC_STATUS_ON_VALUE);
+        }
+    }
+
+    @Override
+    public void onLiveForceKick(TCLiveForceKickMessage messageContent) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (messageContent != null) {
+            ArrayList<String> targetIds = messageContent.getTargetIds();
+            if (targetIds != null && targetIds.size() > 0) {
+                //判断个人
+                for (int i = 0; i < targetIds.size(); i++) {
+                    boolean isContainerOwner = isOwn(targetIds.get(i));
+                    if (isContainerOwner) {
+                        liveRoomOffline();
+                        showLiveCourseStatusChangeTip(messageContent.getReason());
+                        return;
+                    }
+                }
+            } else {
+                //全体
+                liveRoomOffline();
+                showLiveCourseStatusChangeTip(messageContent.getReason());
+            }
+        }
+    }
+
+    private void showLiveCourseStatusChangeTip(String tip) {
+        if (TextUtils.isEmpty(tip)) {
+            tip = "当前课程已调整,请退出直播间";
+        }
+        CommonConfirmDialog confirmDialog = new CommonConfirmDialog(this);
+        confirmDialog.show();
+        confirmDialog.setOnConfirmClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finish();
+            }
+        });
+        confirmDialog.setContent(tip);
+        confirmDialog.hideCancel();
+        confirmDialog.setCancelable(false);
+        confirmDialog.setCanceledOnTouchOutside(false);
+    }
+
+    @Override
+    public void getAllGroupAttributesSuccess(Object o) {
+        Log.i("pq", "getAllGroupAttributesSuccess:" + o.toString());
+        if (o == null) {
+            return;
+        }
+        try {
+            JSONObject jsonObject = new JSONObject(o.toString());
+            parseGroupAttribute(jsonObject);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private void parseGroupAttribute(JSONObject groupAttributeJson) {
+        Log.i("pq", "group:" + groupAttributeJson.toString());
+        if (groupAttributeJson != null) {
+            //主播状态
+            checkAnchorStatus(groupAttributeJson);
+//            //点赞数
+//            getLikesFromAttributes(groupAttributeJson);
+            //人数
+            getMemberCountFromAttributes(groupAttributeJson);
+            //全局禁言状态
+            getGlobalBanStatus(groupAttributeJson);
+            //全员闭麦模式
+            getMuteAllMicStatus(groupAttributeJson);
+        }
+    }
+
+    private void getMuteAllMicStatus(JSONObject groupAttributeJson) {
+        String muteAllMicStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_MIC_STATUS_MODE_KEY);
+        if (!TextUtils.isEmpty(muteAllMicStatus)) {
+            Log.i("pq", " groupAttribute muteAllMicStatus:" + muteAllMicStatus);
+            boolean result = TextUtils.equals(muteAllMicStatus, TTLiveConfig.STATUS_ON);
+            if (result != isMuteAllMic) {
+                //有变化
+                if (isOnMic()) {
+                    changeMicStatus(mUserId, result);
+                    ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, result ? "主讲人已将您的麦克风关闭" : "主讲人已将您的麦克风开启");
+                }
+            }
+            isMuteAllMic = result;
+        }
+    }
+
+    private void getGlobalBanStatus(JSONObject groupAttributeJson) {
+        String globalBanStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_GLOBAL_BAN_KEY);
+        if (!TextUtils.isEmpty(globalBanStatus)) {
+            Log.i("pq", " groupAttribute globalBanStatus:" + globalBanStatus);
+            if (TextUtils.equals(globalBanStatus, TTLiveConfig.STATUS_ON)) {
+                //全局禁言开启
+                isEnableChat = true;
+            } else {
+                isEnableChat = false;
+            }
+        }
+    }
+
+    private void getCameraStatus(JSONObject groupAttributeJson) {
+        String cameraStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_ANCHOR_CAMERA_KEY);
+        if (!TextUtils.isEmpty(cameraStatus)) {
+            Log.i("pq", " groupAttribute cameraStatus:" + cameraStatus);
+            if (TextUtils.equals(cameraStatus, TTLiveConfig.STATUS_OFF)) {
+                //主播关闭摄像头
+                showLiveStatusView(LIVE_STATUS_IS_CLOSE_VIDEO);
+            } else {
+                hideLiveCameraStatus();
+            }
+        }
+    }
+
+    private void getMemberCountFromAttributes(JSONObject groupAttributeMap) {
+        String member_online = groupAttributeMap.optString(TTLiveConfig.LIVE_ROOM_MEMBER_ONLINE_KEY);
+        Log.i("pq", "member_online:" + member_online);
+        if (!TextUtils.isEmpty(member_online)) {
+            setPeopleCount(member_online);
+        }
+    }
+
+    private void getLikesFromAttributes(JSONObject groupAttributeJson) {
+        String likes = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_LIKES_KEY);
+        Log.i("pq", "likes:" + likes);
+        if (!TextUtils.isEmpty(likes)) {
+            try {
+                int i = Integer.parseInt(likes);
+                updateAddLikeCountView(i);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        }
+    }
+
+    private void checkAnchorStatus(JSONObject groupAttributeJson) {
+        if (liveIsFinish) {
+            return;
+        }
+        String anchorStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_LIVE_STATUS_KEY);
+        Log.i("pq", "checkAnchorStatus:" + anchorStatus);
+        if (TextUtils.isEmpty(anchorStatus)) {
+            return;
+        }
+        if (TextUtils.equals(anchorStatus, TTLiveConfig.STATUS_ON)) {
+            //如果在线
+            anchorIsOnline = true;
+            TCStudentLiveRoomActivity.this.liveIsPause = false;
+            play();
+            //主播摄像头状态
+            getCameraStatus(groupAttributeJson);
+        } else {
+            //不在线
+            anchorIsOnline = false;
+            showLiveStatusView(LIVE_STATUS_IS_REST);
+            mLlMicContainer.delAll();
+            handleCloseMicEvent();
+        }
+    }
+
+    private void updateMicIcon(int micStatus) {
+        //主线程更新
+        iv_mic.post(new Runnable() {
+            @Override
+            public void run() {
+                currentSeatStatus = micStatus;
+                if (micStatus == LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
+                    iv_mic.setImageResource(R.drawable.icon_mic_unconnect);
+                }
+                if (micStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING) {
+                    iv_mic.setImageResource(R.drawable.icon_mic_connecting);
+                }
+                if (micStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS) {
+                    iv_mic.setImageResource(R.drawable.icon_mic_conected);
+                }
+            }
+        });
+    }
+
+    /**
+     * 关闭一些交互弹窗
+     */
+    private void hideDialog() {
+        //关闭邀请弹窗
+        if (mInviteSeatMicTipDialog != null && mInviteSeatMicTipDialog.isShowing()) {
+            mInviteSeatMicTipDialog.dismiss();
+        }
+        //关闭商品弹窗
+        if (mShopCarDialog != null && mShopCarDialog.isShowing()) {
+            mShopCarDialog.dismiss();
+        }
+    }
+
+    private void showLiveStatusView(int status) {
+        Log.i("pq", "showLiveStatusView:" + status);
+        if (isFinishing() || isDestroyed()) {
+            return;
+        }
+        if (mViewLiveStatus == null) {
+            return;
+        }
+        //显示视频画面已经关闭页面
+        mViewLiveStatus.post(new Runnable() {
+            @Override
+            public void run() {
+                mViewLiveStatus.setVisibility(status == LIVE_STATUS_IS_CLOSE_VIDEO ? View.GONE : View.VISIBLE);
+                if (status == LIVE_STATUS_IS_REST) {
+                    group_loading.setVisibility(View.GONE);
+                    tv_retry.setVisibility(View.GONE);
+                    group_tip.setVisibility(View.VISIBLE);
+                    hideLiveCameraStatus();
+                    stopPlay();
+                    mIvLiveStatusCenterIcon.setImageResource(R.drawable.icon_live_room_rest_bg);
+                    mTvLiveStatusTipText.setText("休息一下,马上回来!");
+                    mTvLiveStatusTipText.setTextSize(12);
+                    mTvLiveStatusTipText.setBackgroundResource(R.drawable.shape_gray_14dp);
+                } else if (status == LIVE_STATUS_IS_CLOSE_VIDEO) {
+                    viewLiveCameraStatus.setVisibility(View.VISIBLE);
+                    mIvLiveStatusCameraCenterIcon.setImageResource(R.drawable.icon_live_room_close_video);
+                    mTvLiveCameraStatusTipText.setText("主讲人已关闭画面!");
+                    mTvLiveCameraStatusTipText.setTextSize(12);
+                    mTvLiveCameraStatusTipText.setBackgroundResource(R.drawable.shape_gray_14dp);
+                } else if (status == LIVE_STATUS_IS_OFFLINE) {
+                    group_loading.setVisibility(View.GONE);
+                    tv_retry.setVisibility(View.GONE);
+                    group_tip.setVisibility(View.VISIBLE);
+                    hideLiveCameraStatus();
+                    stopPlay();
+                    mLlMicContainer.delAll();
+                    mIvLiveStatusCenterIcon.setImageResource(R.drawable.icon_live_end_tip);
+                    mTvLiveStatusTipText.setText("直播已结束!");
+                    mTvLiveStatusTipText.setTextSize(14);
+                    mTvLiveStatusTipText.setBackgroundColor(Color.TRANSPARENT);
+                } else if (status == LIVE_STATUS_LOADING) {
+                    group_loading.setVisibility(View.VISIBLE);
+                    group_tip.setVisibility(View.GONE);
+                    tv_retry.setVisibility(View.GONE);
+                    tv_loading.setText("视频加载中");
+                } else if (status == LIVE_STATUS_ERROR) {
+                    group_loading.setVisibility(View.GONE);
+                    tv_retry.setVisibility(View.VISIBLE);
+                    group_tip.setVisibility(View.VISIBLE);
+                    hideLiveCameraStatus();
+                    stopPlay();
+                    mIvLiveStatusCenterIcon.setImageResource(R.drawable.icon_live_room_close_video);
+                    mTvLiveStatusTipText.setText("视频加载失败");
+                    mTvLiveStatusTipText.setTextSize(14);
+                    mTvLiveStatusTipText.setBackgroundResource(R.drawable.shape_gray_14dp);
+                }
+            }
+
+        });
+    }
+
+
+    private void stopPlay() {
+        if (mMLivePlayer != null) {
+            mMLivePlayer.stopPlay();
+        }
+    }
+
+    /**
+     * 取消连麦
+     */
+    private void handleCloseMicEvent() {
+        if (currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING) {
+            //连接中取消连接
+            if (presenter != null) {
+                presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_APPLY, getSpeakerId(), getSpeakerName());
+                updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
+            }
+        }
+        if (currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS) {
+            if (presenter != null) {
+                presenter.exitRoom();
+            }
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        this.isOnResume = true;
+        unbindService();
+        //取消全部静音
+        if (!isMuteAll) {
+            muteAll(false);
+        }
+//        if (mMLivePlayer != null) {
+//            mMLivePlayer.resumeAudio();
+//            mMLivePlayer.resumeVideo();
+//        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        isOnResume = false;
+        sendShowFloatWindowAction(SEND_APP_BACKGROUND_MSG);
+//        if (mMLivePlayer != null) {
+//            mMLivePlayer.pauseVideo();
+//            mMLivePlayer.pauseAudio();
+//        }
+    }
+
+    private void sendShowFloatWindowAction(int what) {
+        android.os.Message message = android.os.Message.obtain();
+        message.what = what;
+        mHandler.sendMessageDelayed(message, SEND_SHOW_FLOAT_WINDOW_TIME);
+    }
+
+
+    @Override
+    protected TTLiveRoomPresenter createPresenter() {
+        return new TTLiveRoomPresenter();
+    }
+
+
+    @Override
+    public void getRoomInfoSuccess(LiveRoomInfoBean roomInfo) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (roomInfo != null) {
+            this.roomInfo = roomInfo;
+            LOG.i(TAG,"getRoomInfoSuccess:"+roomInfo.toString());
+            String userSig = roomInfo.getUserSig();
+            if (!TextUtils.isEmpty(userSig)) {
+                presenter.connectIM(mUserId, userSig);
+//                play();
+            }
+            isPcClientLive = TextUtils.equals(roomInfo.getOs(), "pc") || TextUtils.equals(roomInfo.getOs(), "client");
+            mMLivePlayer.setRenderFillMode(isPcClientLive ? V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit : V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill);
+            resetVideoContainer(!isPcClientLive);
+
+//            if (!TextUtils.isEmpty(roomInfo.roomConfig)) {
+//                try {
+//                    JSONObject jsonObject = new JSONObject(roomInfo.roomConfig);
+//                    //聊天模式
+//                    int chatCtrlMode = jsonObject.optInt("whether_chat", 0);
+//                    //连麦模式
+//                    int micCtrlMode = jsonObject.optInt("whether_mic", 0);
+//                    //购物车是否显示
+//                    int shopCarMode = jsonObject.optInt("whether_view_shop_cart", 0);
+//                    isEnableChat = chatCtrlMode == 1;
+//                    isEnableMic = micCtrlMode == 1;
+//
+//                    if (shopCarMode == 1) {
+//                        //隐藏购物车
+//                        mViewShopCarAnim.setVisibility(View.GONE);
+//                        mIvShopCar.setVisibility(View.GONE);
+//                    } else {
+//                        //显示购物车
+//                        mViewShopCarAnim.setVisibility(View.VISIBLE);
+//                        mIvShopCar.setVisibility(View.INVISIBLE);
+//                    }
+//                } catch (JSONException e) {
+//                    e.printStackTrace();
+//                }
+//            }
+            //黑名单模式
+            isEnableAll = roomInfo.blacklistFlag == 1;//1是黑名单 0否
+            updateInputTip();
+            updateAddLikeCountView(roomInfo.likeNum);
+
+            if (mTvNumPeople != null) {
+//                int peopleCount = roomInfo.lookNum + 1;//加上自己
+                setPeopleCount(String.valueOf(roomInfo.lookNum));
+            }
+            if (mIvAvatar != null) {
+                //创建人头像
+                Glide.with(TCStudentLiveRoomActivity.this).load(roomInfo.speakerPic).placeholder(R.drawable.icon_default_head).error(R.drawable.icon_default_head).into(mIvAvatar);
+            }
+            if (mTvRoomCreateName != null) {
+                //创建人昵称
+                mTvRoomCreateName.setText(roomInfo.speakerName);
+            }
+
+            if (mMessageAdapter != null) {
+                mMessageAdapter.setRoomAuthorId(roomInfo.speakerId);
+            }
+        }
+    }
+
+    @Override
+    public void getRoomInfoError(Throwable throwable) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        finish();
+    }
+
+    @Override
+    public void connectIMError(int errorCode, String errorMsg) {
+        hideLoading();
+        ToastUtil.getInstance().show(this, "加入直播间群聊异常,请退出重试");
+    }
+
+    @Override
+    public void loginIMSuccess() {
+        if (presenter != null) {
+            presenter.joinGroup(mRoomId);
+        }
+    }
+
+    @Override
+    public void joinGroupSuccess() {
+        hideLoading();
+        presenter.bindGroupListener();
+        presenter.getAllGroupAttributes(mRoomId);
+        presenter.getAllGroupCounter(mRoomId);
+        presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_JOIN_ROOM);
+        presenter.notifyJoinRoomAction(mRoomId, mUserId);
+    }
+
+    private void play() {
+        if (roomInfo != null && roomInfo.getLiveRoomConfig() != null) {
+            if (isOnMic()) {
+                return;
+            }
+            if (liveIsPause || liveIsFinish || !anchorIsOnline) {
+                return;
+            }
+            if (mMLivePlayer.isPlaying() == 1) {
+                return;
+            }
+            //关键 player 对象与界面 view
+            mMLivePlayer.setRenderView(mVideoView);
+            LiveRoomInfoBean.LiveRoomConfigBean liveRoomConfig = roomInfo.getLiveRoomConfig();
+            String playUrl = getPlayUrl(liveRoomConfig.getPlayUrl(), roomInfo.getRoomId(), roomInfo.speakerImUserId);
+            Log.i("pq", "playUrl:" + playUrl);
+            showLiveStatusView(LIVE_STATUS_LOADING);
+            subVideoView.setVisibility(View.GONE);
+            mMLivePlayer.startLivePlay(playUrl);
+        }
+    }
+
+    private String getPlayUrl(String domain, String roomId, String targetId) {
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("rtmp://")
+                .append(domain)
+                .append("/live/")
+                .append(roomId)
+                .append("_")
+                .append(targetId);
+//        String url = "rtmp://cdn1.dayaedu.com/live/12233333_LIVE?12233333_LIVE";
+        return stringBuilder.toString();
+    }
+
+    @Override
+    public void joinGroupError(int code, String des) {
+        hideLoading();
+        Log.i(TAG, "joinGroupError code:" + code + "des" + des);
+        ToastUtil.getInstance().show(this, "加入直播群组失败,请退出重试");
+    }
+
+    @Override
+    public void addMessageContent(TTMessage ttMessage) {
+        //添加单条消息至页面
+        Log.i("pq", "收到需要显示msg:" + ttMessage);
+        //只处理直播间消息,以及本直播间消息
+        if (mMessageAdapter != null) {
+            mMessageAdapter.addMessage(ttMessage);
+            if (mRecyclerMsg != null && mLinearLayoutManager != null) {
+                mRecyclerMsg.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (isAutoScrollToLast) {
+                            if (mRecyclerMsg != null) {
+                                mRecyclerMsg.scrollToPosition(mMessageAdapter.getItemCount() - 1);
+                            }
+                        } else {
+                            Log.i("pq", "收到消息,不自动滚动");
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    private boolean isOnApplyMic() {
+        return currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING;
+    }
+
+    private boolean isOnMic() {
+        return currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS;
+    }
+
+    private void showMicManagerDialog() {
+        if (mMicManagerDialog == null) {
+            mMicManagerDialog = new LiveRoomMicManagerDialog(this);
+            mMicManagerDialog.setOnEventListener(new LiveRoomMicManagerDialog.OnEventListener() {
+                @Override
+                public void onApplyMic() {
+                    //申请连麦
+                    handleMicEvent();
+                    mMicManagerDialog.setMicStatus(LiveRoomMsgConstants.MIC_STATUS_CONNECTING);
+                    mMicManagerDialog.dismiss();
+                }
+
+                @Override
+                public void onApplyCancel() {
+                    //取消申请连麦
+                    handleMicEvent();
+                }
+
+                @Override
+                public void onCloseMic() {
+                    //关闭连麦
+                    handleMicEvent();
+                }
+            });
+        }
+        if (!mMicManagerDialog.isShowing()) {
+            mMicManagerDialog.show();
+        }
+        if (roomInfo != null) {
+            mMicManagerDialog.setLiveTeacherInfo(roomInfo.speakerPic);
+        }
+        mMicManagerDialog.setMicStatus(currentSeatStatus);
+    }
+
+    private void handleMicEvent() {
+        if (currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
+            //未连麦状态 申请连麦
+            if (presenter != null) {
+                presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_SEAT_APPLY, getSpeakerId(), getSpeakerName());
+            }
+            updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_CONNECTING);
+        } else {
+            //取消连麦
+            showCloseMicTipDialog();
+        }
+    }
+
+    public String getSpeakerId() {
+        if (roomInfo != null) {
+            return roomInfo.speakerId;
+        }
+        return "";
+    }
+
+    public String getSpeakerName() {
+        if (roomInfo != null) {
+            return roomInfo.speakerName;
+        }
+        return "";
+    }
+
+    private void showCloseMicTipDialog() {
+        if (mRoomCloseMicTipDialog == null) {
+            mRoomCloseMicTipDialog = new LiveRoomCloseMicTipDialog(this);
+            mRoomCloseMicTipDialog.setConfirmClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    handleCloseMicEvent();
+                    mRoomCloseMicTipDialog.dismiss();
+                    if (mMicManagerDialog != null) {
+                        mMicManagerDialog.dismiss();
+                    }
+                }
+            });
+        }
+        if (!mRoomCloseMicTipDialog.isShowing()) {
+            mRoomCloseMicTipDialog.show();
+        }
+        mRoomCloseMicTipDialog.setContent(getString(currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING ? R.string.cancel_seat_on_connecting : R.string.cancel_seat_on_connected));
+    }
+
+    /**
+     * 检查聊天模式
+     */
+    public boolean checkChatMode() {
+        if (liveIsFinish) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
+            return true;
+        }
+        if (isEnableAll) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
+            return true;
+        }
+        if (isEnableChat) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "管理员关闭聊天");
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 检查mic模式
+     */
+    public boolean checkMicMode() {
+        if (!anchorIsOnline) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
+            return true;
+        }
+        if (liveIsPause) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
+            return true;
+        }
+        if (liveIsFinish) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
+            return true;
+        }
+        if (isEnableAll) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
+            return true;
+        }
+        if (isEnableMic) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "管理员关闭连麦申请");
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 检查mic模式
+     */
+    public boolean checkMicMode2() {
+        if (!anchorIsOnline) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
+            return true;
+        }
+        if (liveIsPause) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
+            return true;
+        }
+        if (liveIsFinish) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
+            return true;
+        }
+        if (isEnableAll) {
+            ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
+            return true;
+        }
+        return false;
+    }
+
+
+    @Override
+    public void finish() {
+        super.finish();
+        //前置通知离开接口
+        notifyLeave();
+    }
+
+    private void notifyLeave() {
+        if (presenter != null) {
+            //通知离开房间
+            presenter.notifyLeaveRoomAction();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (presenter != null) {
+            presenter.release();
+        }
+        super.onDestroy();
+        if (mHandler != null) {
+            mHandler.removeCallbacksAndMessages(null);
+        }
+        if (mMLivePlayer != null) {
+            mMLivePlayer.stopPlay();
+        }
+        //取消动画
+        if (hideHeaderInfoAnim != null) {
+            hideHeaderInfoAnim.cancel();
+            hideHeaderInfoAnim = null;
+        }
+
+        if (showHeaderInfoAnim != null) {
+            showHeaderInfoAnim.cancel();
+            showHeaderInfoAnim = null;
+        }
+        LiveRoomAnimatorHelper.getInstance().releaseAnimator();
+        LiveRoomAddLikeHelper.getInstance().release();
+        TRTCSdkManager.getInstance().release();
+        TCIMSdkManager.getInstance().quitGroup(mRoomId);
+        TCIMSdkManager.getInstance().release(mTIMSDKListener);
+    }
+
+}

+ 3 - 5
tclive/src/main/java/com/daya/tclive/ui/TCTeacherLiveRoomActivity.java

@@ -451,7 +451,7 @@ public class TCTeacherLiveRoomActivity extends BaseMVPActivity<ActivityTcTeacher
         if (isLiveCourse()) {
             iconFinishLive.setImageResource(R.drawable.icon_live_course_pause);
         }
-        mUserId = UserHelper.getUserId();
+        mUserId = UserHelper.getImUserId();
         mRoomMicMemberHelper = new LiveRoomMicMemberHelper();
         mRoomMicMemberHelper.setOnEventListener(this);
         mMessageAdapter = new TTLiveRoomMessageAdapter(this);
@@ -497,6 +497,7 @@ public class TCTeacherLiveRoomActivity extends BaseMVPActivity<ActivityTcTeacher
     }
 
     private void initListener() {
+        initClickListener();
         TCIMSdkManager.getInstance().addEventListener(mTIMSDKListener);
         SoftKeyboardUtil.registerSoftInputChangedListener(getWindow(), this);
         recyclerMsg.addOnScrollListener(new RecyclerView.OnScrollListener() {
@@ -562,7 +563,7 @@ public class TCTeacherLiveRoomActivity extends BaseMVPActivity<ActivityTcTeacher
         mTvNumPeople.setText(String.format("%s人", LiveMemberHelper.getMemberCountText(peopleCount)));
     }
 
-    private void initListener2(){
+    private void initClickListener(){
         viewBinding.viewCreateOptions.ivReverseCamera.setOnClickListener(this);
         viewBinding.viewCreateOptions.tvStartLive.setOnClickListener(this);
         viewBinding.viewCreateOptions.tvClose.setOnClickListener(this);
@@ -1417,9 +1418,6 @@ public class TCTeacherLiveRoomActivity extends BaseMVPActivity<ActivityTcTeacher
      * @param type
      */
     private void switchOpsLiveVideoMode(String type) {
-        if (presenter != null) {
-            presenter.notifyOpenOpsLiveVideoAction(mRoomId, type, mUserId);
-        }
     }
 
 

+ 4 - 2
tclive/src/main/java/com/daya/tclive/ui/TTLiveOnMicFragment.java

@@ -134,8 +134,10 @@ public class TTLiveOnMicFragment extends BaseFragment<TcFgTtLiveOnMicLayoutBindi
      * @param applyListData
      */
     public void refresh(ArrayList<User> applyListData) {
-        mAdapter.getData().clear();
-        mAdapter.setList(applyListData);
+        if (mAdapter != null) {
+            mAdapter.getData().clear();
+            mAdapter.setList(applyListData);
+        }
     }
 
     public void setOnEventListener(LiveMicOnEventListener listener) {

+ 322 - 0
tclive/src/main/java/com/daya/tclive/ui/floatPop/FloatWindowHelper.java

@@ -0,0 +1,322 @@
+package com.daya.tclive.ui.floatPop;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.PixelFormat;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+
+import com.cooleshow.base.common.AppManager;
+import com.cooleshow.base.utils.AppUtils;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.utils.helper.QMUIDisplayHelper;
+import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
+import com.daya.tclive.R;
+
+import java.util.List;
+
+
+/**
+ * Author by pq, Date on 2022/5/13.
+ * 悬浮窗
+ */
+public class FloatWindowHelper implements View.OnTouchListener {
+    public static final int REQUEST_OVERLAY_CODE = 5000;
+    private Context mContext;
+    private View mContentView;
+    private WindowManager.LayoutParams mFloatParams;
+    private WindowManager mWindowManager;
+    private RelativeLayout mLiveContainer;
+    private int maxWidth;
+    private int maxHeight;
+    private int maxDragX = 0;//控制最大拖拽的坐标
+    private int maxDragY = 0;//控制最大拖拽的坐标
+    private int initX = 0;//初始位置坐标
+    private int initY = 0;//初始位置坐标
+    private OnEventListener mEventListener;
+    private boolean isLiveFromPc = true;
+
+    public FloatWindowHelper(Context context, OnEventListener eventListener) {
+        mContext = context;
+        this.mEventListener = eventListener;
+        initView();
+    }
+
+    private void setDefaultParams() {
+        int deviceWidth = QMUIDisplayHelper.getScreenWidth(mContext);
+        int deviceHeight = QMUIDisplayHelper.getScreenHeight(mContext);
+        int orientation = mContext.getResources().getConfiguration().orientation;
+        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            maxWidth = deviceHeight / 2;
+            maxDragX = deviceHeight - maxWidth;
+            maxHeight = UiUtils.getHeightAtRatio16_9(mContext, maxWidth);
+            int actionBarHeight = QMUIDisplayHelper.getActionBarHeight(mContext);
+            int statusBarHeight = QMUIStatusBarHelper.getStatusbarHeight(mContext);
+            maxDragY = deviceWidth - actionBarHeight - statusBarHeight - maxHeight;
+        } else {
+            if (isLiveFromPc) {
+                //PC端是16:9的比例尺寸
+                maxWidth = deviceWidth / 2;
+                maxHeight = UiUtils.getHeightAtRatio16_9(mContext, maxWidth);
+            } else {
+                maxWidth = deviceWidth / 4;
+                float ratio = (float) deviceWidth / (float) deviceHeight;
+                maxHeight = (int) (maxWidth / ratio);
+            }
+            maxDragX = deviceWidth - maxWidth;
+            maxDragY = deviceHeight - maxHeight;
+        }
+        initX = deviceWidth-maxWidth - 50;
+        initY = maxDragY - 300;
+    }
+
+    /**
+     * 判断是否有悬浮窗权限
+     *
+     * @param activity
+     * @return
+     */
+    public static boolean requestOverlayPermission(Activity activity, int requestCode) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if (!Settings.canDrawOverlays(activity)) {
+                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + activity.getPackageName()));
+                activity.startActivityForResult(intent, requestCode);
+                return false;
+            } else {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isLiveFromPc() {
+        return isLiveFromPc;
+    }
+
+    public void setLiveFromPc(boolean liveFromPc) {
+        isLiveFromPc = liveFromPc;
+        //设置默认参数
+        setDefaultParams();
+    }
+
+    /**
+     * 判断是否有悬浮窗权限
+     *
+     * @param activity
+     * @return
+     */
+    public static boolean requestOverlayPermission(Activity activity) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if (!Settings.canDrawOverlays(activity)) {
+                return false;
+            } else {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void initView() {
+        mContentView = LayoutInflater.from(mContext).inflate(R.layout.tc_view_live_float_window_layout, null);
+        mLiveContainer = mContentView.findViewById(R.id.fl_live_container);
+        ImageView iv_close = mContentView.findViewById(R.id.iv_close);
+        mContentView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if(UiUtils.isFastClick()){
+                    return;
+                }
+                setTopApp(mContext);
+            }
+        });
+        iv_close.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mEventListener != null) {
+                    mEventListener.onClose();
+                }
+            }
+        });
+    }
+
+    public void showFloatingWindowView(Context context) {
+        // 获取系统窗口管理服务
+        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        // 悬浮窗口参数设置及返回
+        mFloatParams = getParams();
+        // 设置窗口触摸移动事件
+        mContentView.setOnTouchListener(this);
+        // 悬浮窗生成
+        mWindowManager.addView(mContentView, mFloatParams);
+    }
+
+    private WindowManager.LayoutParams getParams() {
+        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        //设置悬浮窗口类型
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+        } else {
+            layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+        }
+        //设置悬浮窗口属性
+        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+        //设置悬浮窗口透明
+        layoutParams.format = PixelFormat.TRANSLUCENT;
+        //设置悬浮窗口长宽数据
+        layoutParams.width = maxWidth;
+        layoutParams.height = maxHeight;
+        //设置悬浮窗显示位置
+        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
+        layoutParams.x = initX;
+        layoutParams.y = initY;
+        return layoutParams;
+    }
+
+    //开始触控的坐标,移动时的坐标(相对于屏幕左上角的坐标)
+    int mTouchStartX = 0;
+    int mTouchStartY = 0;
+    //开始时的坐标和结束时的坐标(相对于自身控件的坐标)
+    int mStartX = 0;
+    int mStartY = 0;
+    //判断悬浮窗口是否移动,这里做个标记,防止移动后松手触发了点击事件
+    boolean isMove = false;
+
+    @Override
+    public boolean onTouch(View v, MotionEvent motionEvent) {
+        int action = motionEvent.getAction();
+        int x = (int) motionEvent.getX();
+        int y = (int) motionEvent.getY();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                isMove = false;
+                mTouchStartX = (int) motionEvent.getRawX();
+                mTouchStartY = (int) motionEvent.getRawY();
+                mStartX = x;
+                mStartY = y;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                int nowX = (int) motionEvent.getRawX();
+                int nowY = (int) motionEvent.getRawY();
+                Log.i("pq", "now:x=" + nowX + "y=" + nowX);
+                int offsetX = nowX - mTouchStartX;
+                int offsetY = nowY - mTouchStartY;
+                Log.i("pq", "start:x=" + mTouchStartX + "y=" + mTouchStartY);
+                mFloatParams.x += offsetX;
+                mFloatParams.y += offsetY;
+                if (mFloatParams.x < 0) {
+                    mFloatParams.x = 0;
+                }
+                if (mFloatParams.x > maxDragX) {
+                    mFloatParams.x = maxDragX;
+                }
+                if (mFloatParams.y < 0) {
+                    mFloatParams.y = 0;
+                }
+                if (mFloatParams.y > maxDragY) {
+                    mFloatParams.y = maxDragY;
+                }
+
+                Log.i("pq", "move:x=" + offsetX + "y=" + offsetY);
+                Log.i("pq", "moveAfter:x=" + mFloatParams.x + "y=" + mFloatParams.y);
+                mWindowManager.updateViewLayout(mContentView, mFloatParams);
+                mTouchStartX = nowX;
+                mTouchStartY = nowY;
+                float deltaX = x - mStartX;
+                float deltaY = y - mStartY;
+                if (Math.abs(deltaX) >= 5 || Math.abs(deltaY) >= 5) {
+                    isMove = true;
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                break;
+            default:
+                break;
+        }
+        //如果是移动事件不触发OnClick事件,防止移动的时候一放手形成点击事件
+        return isMove;
+    }
+
+    public void dismiss() {
+        if (mContext == null) {
+            return;
+        }
+        WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        if (windowManager != null && mContentView != null && mContentView.getParent() != null) {
+            windowManager.removeView(mContentView);
+        }
+        if (mLiveContainer != null) {
+            mLiveContainer.removeAllViews();
+        }
+        this.mContext = null;
+    }
+
+
+    public void addTTVideoView(List<View> videoViews) {
+        if (videoViews != null && videoViews.size() > 0) {
+            mLiveContainer.removeAllViews();
+            for (int i = 0; i < videoViews.size(); i++) {
+                View videoView = videoViews.get(i);
+                ViewGroup parent = (ViewGroup) videoView.getParent();
+                if (parent != null) {
+                    parent.removeView(videoView);
+                }
+                RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+                layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
+                mLiveContainer.addView(videoView, layoutParams);
+            }
+        }
+    }
+
+    /**
+     * 返回前台
+     *
+     * @param context
+     */
+    public void setTopApp(Context context) {
+        if (AppUtils.isApplicationInBackground(context)) {
+            //获取ActivityManager
+            ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+            //获得当前运行的task(任务)
+            List<ActivityManager.RunningTaskInfo> taskInfoList = null;
+            if (activityManager != null) {
+                taskInfoList = activityManager.getRunningTasks(100);
+            }
+            if (taskInfoList != null) {
+                for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
+                    //找到本应用的 task,并将它切换到前台
+                    if (taskInfo.topActivity != null && taskInfo.topActivity.getPackageName().equals(context.getPackageName())) {
+                        activityManager.moveTaskToFront(taskInfo.id, 0);
+                        break;
+                    }
+                }
+            }
+        } else {
+            Activity topActivity = AppManager.Companion.getInstance().getTopActivity();
+            if (topActivity != null) {
+                topActivity.finish();
+            }
+        }
+    }
+
+    public interface OnEventListener {
+        void onClose();
+    }
+}

+ 95 - 0
tclive/src/main/java/com/daya/tclive/ui/floatPop/FloatingWindowService.java

@@ -0,0 +1,95 @@
+package com.daya.tclive.ui.floatPop;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+import android.view.View;
+
+import java.util.List;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Author by pq, Date on 2022/5/13.
+ */
+public class FloatingWindowService extends Service implements FloatWindowHelper.OnEventListener {
+    public static final String CLASS_PATH = "com.daya.studaya_android.ui.live.floatPop.FloatingWindowService";
+    private FloatWindowHelper mHelper;
+    private boolean isShowing = false;
+    private MyBinder mBinder;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mHelper = new FloatWindowHelper(this, this);
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        return super.onStartCommand(intent, flags, startId);
+    }
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (mBinder == null) {
+            mBinder = new MyBinder();
+        }
+        boolean isPc = intent.getBooleanExtra("isPc", true);
+        if (mHelper != null && !isShowing) {
+            mHelper.setLiveFromPc(isPc);
+            mHelper.showFloatingWindowView(this);
+            isShowing = true;
+        }
+        return mBinder;
+    }
+
+    @Override
+    public void onDestroy() {
+        // 移除浮动框
+        if (mHelper != null) {
+            mHelper.dismiss();
+        }
+        if (mBinder != null) {
+            if (mBinder.eventListener != null) {
+                mBinder.eventListener.onServiceDestroy();
+            }
+        }
+        super.onDestroy();
+        Log.i("pq", "FloatingWindowService onDestroy");
+    }
+
+    @Override
+    public void onClose() {
+        if (mBinder != null && mBinder.eventListener != null) {
+            mBinder.eventListener.onUnbindService();
+        }
+    }
+
+    public class MyBinder extends Binder {
+        private OnEventListener eventListener;
+
+        public FloatingWindowService getService() {
+            return FloatingWindowService.this;
+        }
+
+
+        public void addTTVideoView(List<View> videoViews) {
+            if (mHelper != null) {
+                mHelper.addTTVideoView(videoViews);
+            }
+        }
+
+        public void setOnEventListener(OnEventListener eventListener) {
+            this.eventListener = eventListener;
+        }
+    }
+
+    public interface OnEventListener {
+        void onServiceDestroy();
+
+        void onUnbindService();
+    }
+}

+ 57 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomCloseMicTipDialog.java

@@ -0,0 +1,57 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.daya.tclive.R;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2022/4/7.
+ */
+public class LiveRoomCloseMicTipDialog extends Dialog implements View.OnClickListener {
+
+    private TextView mTvSure;
+    private TextView mTvCancel;
+    private View.OnClickListener confirmClickListener;
+    private TextView mTvTip;
+
+    public LiveRoomCloseMicTipDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.DialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_live_room_close_mic_layout);
+        mTvSure = findViewById(R.id.tv_sure);
+        mTvCancel = findViewById(R.id.tv_cancel);
+        mTvTip = findViewById(R.id.tv_tip);
+        mTvCancel.setOnClickListener(this);
+        if (confirmClickListener != null) {
+            mTvSure.setOnClickListener(confirmClickListener);
+        }
+    }
+
+    public void setContent(String content) {
+        if (mTvTip != null) {
+            mTvTip.setText(content);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.tv_cancel) {
+            dismiss();
+        }
+    }
+
+    public void setConfirmClickListener(View.OnClickListener confirmClickListener) {
+        this.confirmClickListener = confirmClickListener;
+    }
+}

+ 65 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomClosePageOnMicTipDialog.java

@@ -0,0 +1,65 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.daya.tclive.R;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2022/4/7.
+ */
+public class LiveRoomClosePageOnMicTipDialog extends Dialog implements View.OnClickListener {
+
+    private TextView mTvSure;
+    private TextView mTvCancel;
+    private View.OnClickListener confirmClickListener;
+    private TextView mTvTip;
+    private TextView mTvContent;
+
+    public LiveRoomClosePageOnMicTipDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.DialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_live_room_close_page_layout);
+        mTvSure = findViewById(R.id.tv_sure);
+        mTvCancel = findViewById(R.id.tv_cancel);
+        mTvTip = findViewById(R.id.tv_tip);
+        mTvContent = findViewById(R.id.tv_content);
+        mTvCancel.setOnClickListener(this);
+        if (confirmClickListener != null) {
+            mTvSure.setOnClickListener(confirmClickListener);
+        }
+    }
+
+    public void setTitle(String title) {
+        if (mTvTip != null) {
+            mTvTip.setText(title);
+        }
+    }
+
+    public void setContent(String content) {
+        if (mTvContent != null) {
+            mTvContent.setText(content);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.tv_cancel) {
+            dismiss();
+        }
+    }
+
+    public void setConfirmClickListener(View.OnClickListener confirmClickListener) {
+        this.confirmClickListener = confirmClickListener;
+    }
+}

+ 64 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomExitTipDialog2.java

@@ -0,0 +1,64 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.daya.tclive.R;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2022/4/7.
+ */
+public class LiveRoomExitTipDialog2 extends Dialog implements View.OnClickListener {
+
+    private TextView mTvSure;
+    private TextView mTvCancel;
+    private View.OnClickListener confirmClickListener;
+    private TextView mTvTip;
+
+    public LiveRoomExitTipDialog2(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.DialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_live_room_exit_tip_layout2);
+        mTvSure = findViewById(R.id.tv_sure);
+        mTvCancel = findViewById(R.id.tv_cancel);
+        mTvTip = findViewById(R.id.tv_tip);
+        mTvCancel.setOnClickListener(this);
+        if (confirmClickListener != null) {
+            mTvSure.setOnClickListener(confirmClickListener);
+        }
+    }
+
+    public void setContent(String content) {
+        if (mTvTip != null) {
+            mTvTip.setText(content);
+        }
+    }
+
+    public void setCancelClickListener(View.OnClickListener listener) {
+        if (mTvCancel != null) {
+            mTvCancel.setOnClickListener(listener);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.tv_cancel) {
+            dismiss();
+            return;
+        }
+    }
+
+    public void setConfirmClickListener(View.OnClickListener confirmClickListener) {
+        this.confirmClickListener = confirmClickListener;
+    }
+}

+ 51 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomInviteSeatMicTipDialog.java

@@ -0,0 +1,51 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.daya.tclive.R;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2022/4/7.
+ */
+public class LiveRoomInviteSeatMicTipDialog extends Dialog {
+
+    private TextView mTvSure;
+    private TextView mTvCancel;
+    private View.OnClickListener viewClickListener;
+    private TextView mTvContent;
+
+    public LiveRoomInviteSeatMicTipDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.DialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_live_room_invite_mic_layout);
+        mTvSure = findViewById(R.id.tv_sure);
+        mTvCancel = findViewById(R.id.tv_cancel);
+        mTvContent = findViewById(R.id.tv_content);
+        if (viewClickListener != null) {
+            mTvSure.setOnClickListener(viewClickListener);
+            mTvCancel.setOnClickListener(viewClickListener);
+        }
+    }
+
+    public void setContent(String nickName) {
+        if (mTvContent != null) {
+            String content = getContext().getString(R.string.invite_seat_content_tip, nickName);
+            mTvContent.setText(content);
+        }
+    }
+
+    public void setViewClickListener(View.OnClickListener confirmClickListener) {
+        this.viewClickListener = confirmClickListener;
+    }
+}

+ 145 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomMicManagerDialog.java

@@ -0,0 +1,145 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+
+import com.cooleshow.base.utils.GlideImageLoaderUtils;
+import com.cooleshow.usercenter.helper.UserHelper;
+import com.daya.tclive.R;
+import com.daya.tclive.constants.LiveRoomMsgConstants;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+/**
+ * Author by pq, Date on 2022/8/11.
+ */
+public class LiveRoomMicManagerDialog extends Dialog implements View.OnClickListener {
+
+    private LinearLayout mLlApply;
+    private TextView mTvApplyMic;
+    private TextView mTvCancel;
+    private ConstraintLayout mCsApplying;
+    private TextView mTvCancelApply;
+    private ImageView mIvOwnerAvatar;
+    private ImageView mIvTeacherAvatar;
+    private LinearLayout mLlCloseMic;
+    private TextView mTvCloseMic;
+    private TextView mTvCancel2;
+    private OnEventListener mEventListener;
+
+    public LiveRoomMicManagerDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.BottomDialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_live_room_mic_manager_layout);
+        Window window = getWindow();
+        //设置dialog在屏幕底部
+        window.setGravity(Gravity.BOTTOM);
+        //设置dialog弹出时的动画效果,从屏幕底部向上弹出
+        window.setWindowAnimations(com.cooleshow.base.R.style.BottomAnimation);
+        window.getDecorView().setPadding(0, 0, 0, 0);
+        //获得window窗口的属性
+        WindowManager.LayoutParams lp = window.getAttributes();
+        //设置窗口宽度为充满全屏
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+        //设置窗口高度为包裹内容
+        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        lp.horizontalMargin = 0;
+        lp.verticalMargin = 0;
+        //将设置好的属性set回去
+        window.setAttributes(lp);
+
+        mLlApply = findViewById(R.id.ll_apply);
+        mTvApplyMic = findViewById(R.id.tv_apply_mic);
+        mTvCancel = findViewById(R.id.tv_cancel);
+        mCsApplying = findViewById(R.id.cs_applying);
+        mTvCancelApply = findViewById(R.id.tv_cancel_apply);
+        mIvOwnerAvatar = findViewById(R.id.iv_owner_avatar);
+        mIvTeacherAvatar = findViewById(R.id.iv_teacher_avatar);
+        mLlCloseMic = findViewById(R.id.ll_close_mic);
+        mTvCloseMic = findViewById(R.id.tv_close_mic);
+        mTvCancel2 = findViewById(R.id.tv_cancel2);
+
+        String userAvatar = UserHelper.getUserAvatar();
+        GlideImageLoaderUtils.getInstance().loadImage(getContext(),userAvatar,mIvOwnerAvatar,R.drawable.icon_default_head);
+        initListener();
+    }
+
+    private void initListener() {
+        mTvApplyMic.setOnClickListener(this);
+        mTvCancel.setOnClickListener(this);
+        mTvCancelApply.setOnClickListener(this);
+        mTvCloseMic.setOnClickListener(this);
+        mTvCancel2.setOnClickListener(this);
+    }
+
+    public void setMicStatus(int micStatus) {
+        if (mLlApply != null) {
+            mLlApply.setVisibility(micStatus == LiveRoomMsgConstants.MIC_STATUS_NORMAL ? View.VISIBLE : View.GONE);
+        }
+        if (mCsApplying != null) {
+            mCsApplying.setVisibility(micStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING ? View.VISIBLE : View.GONE);
+        }
+        if (mLlCloseMic != null) {
+            mLlCloseMic.setVisibility(micStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.tv_cancel || id == R.id.tv_cancel2) {
+            dismiss();
+            return;
+        }
+        if (id == R.id.tv_cancel_apply) {
+            //取消申请
+            if (mEventListener != null) {
+                mEventListener.onApplyCancel();
+            }
+        }
+        if (id == R.id.tv_apply_mic) {
+            //申请连麦
+            if (mEventListener != null) {
+                mEventListener.onApplyMic();
+            }
+        }
+        if (id == R.id.tv_close_mic) {
+            //关闭连麦
+            if (mEventListener != null) {
+                mEventListener.onCloseMic();
+            }
+        }
+    }
+
+    public void setLiveTeacherInfo(String teacherAvatar){
+        if (mIvTeacherAvatar != null) {
+            GlideImageLoaderUtils.getInstance().loadImage(getContext(),teacherAvatar,mIvTeacherAvatar,R.drawable.icon_default_head);
+        }
+    }
+
+    public void setOnEventListener(OnEventListener listener) {
+        this.mEventListener = listener;
+    }
+
+    public interface OnEventListener {
+        void onApplyMic();
+
+        void onApplyCancel();
+
+        void onCloseMic();
+    }
+}

+ 336 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/LiveRoomShopCarDialog.java

@@ -0,0 +1,336 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.webkit.GeolocationPermissions;
+import android.webkit.JavascriptInterface;
+import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
+import android.webkit.WebResourceError;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.TextView;
+
+
+import com.cooleshow.base.utils.LOG;
+import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.usercenter.helper.UserHelper;
+import com.daya.tclive.BuildConfig;
+import com.daya.tclive.R;
+import com.daya.tclive.constants.UrlConstants;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import androidx.annotation.NonNull;
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.core.Observable;
+import io.reactivex.rxjava3.core.ObservableEmitter;
+import io.reactivex.rxjava3.core.ObservableOnSubscribe;
+import io.reactivex.rxjava3.core.Observer;
+import io.reactivex.rxjava3.disposables.Disposable;
+import io.reactivex.rxjava3.schedulers.Schedulers;
+
+/**
+ * Author by pq, Date on 2022/5/16.
+ */
+public class LiveRoomShopCarDialog extends Dialog {
+    public static final String OPEN_DETAIL = "openUrl";
+
+    private WebView mWebView;
+    private String authorization;
+    private TextView mTvTitle;
+    private OnEventListener mEventListener;
+    private String webUrl;
+
+    public LiveRoomShopCarDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.BottomDialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_live_room_shop_car_layout);
+        Window window = getWindow();
+        //设置dialog在屏幕底部
+        window.setGravity(Gravity.BOTTOM);
+        //设置dialog弹出时的动画效果,从屏幕底部向上弹出
+        window.setWindowAnimations(com.cooleshow.base.R.style.BottomAnimation);
+        window.getDecorView().setPadding(0, 0, 0, 0);
+        //获得window窗口的属性
+        WindowManager.LayoutParams lp = window.getAttributes();
+        //设置窗口宽度为充满全屏
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+        //设置窗口高度为包裹内容
+        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        lp.horizontalMargin = 0;
+        lp.verticalMargin = 0;
+        //将设置好的属性set回去
+        window.setAttributes(lp);
+
+        mWebView = findViewById(R.id.webView);
+        initWebSetting();
+    }
+
+    public void changeGoods(String str) {
+        JSONObject jsonObject = new JSONObject();
+        try {
+            jsonObject.put("api", "cardChange");
+            JSONArray json = new JSONArray(str);
+            jsonObject.put("content", json);
+            String message = jsonObject.toString();
+            Log.i("LiveRoomShopCarDialog", "jsonObject:" + jsonObject.toString());
+            mWebView.evaluateJavascript("postMessage('" + message + "','*')", new ValueCallback<String>() {
+                @Override
+                public void onReceiveValue(String s) {
+                }
+            });
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void setRoomId(String roomId) {
+        if(TextUtils.isEmpty(webUrl)){
+            webUrl = UrlConstants.getShopCarWebUrl() + "?liveId=" + roomId;
+            if (!TextUtils.isEmpty(authorization)) {
+                try {
+                    authorization = URLEncoder.encode(authorization, "UTF-8");
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                boolean status = webUrl.contains("?");
+                if (status) {
+                    webUrl = (webUrl + "&Authorization=" + authorization);
+                } else {
+                    webUrl = (webUrl + "?Authorization=" + authorization);
+                }
+            }
+            mWebView.loadUrl(webUrl);
+        }
+    }
+
+    private void initWebSetting() {
+        mWebView.addJavascriptInterface(new Object() {
+            @JavascriptInterface
+            public void postMessage(String message) {
+                handleMessage(message);
+            }
+        }, "DAYA");
+        authorization = UserHelper.getUserToken();
+
+        mWebView.setWebViewClient(new WebClient());
+        mWebView.setWebChromeClient(new MyWebChromeClient());
+
+        //声明WebSettings子类
+        WebSettings webSettings = mWebView.getSettings();
+        webSettings.setUserAgentString(webSettings.getUserAgentString() + ";DAYAAPPA");
+        webSettings.setGeolocationDatabasePath(getContext().getFilesDir().getPath());
+        webSettings.setGeolocationEnabled(true);
+        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+        //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
+        webSettings.setJavaScriptEnabled(true);
+        webSettings.setMediaPlaybackRequiresUserGesture(false);//false允许自动播放音视频
+        //是否启用缓存
+        webSettings.setAppCacheEnabled(true);
+
+        // 开启DOM缓存,默认状态下是不支持LocalStorage的
+        webSettings.setDomStorageEnabled(true);
+        // 开启数据库缓存
+        webSettings.setDatabaseEnabled(true);
+        // 地址跨域导致视频预览图片加载不出来 无法播放:
+        webSettings.setAllowUniversalAccessFromFileURLs(false);
+        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
+
+        //设置自适应屏幕,两者合用
+        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
+        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
+        //缩放操作
+        webSettings.setSupportZoom(false); //支持缩放,默认为true。是下面那个的前提。
+        // 设置允许JS弹窗
+        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+        //其他细节操作
+        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存
+        webSettings.setAllowFileAccess(true); //设置可以访问文件
+        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
+        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
+        webSettings.setDefaultTextEncodingName("UTF-8");//设置编码格式
+
+        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);  //富文本适配
+        webSettings.setAppCacheMaxSize(Long.MAX_VALUE);
+        webSettings.setAppCachePath(getContext().getDir("appcache", 0).getPath());
+        webSettings.setDatabasePath(getContext().getDir("databases", 0).getPath());
+        webSettings.setGeolocationDatabasePath(getContext().getDir("geolocation", 0)
+                .getPath());
+        webSettings.setPluginState(WebSettings.PluginState.ON_DEMAND);
+        if (BuildConfig.DEBUG) {
+            mWebView.setWebContentsDebuggingEnabled(true);
+        }
+        webSettings.setTextZoom(100);//设置字体默认的缩放比例,以避免手机系统的字体修改对页面字体及布局造成影响。
+        mWebView.setHorizontalScrollBarEnabled(false);
+        mWebView.setVerticalScrollBarEnabled(false);
+        mWebView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> {
+
+        });
+    }
+
+    private void handleMessage(String message) {
+        Observable.create(new ObservableOnSubscribe<String>() {
+            @Override
+            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
+                JSONObject jsonObject = new JSONObject(message);
+                String api = jsonObject.getString("api");
+                if (TextUtils.equals(api, OPEN_DETAIL)) {
+                    JSONObject content = jsonObject.getJSONObject("content");
+                    String url = content.optString("url");
+                    if (!TextUtils.isEmpty(url)) {
+                        emitter.onNext(url);
+                    }
+                }
+            }
+        }).subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Observer<String>() {
+                    @Override
+                    public void onSubscribe(Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(String url) {
+                        if (mEventListener != null) {
+                            mEventListener.onOpenDetail(url);
+                        }
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+                        e.printStackTrace();
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+                });
+    }
+
+
+    private class WebClient extends WebViewClient {
+        //页面开始载入时调用
+
+        @Override
+        public void onPageStarted(WebView view, String url, Bitmap favicon) {
+            super.onPageStarted(view, url, favicon);
+            LOG.e("onPageStarted:" + url);
+        }
+
+        //页面载入结束时调用
+        @Override
+        public void onPageFinished(WebView view, String url) {
+            super.onPageFinished(view, url);
+            if (!TextUtils.isEmpty(authorization)) {
+                String js = "window.localStorage.setItem('Authorization','" + authorization + "');";
+                String jsUrl = "javascript:(function({var localStorage = window.localStorage; localStorage.setItem('Authorization','" + authorization + "') })()";
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+                    view.evaluateJavascript(js, null);
+                } else {
+                    view.loadUrl(jsUrl);
+                    view.reload();
+                }
+            }
+
+            LOG.e("onPageFinished:" + url);
+            LOG.e("Authorization:" + authorization);
+        }
+
+        //截取url请求,在当前视图加载,避免在跳转到自带浏览器
+        @Override
+        public boolean shouldOverrideUrlLoading(WebView view, String request) {
+            if (!(request.startsWith("http://") || request.startsWith("https://"))) {
+                try {
+                    Intent intent = new Intent();
+                    intent.setAction(Intent.ACTION_VIEW);
+                    intent.setData(Uri.parse(request));
+                    getContext().startActivity(intent);
+                } catch (ActivityNotFoundException e) {
+                    ToastUtil.getInstance().show(getContext(), "未安装该应用");
+                }
+                return true;
+            } else {
+                view.loadUrl(request);
+                return true;
+            }
+        }
+
+        //处理报错信息
+        @Override
+        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
+            super.onReceivedError(view, request, error);
+        }
+    }
+
+
+    private class MyWebChromeClient extends WebChromeClient {
+        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
+            callback.invoke(origin, true, false);
+        }
+
+        @Override
+        public void onProgressChanged(WebView view, int newProgress) {
+            LOG.e(newProgress + "");
+        }
+
+        @Override
+        public void onReceivedTitle(WebView view, String title) {
+            super.onReceivedTitle(view, title);
+        }
+
+        // Android > 5.0.1
+        public boolean onShowFileChooser(
+                WebView webView, ValueCallback<Uri[]> filePathCallback,
+                FileChooserParams fileChooserParams) {
+            return true;
+        }
+
+
+        // 点击全屏按钮时,调用的方法
+        @Override
+        public void onShowCustomView(View view, CustomViewCallback callback) {
+            super.onShowCustomView(view, callback);
+        }
+
+        // 取消全屏调用的方法
+        @Override
+        public void onHideCustomView() {
+            super.onHideCustomView();
+        }
+    }
+
+
+    public void setOnEventListener(OnEventListener listener) {
+        this.mEventListener = listener;
+    }
+
+    public interface OnEventListener {
+        void onOpenDetail(String url);
+    }
+}

+ 64 - 0
tclive/src/main/java/com/daya/tclive/widget/dialog/OpenOverlayPermissionTipDialog.java

@@ -0,0 +1,64 @@
+package com.daya.tclive.widget.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+
+import com.daya.tclive.R;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2022/4/7.
+ */
+public class OpenOverlayPermissionTipDialog extends Dialog implements View.OnClickListener {
+
+    private TextView mTvSure;
+    private TextView mTvCancel;
+    private View.OnClickListener confirmClickListener;
+    private TextView mTvTip;
+
+    public OpenOverlayPermissionTipDialog(@NonNull Context context) {
+        super(context, com.cooleshow.base.R.style.DialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.tc_dialog_open_overlay_permission_tip_layout);
+        mTvSure = findViewById(R.id.tv_sure);
+        mTvCancel = findViewById(R.id.tv_cancel);
+        mTvTip = findViewById(R.id.tv_tip);
+        mTvCancel.setOnClickListener(this);
+        if (confirmClickListener != null) {
+            mTvSure.setOnClickListener(confirmClickListener);
+        }
+    }
+
+    public void setContent(String content) {
+        if (mTvTip != null) {
+            mTvTip.setText(content);
+        }
+    }
+
+    public void setCancelClickListener(View.OnClickListener listener) {
+        if (mTvCancel != null) {
+            mTvCancel.setOnClickListener(listener);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.tv_cancel) {
+            dismiss();
+            return;
+        }
+    }
+
+    public void setConfirmClickListener(View.OnClickListener confirmClickListener) {
+        this.confirmClickListener = confirmClickListener;
+    }
+}

二进制
tclive/src/main/res/drawable-xhdpi/icon_live_end_tip.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_loading_progress.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_1.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_2.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_3.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_4.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_5.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_6.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_7.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_add_like_8.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_room_rest_bg.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_voice_off.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_live_voice_on.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_mic_applying.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_mic_conected.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_mic_connecting.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_mic_unconnect.png


二进制
tclive/src/main/res/drawable-xhdpi/icon_video_orientation_convert.png


二进制
tclive/src/main/res/drawable-xhdpi/tc_icon_add_like.png


二进制
tclive/src/main/res/drawable-xhdpi/tc_icon_close_gray.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_end_tip.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_1.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_2.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_3.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_4.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_5.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_6.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_7.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_add_like_8.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_room_rest_bg.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_voice_off.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_live_voice_on.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_mic_applying.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_mic_conected.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_mic_connecting.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_mic_unconnect.png


二进制
tclive/src/main/res/drawable-xxhdpi/icon_video_orientation_convert.png


二进制
tclive/src/main/res/drawable-xxhdpi/tc_icon_add_like.png


二进制
tclive/src/main/res/drawable-xxhdpi/tc_icon_close_gray.png


+ 5 - 0
tclive/src/main/res/drawable/shape_gray_14dp.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#0DFFFFFF"/>
+    <corners android:radius="14dp"/>
+</shape>

+ 7 - 0
tclive/src/main/res/drawable/shape_gray_14dp_border_white.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#0DFFFFFF"/>
+    <corners android:radius="14dp"/>
+    <stroke android:color="#f2f2f2"
+        android:width="1dp"/>
+</shape>

+ 6 - 0
tclive/src/main/res/drawable/shape_live_room_close_bt_bg.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <stroke android:color="@color/color_00B7AC"
+        android:width="1dp"/>
+    <corners android:radius="3dp"/>
+</shape>

+ 5 - 0
tclive/src/main/res/drawable/shape_live_room_close_cancel_bt_bg.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/color_00B7AC" />
+    <corners android:radius="3dp"/>
+</shape>

+ 9 - 0
tclive/src/main/res/drawable/shape_live_room_shop_car_top.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:angle="180"
+        android:endColor="#FF9D6F"
+        android:startColor="#FFBC92" />
+    <corners android:topLeftRadius="20dp"
+        android:topRightRadius="20dp"/>
+</shape>

+ 10 - 0
tclive/src/main/res/drawable/shape_live_video_progress2.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<animated-rotate
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pivotX="50%" android:pivotY="50%"
+    android:fromDegrees="0"
+    android:toDegrees="360">
+
+    <bitmap android:src="@drawable/icon_live_loading_progress"/>
+</animated-rotate>

+ 430 - 0
tclive/src/main/res/layout/ac_tt_liveroom_layout.xml

@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/content_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/color_25292e">
+
+    <FrameLayout
+        android:id="@+id/fl_video_container"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+<!--        这一层设置纯黑背景是防止web端有时候流信息异常会显示一个黑色矩形块,影响体验,所以纯黑覆盖-->
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/cs_video_container"
+            android:layout_width="match_parent"
+            android:background="@color/black"
+            android:layout_height="match_parent">
+
+
+            <com.tencent.rtmp.ui.TXCloudVideoView
+                android:id="@+id/video_view"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_centerInParent="true"
+                android:visibility="visible"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintHorizontal_bias="0.0"
+                app:layout_constraintLeft_toLeftOf="parent"
+                app:layout_constraintRight_toRightOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintVertical_bias="1.0" />
+
+            <com.tencent.rtmp.ui.TXCloudVideoView
+                android:id="@+id/sub_video_view"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:visibility="gone"
+                app:layout_constrainedWidth="true"
+                app:layout_constraintDimensionRatio="16:9"
+                app:layout_constraintRight_toRightOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintWidth_percent="0.2"
+                tools:visibility="visible" />
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </FrameLayout>
+
+    <include
+        android:id="@+id/view_live_status"
+        layout="@layout/tc_item_live_room_status_layout"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/fl_video_container"
+        app:layout_constraintLeft_toLeftOf="@+id/fl_video_container"
+        app:layout_constraintRight_toRightOf="@+id/fl_video_container"
+        app:layout_constraintTop_toTopOf="@+id/fl_video_container" />
+
+    <include
+        android:id="@+id/view_live_camera_status"
+        layout="@layout/tc_item_live_room_camera_status_layout"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/fl_video_container"
+        app:layout_constraintLeft_toLeftOf="@+id/fl_video_container"
+        app:layout_constraintRight_toRightOf="@+id/fl_video_container"
+        app:layout_constraintTop_toTopOf="@+id/fl_video_container" />
+
+    <ImageView
+        android:id="@+id/iv_switch_video_orientation"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="10dp"
+        android:layout_marginBottom="11dp"
+        android:src="@drawable/icon_video_orientation_convert"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/fl_video_container"
+        app:layout_constraintRight_toRightOf="@+id/fl_video_container" />
+
+    <ImageView
+        android:id="@+id/iv_switch_video_orientation_full"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="10dp"
+        android:src="@drawable/icon_video_orientation_convert"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/fl_video_container"
+        app:layout_constraintRight_toRightOf="@+id/fl_video_container"
+        app:layout_constraintTop_toTopOf="@+id/fl_video_container" />
+
+    <View
+        android:id="@+id/statusbar_view"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/statusbar_view_height"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cs_header_info"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toBottomOf="@+id/statusbar_view">
+
+        <View
+            android:id="@+id/bg_avatar"
+            android:layout_width="0dp"
+            android:layout_height="38dp"
+            android:layout_marginLeft="11dp"
+            android:layout_marginTop="2dp"
+            android:background="@drawable/bg_gray_20dp_shape"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="@+id/tv_room_author_name"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <de.hdodenhof.circleimageview.CircleImageView
+            android:id="@+id/iv_avatar"
+            android:layout_width="34dp"
+            android:layout_height="34dp"
+            android:layout_marginStart="2dp"
+            app:civ_circle_background_color="@color/white"
+            app:layout_constraintBottom_toBottomOf="@+id/bg_avatar"
+            app:layout_constraintLeft_toLeftOf="@+id/bg_avatar"
+            app:layout_constraintTop_toTopOf="@+id/bg_avatar" />
+
+        <TextView
+            android:id="@+id/tv_room_author_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="9dp"
+            android:ellipsize="end"
+            android:includeFontPadding="false"
+            android:maxLines="1"
+            android:paddingEnd="17dp"
+            android:text=""
+            android:textColor="@color/white"
+            android:textSize="@dimen/sp_18"
+            app:layout_constraintBottom_toBottomOf="@+id/bg_avatar"
+            app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+            app:layout_constraintTop_toTopOf="@+id/bg_avatar"
+            tools:text="唐老唐老师唐老师师" />
+
+        <ImageView
+            android:id="@+id/iv_close"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="14dp"
+            android:padding="5dp"
+            android:src="@drawable/tc_icon_close_gray"
+            app:layout_constraintBottom_toBottomOf="@+id/bg_avatar"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="@+id/bg_avatar" />
+
+        <LinearLayout
+            android:id="@+id/ll_member_num_bg"
+            android:layout_width="wrap_content"
+            android:layout_height="38dp"
+            android:layout_marginEnd="15dp"
+            android:background="@drawable/bg_gray_20dp_shape"
+            android:gravity="center_vertical"
+            android:paddingStart="6dp"
+            android:paddingEnd="10dp"
+            app:layout_constraintBottom_toBottomOf="@+id/bg_avatar"
+            app:layout_constraintRight_toLeftOf="@+id/iv_close"
+            app:layout_constraintTop_toTopOf="@+id/bg_avatar">
+
+            <ImageView
+                android:id="@+id/iv_number_people"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/icon_live_room_number_people" />
+
+            <TextView
+                android:id="@+id/tv_num_people"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="6dp"
+                android:ellipsize="end"
+                android:includeFontPadding="false"
+                android:maxLines="1"
+                android:textColor="@color/white"
+                android:textSize="@dimen/sp_14"
+                tools:text="176人" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/ll_like"
+            android:layout_width="wrap_content"
+            android:layout_height="22dp"
+            android:layout_marginTop="8dp"
+            android:background="@drawable/bg_gray_20dp_shape"
+            android:orientation="horizontal"
+            android:paddingStart="7dp"
+            android:paddingEnd="7dp"
+            app:layout_constraintLeft_toLeftOf="@+id/bg_avatar"
+            app:layout_constraintTop_toBottomOf="@+id/bg_avatar">
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:src="@drawable/icon_like_num" />
+
+            <TextView
+                android:id="@+id/tv_add_like_count"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:includeFontPadding="false"
+                android:paddingStart="2dp"
+                android:text="本场点赞0"
+                android:textColor="@color/white"
+                android:textSize="@dimen/sp_12"
+                tools:text="本场点赞1240000000" />
+        </LinearLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <View
+        android:id="@+id/mic_container_guide_view"
+        android:layout_width="1px"
+        android:layout_height="1px"
+        android:layout_marginTop="121dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/cs_header_info" />
+
+    <com.daya.tclive.widget.TTLiveRoomMicIconView
+        android:id="@+id/ll_mic_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="9dp"
+        android:layout_marginBottom="9dp"
+        android:paddingStart="5dp"
+        android:paddingEnd="5dp"
+        app:layout_constraintBottom_toTopOf="@+id/mic_container_guide_view"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/cs_header_info" />
+
+
+    <FrameLayout
+        android:id="@+id/fl_input"
+        android:layout_width="0dp"
+        android:layout_height="38dp"
+        android:layout_marginStart="11dp"
+        android:layout_marginEnd="11dp"
+        android:layout_marginBottom="30dp"
+        android:background="@drawable/bg_gray_20dp_shape"
+        android:orientation="horizontal"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/iv_voice_switch">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_input"
+            android:layout_width="match_parent"
+            android:layout_height="38dp"
+            android:gravity="center_vertical"
+            android:includeFontPadding="false"
+            android:singleLine="true"
+            android:ellipsize="middle"
+            android:layout_marginEnd="40dp"
+            android:paddingStart="16dp"
+            android:text="@string/live_input_tips_str"
+            android:textColor="@color/color_90ffffff"
+            android:textColorHint="@color/white"
+            android:textSize="@dimen/sp_14"
+            tools:text="您已被管理员禁言您已被管理员禁言您已被管理员禁言" />
+
+        <ImageView
+            android:layout_gravity="center_vertical|right"
+            android:id="@+id/iv_chat_speak"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:layout_marginEnd="11dp"
+            android:src="@drawable/icon_live_room_chat_speak"
+            app:layout_constraintBottom_toBottomOf="@+id/fl_input"
+            app:layout_constraintRight_toRightOf="@+id/fl_input"
+            app:layout_constraintTop_toTopOf="@+id/fl_input" />
+    </FrameLayout>
+
+    <ImageView
+        android:id="@+id/iv_voice_switch"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="11dp"
+        android:src="@drawable/icon_live_voice_on"
+        android:visibility="visible"
+        app:layout_constraintBottom_toBottomOf="@+id/icon_add_like"
+        app:layout_constraintRight_toLeftOf="@+id/iv_mic"
+        app:layout_constraintTop_toTopOf="@+id/icon_add_like" />
+
+    <com.airbnb.lottie.LottieAnimationView
+        android:id="@+id/view_shop_car_anim"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_shop_car"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_shop_car"
+        app:layout_constraintRight_toRightOf="@+id/iv_shop_car"
+        app:lottie_autoPlay="true"
+        app:lottie_loop="true"
+        app:lottie_rawRes="@raw/tc_live_shop_car_anim" />
+
+
+    <ImageView
+        android:id="@+id/iv_shop_car"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="11dp"
+        android:src="@drawable/tc_icon_add_like"
+        android:visibility="invisible"
+        app:layout_constraintBottom_toBottomOf="@+id/icon_add_like"
+        app:layout_constraintRight_toLeftOf="@+id/icon_add_like"
+        app:layout_constraintTop_toTopOf="@+id/icon_add_like" />
+
+    <ImageView
+        android:id="@+id/icon_add_like"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="11dp"
+        android:layout_marginBottom="30dp"
+        android:src="@drawable/tc_icon_add_like"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintRight_toRightOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_mic"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="11dp"
+        android:src="@drawable/icon_mic_unconnect"
+        app:layout_constraintBottom_toBottomOf="@+id/icon_add_like"
+        app:layout_constraintRight_toLeftOf="@+id/iv_shop_car"
+        app:layout_constraintTop_toTopOf="@+id/icon_add_like" />
+
+    <View
+        android:id="@+id/view_center"
+        android:layout_width="1px"
+        android:layout_height="1px"
+        android:layout_marginTop="50dp"
+        android:visibility="invisible"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <FrameLayout
+        android:id="@+id/fl_recycler_container"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="15dp"
+        android:layout_marginBottom="10dp"
+        android:paddingStart="11dp"
+        android:paddingEnd="11dp"
+        app:layout_constraintBottom_toTopOf="@+id/fl_input"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/fl_video_container">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recycler_msg"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:overScrollMode="never"
+            android:scrollbars="none" />
+    </FrameLayout>
+
+    <FrameLayout
+        android:id="@+id/fl_join_barrage"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="11dp"
+        android:layout_marginBottom="10dp"
+        android:background="@drawable/shape_live_barrage_for_join_msg"
+        android:paddingStart="10dp"
+        android:paddingTop="3dp"
+        android:paddingEnd="10dp"
+        android:paddingBottom="3dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toTopOf="@+id/fl_recycler_container"
+        app:layout_constraintLeft_toLeftOf="parent">
+
+        <TextView
+            android:id="@+id/tv_join_barrage"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="@color/white"
+            android:textSize="@dimen/sp_13"
+            tools:text="新雷 进入直播间" />
+
+    </FrameLayout>
+
+    <FrameLayout
+        android:id="@+id/fl_snap_up_barrage"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="11dp"
+        android:layout_marginBottom="10dp"
+        android:background="@drawable/shape_live_barrage_for_snap_up_msg"
+        android:paddingStart="10dp"
+        android:paddingTop="3dp"
+        android:paddingEnd="10dp"
+        android:paddingBottom="3dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toTopOf="@+id/fl_recycler_container"
+        app:layout_constraintLeft_toLeftOf="parent">
+
+        <TextView
+            android:id="@+id/tv_snap_up_barrage"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/icon_live_barrage_buy_tag"
+            android:drawablePadding="4dp"
+            android:textColor="@color/white"
+            android:textSize="@dimen/sp_13"
+            tools:text="张予锡 正在去购买" />
+
+    </FrameLayout>
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/group_views"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:constraint_referenced_ids="fl_recycler_container,fl_input" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 77 - 0
tclive/src/main/res/layout/dialog_live_room_close_mic_layout.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_white_shape_5dp"
+    android:minWidth="277dp">
+
+    <TextView
+        android:id="@+id/tv_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="19dp"
+        android:includeFontPadding="false"
+        android:text="@string/make_sure_close_mic_tip"
+        android:textColor="@color/black"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1px"
+        android:layout_marginTop="19dp"
+        android:background="@color/color_dedede"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_tip" />
+
+    <TextView
+        android:id="@+id/tv_content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="29dp"
+        android:includeFontPadding="false"
+        android:text="@string/close_mic_tip2"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_line" />
+
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="9dp"
+        android:background="@drawable/shape_live_room_close_cancel_bt_bg"
+        android:gravity="center"
+        android:text="@string/sure_close_tip"
+        android:textColor="@color/white"
+        app:layout_constraintLeft_toRightOf="@+id/tv_cancel"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_cancel" />
+
+    <TextView
+        android:id="@+id/tv_cancel"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="9dp"
+        android:layout_marginBottom="24dp"
+        android:background="@drawable/shape_live_room_close_bt_bg"
+        android:gravity="center"
+        android:text="@string/cancel"
+        android:textColor="@color/color_00B7AC"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toBottomOf="@+id/tv_content"
+
+        />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 77 - 0
tclive/src/main/res/layout/dialog_live_room_close_page_layout.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_white_shape_5dp"
+    android:minWidth="277dp">
+
+    <TextView
+        android:id="@+id/tv_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="19dp"
+        android:includeFontPadding="false"
+        android:text="@string/make_sure_close_mic_tip"
+        android:textColor="@color/black"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1px"
+        android:layout_marginTop="19dp"
+        android:background="@color/color_dedede"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_tip" />
+
+    <TextView
+        android:id="@+id/tv_content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="29dp"
+        android:includeFontPadding="false"
+        android:text="@string/close_mic_tip2"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_line" />
+
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="9dp"
+        android:background="@drawable/shape_live_room_close_cancel_bt_bg"
+        android:gravity="center"
+        android:text="@string/agree_str"
+        android:textColor="@color/white"
+        app:layout_constraintLeft_toRightOf="@+id/tv_cancel"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_cancel" />
+
+    <TextView
+        android:id="@+id/tv_cancel"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="9dp"
+        android:layout_marginBottom="24dp"
+        android:background="@drawable/shape_live_room_close_bt_bg"
+        android:gravity="center"
+        android:text="@string/cancel"
+        android:textColor="@color/color_00B7AC"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toBottomOf="@+id/tv_content"
+
+        />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 80 - 0
tclive/src/main/res/layout/dialog_live_room_exit_tip_layout2.xml

@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_white_shape_5dp"
+    android:minWidth="277dp">
+
+    <TextView
+        android:id="@+id/tv_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="19dp"
+        android:includeFontPadding="false"
+        android:text="确定要退出直播间吗?"
+        android:textColor="@color/black"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1px"
+        android:layout_marginTop="19dp"
+        android:background="@color/color_dedede"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_tip" />
+
+    <TextView
+        android:id="@+id/tv_content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="29dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingStart="14dp"
+        android:paddingEnd="14dp"
+        android:text="退出后如再次观看可重新进入~"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_line" />
+
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="9dp"
+        android:background="@drawable/shape_live_room_close_cancel_bt_bg"
+        android:gravity="center"
+        android:text="确认"
+        android:textColor="@color/white"
+        app:layout_constraintLeft_toRightOf="@+id/tv_cancel"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_cancel" />
+
+    <TextView
+        android:id="@+id/tv_cancel"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="9dp"
+        android:layout_marginBottom="24dp"
+        android:background="@drawable/shape_live_room_close_bt_bg"
+        android:gravity="center"
+        android:text="取消"
+        android:textColor="@color/color_00B7AC"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toBottomOf="@+id/tv_content"
+
+        />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 75 - 0
tclive/src/main/res/layout/dialog_live_room_invite_mic_layout.xml

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_white_shape_5dp"
+    android:minWidth="277dp">
+
+    <TextView
+        android:id="@+id/tv_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="19dp"
+        android:includeFontPadding="false"
+        android:text="@string/invite_seat_mic_tip"
+        android:textColor="@color/black"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1px"
+        android:layout_marginTop="19dp"
+        android:background="@color/color_dedede"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_tip" />
+
+    <TextView
+        android:id="@+id/tv_content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="29dp"
+        android:includeFontPadding="false"
+        android:text="@string/invite_seat_mic_tip2"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_line" />
+
+    <TextView
+        android:id="@+id/tv_cancel"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginEnd="9dp"
+        android:background="@drawable/shape_live_room_close_bt_bg"
+        android:gravity="center"
+        android:text="@string/disagree_str"
+        android:textColor="@color/color_00B7AC"
+        android:layout_marginTop="28dp"
+        android:layout_marginBottom="24dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toBottomOf="@+id/tv_content"
+
+        />
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:background="@drawable/shape_live_room_close_cancel_bt_bg"
+        android:gravity="center"
+        android:layout_marginStart="9dp"
+        android:text="@string/agree_str"
+        android:textColor="@color/white"
+        app:layout_constraintLeft_toRightOf="@+id/tv_cancel"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_cancel"  />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 155 - 0
tclive/src/main/res/layout/dialog_live_room_mic_manager_layout.xml

@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:id="@+id/ll_apply"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/bg_white_top_10dp"
+        android:orientation="vertical"
+        android:paddingBottom="20dp"
+        android:visibility="visible">
+
+        <TextView
+            android:id="@+id/tv_apply_mic"
+            android:layout_width="match_parent"
+            android:layout_height="60dp"
+            android:gravity="center"
+            android:text="申请连麦"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_18"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="0.5dp"
+            android:background="@color/color_dedede" />
+
+        <TextView
+            android:id="@+id/tv_cancel"
+            android:layout_width="match_parent"
+            android:layout_height="60dp"
+            android:gravity="center"
+            android:text="取消"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_18"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+    </LinearLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:visibility="gone"
+        android:id="@+id/cs_applying"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/bg_white_top_10dp"
+        android:minHeight="288dp">
+
+        <TextView
+            android:id="@+id/tv_cancel_apply"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:includeFontPadding="false"
+            android:padding="18dp"
+            android:text="取消申请"
+            android:textColor="@color/color_999999"
+            android:textSize="@dimen/sp_14"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <de.hdodenhof.circleimageview.CircleImageView
+            android:id="@+id/iv_owner_avatar"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:layout_marginTop="64dp"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toLeftOf="@+id/iv_applying"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <ImageView
+            android:id="@+id/iv_applying"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="14dp"
+            android:layout_marginEnd="14dp"
+            android:src="@drawable/icon_mic_applying"
+            app:layout_constraintBottom_toBottomOf="@+id/iv_owner_avatar"
+            app:layout_constraintLeft_toRightOf="@+id/iv_owner_avatar"
+            app:layout_constraintRight_toLeftOf="@+id/iv_teacher_avatar"
+            app:layout_constraintTop_toTopOf="@+id/iv_owner_avatar" />
+
+        <de.hdodenhof.circleimageview.CircleImageView
+            android:id="@+id/iv_teacher_avatar"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            app:layout_constraintLeft_toRightOf="@+id/iv_applying"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="@+id/iv_owner_avatar" />
+
+
+        <TextView
+            android:id="@+id/tv_tip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="38dp"
+            android:text="已申请连麦"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_18"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/iv_owner_avatar" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingTop="8dp"
+            android:text="等待老师通过"
+            android:textColor="@color/color_999999"
+            android:textSize="@dimen/sp_14"
+            app:layout_constraintLeft_toLeftOf="@+id/tv_tip"
+            app:layout_constraintRight_toRightOf="@+id/tv_tip"
+            app:layout_constraintTop_toBottomOf="@+id/tv_tip" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <LinearLayout
+        android:id="@+id/ll_close_mic"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/bg_white_top_10dp"
+        android:orientation="vertical"
+        android:paddingBottom="20dp"
+        android:visibility="gone">
+
+        <TextView
+            android:id="@+id/tv_close_mic"
+            android:layout_width="match_parent"
+            android:layout_height="60dp"
+            android:gravity="center"
+            android:text="断开连麦"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_18"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="0.5dp"
+            android:background="@color/color_dedede" />
+
+        <TextView
+            android:id="@+id/tv_cancel2"
+            android:layout_width="match_parent"
+            android:layout_height="60dp"
+            android:gravity="center"
+            android:text="取消"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_18"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+    </LinearLayout>
+</FrameLayout>

+ 38 - 0
tclive/src/main/res/layout/dialog_live_room_shop_car_layout.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="400dp">
+
+    <View
+        android:id="@+id/view_top_bg"
+        android:layout_width="match_parent"
+        android:layout_height="41dp"
+        android:background="@drawable/shape_live_room_shop_car_top"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@color/color_f5f5f5"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_top_bg" />
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="15dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/view_top_bg" />
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_top_bg" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 80 - 0
tclive/src/main/res/layout/tc_dialog_open_overlay_permission_tip_layout.xml

@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_white_shape_5dp"
+    android:minWidth="277dp">
+
+    <TextView
+        android:id="@+id/tv_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="19dp"
+        android:includeFontPadding="false"
+        android:text="开启悬浮窗功能"
+        android:textColor="@color/black"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1px"
+        android:layout_marginTop="19dp"
+        android:background="@color/color_dedede"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_tip" />
+
+    <TextView
+        android:id="@+id/tv_content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="29dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingStart="14dp"
+        android:paddingEnd="14dp"
+        android:text="需要您在系统设置中手动开启系统权限后\n才能使用悬浮窗播放功能"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_line" />
+
+    <TextView
+        android:id="@+id/tv_sure"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="9dp"
+        android:background="@drawable/shape_live_room_close_cancel_bt_bg"
+        android:gravity="center"
+        android:text="去开启"
+        android:textColor="@color/white"
+        app:layout_constraintLeft_toRightOf="@+id/tv_cancel"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_cancel" />
+
+    <TextView
+        android:id="@+id/tv_cancel"
+        android:layout_width="109dp"
+        android:layout_height="32dp"
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="9dp"
+        android:layout_marginBottom="24dp"
+        android:background="@drawable/shape_live_room_close_bt_bg"
+        android:gravity="center"
+        android:text="暂不开启"
+        android:textColor="@color/color_00B7AC"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+        app:layout_constraintTop_toBottomOf="@+id/tv_content"
+
+        />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 37 - 0
tclive/src/main/res/layout/tc_item_live_room_camera_status_layout.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/color_1a1a1a">
+
+    <ImageView
+        android:id="@+id/iv_camera_center_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toTopOf="@+id/tv_live_camera_status_tip_text"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:src="@drawable/icon_live_room_close_video" />
+
+    <TextView
+        android:id="@+id/tv_live_camera_status_tip_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="7dp"
+        android:background="@drawable/shape_gray_14dp"
+        android:paddingStart="8dp"
+        android:paddingTop="4dp"
+        android:paddingEnd="8dp"
+        android:paddingBottom="4dp"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_camera_center_icon"
+        app:layout_constraintRight_toRightOf="@+id/iv_camera_center_icon"
+        app:layout_constraintTop_toBottomOf="@+id/iv_camera_center_icon"
+        tools:text="主持人已关闭画面!" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 99 - 0
tclive/src/main/res/layout/tc_item_live_room_status_layout.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/cs_root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/color_1a1a1a">
+
+    <ImageView
+        android:id="@+id/iv_center_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toTopOf="@+id/tv_live_status_tip_text"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:src="@drawable/icon_live_room_close_video" />
+
+    <TextView
+        android:id="@+id/tv_live_status_tip_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="7dp"
+        android:background="@drawable/shape_gray_14dp"
+        android:paddingStart="8dp"
+        android:paddingTop="4dp"
+        android:paddingEnd="8dp"
+        android:paddingBottom="4dp"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintBottom_toTopOf="@+id/tv_retry"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_center_icon"
+        app:layout_constraintRight_toRightOf="@+id/iv_center_icon"
+        app:layout_constraintTop_toBottomOf="@+id/iv_center_icon"
+        tools:text="主持人已关闭画面!" />
+
+    <TextView
+        android:id="@+id/tv_retry"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="7dp"
+        android:background="@drawable/shape_gray_14dp_border_white"
+        android:paddingStart="18dp"
+        android:paddingTop="4dp"
+        android:paddingEnd="18dp"
+        android:paddingBottom="4dp"
+        android:text="刷新一下"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_center_icon"
+        app:layout_constraintRight_toRightOf="@+id/iv_center_icon"
+        app:layout_constraintTop_toBottomOf="@+id/tv_live_status_tip_text"
+        tools:text="重试" />
+
+
+    <ProgressBar
+        android:id="@+id/pb_loading"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:indeterminateDrawable="@drawable/shape_live_video_progress2"
+        android:max="100"
+        app:layout_constraintBottom_toTopOf="@+id/tv_loading"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_chainStyle="packed" />
+
+    <TextView
+        android:id="@+id/tv_loading"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingTop="10dp"
+        android:text="加载中"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/pb_loading" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/group_loading"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:constraint_referenced_ids="tv_loading,pb_loading" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/group_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="visible"
+        app:constraint_referenced_ids="tv_live_status_tip_text,iv_center_icon" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 27 - 0
tclive/src/main/res/layout/tc_view_live_float_window_layout.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_gravity="center"
+    android:layout_height="match_parent"
+    android:background="@color/color_1a1a1a">
+
+    <RelativeLayout
+        android:id="@+id/fl_live_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_close"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right"
+        android:padding="12dp"
+        android:src="@drawable/ic_live_teaching_close"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent" />
+</FrameLayout>

+ 1 - 1
tclive/src/main/res/layout/view_start_tc_live_layout.xml

@@ -12,7 +12,7 @@
         android:layout_marginStart="19dp"
         android:layout_marginTop="50dp"
         android:drawableLeft="@drawable/icon_close_live"
-        android:text="@string/close_str"
+        android:text="@string/tc_close_str"
         android:textColor="@color/white"
         android:textSize="@dimen/sp_14" />
 

文件差异内容过多而无法显示
+ 0 - 0
tclive/src/main/res/raw/tc_live_shop_car_anim.json


+ 1 - 0
tclive/src/main/res/values/colors.xml

@@ -10,4 +10,5 @@
     <color name="color_00fff0">#00FFF0</color>
     <color name="color_00d6c9">#00d6c9</color>
     <color name="color_ff605e">#ff605e</color>
+    <color name="color_f5f5f5">#F5F5F5</color>
 </resources>

+ 22 - 1
tclive/src/main/res/values/strings.xml

@@ -1,5 +1,5 @@
 <resources>
-    <string name="close_str">关闭</string>
+    <string name="tc_close_str">关闭</string>
     <string name="reverse_camera_str">翻转</string>
     <string name="beauty_str">美化</string>
     <string name="share_str">分享</string>
@@ -15,4 +15,25 @@
     <string name="enter_live_tip_str">%1$s 进入直播间</string>
     <string name="live_snap_up_tip_str">%1$s 正在抢购</string>
     <string name="net_error_tip">网络已断开</string>
+    <string name="live_input_tips_str">快来互动吧!</string>
+
+    <string name="invite_seat_mic_tip">连麦邀请</string>
+    <string name="invite_seat_mic_tip2">XXX邀请您连麦</string>
+    <string name="agree_str">确定</string>
+    <string name="disagree_str">取消</string>
+    <string name="invite_seat_content_tip">%1$s邀请您连麦</string>
+    <string name="make_sure_close_mic_tip">确定要关闭连麦吗?</string>
+    <string name="close_mic_tip2">断开后如想再次连麦可重新发起</string>
+    <string name="sure_close_tip">确定关闭</string>
+    <string name="create_recall_seat_invite_tip">主讲人撤回了连麦申请</string>
+    <string name="create_refuse_seat_tip">主讲人拒绝了您的连麦申请</string>
+    <string name="down_mic_by_create_tip">您已被主讲人抱下麦</string>
+    <string name="enable_mic_mode_tip">禁止连麦模式</string>
+    <string name="cancel_seat_on_connecting">连麦申请中,确认取消连麦申请吗?</string>
+    <string name="cancel_seat_on_connected">连麦中,确认取消连麦吗?</string>
+    <string name="seat_apply_str">已发起连麦申请</string>
+    <string name="home_live_room_create_str">主讲人:%1$s</string>
+    <string name="live_is_pause_str">主讲人已暂停直播</string>
+    <string name="nickname_call_str">亲爱的%1$s同学:</string>
+    <string name="unable_input_tip_str">您已被管理员禁言</string>
 </resources>

部分文件因为文件数量过多而无法显示