蒋洪波

fix bug

@@ -36,9 +36,9 @@ public class AppConfig { @@ -36,9 +36,9 @@ public class AppConfig {
36 36
37 37
38 //SD卡 统一文件夹名称 38 //SD卡 统一文件夹名称
39 - public static final String SHOPIN_DIR = "shopin"; 39 + public static final String XDY_DIR = "xdy";
40 //本地文件夹位置 40 //本地文件夹位置
41 - public static final File LOCAL_FILE_DIR = new File(Environment.getExternalStorageDirectory(), SHOPIN_DIR); 41 + public static final File LOCAL_FILE_DIR = new File(Environment.getExternalStorageDirectory(), XDY_DIR);
42 42
43 //辨识系统常量,在某些页面需要针对 43 //辨识系统常量,在某些页面需要针对
44 public static final CharSequence SAMSUNG_BRAND = "samsung"; 44 public static final CharSequence SAMSUNG_BRAND = "samsung";
@@ -2,9 +2,12 @@ package com.xdy.commonlibrary.core; @@ -2,9 +2,12 @@ package com.xdy.commonlibrary.core;
2 2
3 3
4 import com.xdy.util.AppUtil; 4 import com.xdy.util.AppUtil;
  5 +import com.xdy.util.DateUtils;
5 import com.xdy.util.LogUtil; 6 import com.xdy.util.LogUtil;
6 7
7 import java.io.ByteArrayOutputStream; 8 import java.io.ByteArrayOutputStream;
  9 +import java.io.File;
  10 +import java.io.FileWriter;
8 import java.io.IOException; 11 import java.io.IOException;
9 import java.io.PrintStream; 12 import java.io.PrintStream;
10 13
@@ -50,6 +53,22 @@ public class CrashHandler extends AbsCrashHandler { @@ -50,6 +53,22 @@ public class CrashHandler extends AbsCrashHandler {
50 // entity.setErrorMsg(errorMessage); 53 // entity.setErrorMsg(errorMessage);
51 // instance.insertOrUpdateData(entity); 54 // instance.insertOrUpdateData(entity);
52 LogUtil.e(TAG, errorMessage); 55 LogUtil.e(TAG, errorMessage);
  56 +
  57 + File sdCard = AppConfig.LOCAL_FILE_DIR;
  58 + if (!sdCard.exists())
  59 + sdCard.mkdirs();
  60 +
  61 + File txt = new File(AppConfig.LOCAL_FILE_DIR, DateUtils.getTimeWithSec() + ".txt");
  62 + if (!txt.exists()) {
  63 + boolean newFile = txt.createNewFile();
  64 + if (newFile) {
  65 + FileWriter writer = new FileWriter(txt);
  66 + writer.write(errorMessage);
  67 + writer.flush();
  68 + writer.close();
  69 + }
  70 + }
  71 +
53 baos.close(); 72 baos.close();
54 } catch (IOException e) { 73 } catch (IOException e) {
55 e.printStackTrace(); 74 e.printStackTrace();
@@ -46,6 +46,7 @@ public class ChatAdapter extends BaseAdapter { @@ -46,6 +46,7 @@ public class ChatAdapter extends BaseAdapter {
46 private List<Message> datas = null; 46 private List<Message> datas = null;
47 private KJBitmap kjb; 47 private KJBitmap kjb;
48 private ChatFragment.OnChatItemClickListener listener; 48 private ChatFragment.OnChatItemClickListener listener;
  49 + String oldTime;
49 50
50 public ChatAdapter(Context cxt, List<Message> datas, ChatFragment.OnChatItemClickListener listener) { 51 public ChatAdapter(Context cxt, List<Message> datas, ChatFragment.OnChatItemClickListener listener) {
51 this.cxt = cxt; 52 this.cxt = cxt;
@@ -109,17 +110,20 @@ public class ChatAdapter extends BaseAdapter { @@ -109,17 +110,20 @@ public class ChatAdapter extends BaseAdapter {
109 holder.tv_chatcontent = (TextView) v.findViewById(R.id.chat_item_content_text); 110 holder.tv_chatcontent = (TextView) v.findViewById(R.id.chat_item_content_text);
110 holder.tv_date = (TextView) v.findViewById(R.id.chat_item_date); 111 holder.tv_date = (TextView) v.findViewById(R.id.chat_item_date);
111 holder.tv_name = (TextView) v.findViewById(R.id.chat_item_name); 112 holder.tv_name = (TextView) v.findViewById(R.id.chat_item_name);
112 - holder.tv_teacher_bg= (TextView) v.findViewById(R.id.chat_item_taacher_bg); 113 + holder.tv_teacher_bg = (TextView) v.findViewById(R.id.chat_item_taacher_bg);
113 v.setTag(holder); 114 v.setTag(holder);
114 } else { 115 } else {
115 holder = (ViewHolder) v.getTag(); 116 holder = (ViewHolder) v.getTag();
116 } 117 }
117 - if (data.getTime()!=null){  
118 - holder.tv_date.setText(StringUtils.getDataTime("HH:mm")); 118 +
  119 + if (data.getTime() != null) {
  120 + String dataTime = data.getTime();
  121 + holder.tv_date.setText(dataTime);
119 holder.tv_date.setVisibility(View.VISIBLE); 122 holder.tv_date.setVisibility(View.VISIBLE);
  123 + }else {
  124 + holder.tv_date.setVisibility(View.GONE);
120 } 125 }
121 126
122 -  
123 //如果是文本类型,则隐藏图片,如果是图片则隐藏文本 127 //如果是文本类型,则隐藏图片,如果是图片则隐藏文本
124 if (data.getType() == Message.MSG_TYPE_TEXT) { 128 if (data.getType() == Message.MSG_TYPE_TEXT) {
125 holder.img_chatimage.setVisibility(View.GONE); 129 holder.img_chatimage.setVisibility(View.GONE);
@@ -161,6 +165,7 @@ public class ChatAdapter extends BaseAdapter { @@ -161,6 +165,7 @@ public class ChatAdapter extends BaseAdapter {
161 } else { 165 } else {
162 holder.tv_name.setText("学生"); 166 holder.tv_name.setText("学生");
163 } 167 }
  168 + holder.tv_teacher_bg.setVisibility(View.GONE);
164 holder.img_avatar.setImageResource(R.mipmap.student); 169 holder.img_avatar.setImageResource(R.mipmap.student);
165 break; 170 break;
166 case "host"://主持人/老师 171 case "host"://主持人/老师
@@ -177,6 +182,7 @@ public class ChatAdapter extends BaseAdapter { @@ -177,6 +182,7 @@ public class ChatAdapter extends BaseAdapter {
177 } else { 182 } else {
178 holder.tv_name.setText("主讲人"); 183 holder.tv_name.setText("主讲人");
179 } 184 }
  185 + holder.tv_teacher_bg.setVisibility(View.GONE);
180 holder.img_avatar.setImageResource(R.mipmap.student); 186 holder.img_avatar.setImageResource(R.mipmap.student);
181 break; 187 break;
182 case "assistant"://助教 188 case "assistant"://助教
@@ -185,6 +191,7 @@ public class ChatAdapter extends BaseAdapter { @@ -185,6 +191,7 @@ public class ChatAdapter extends BaseAdapter {
185 } else { 191 } else {
186 holder.tv_name.setText("助教"); 192 holder.tv_name.setText("助教");
187 } 193 }
  194 + holder.tv_teacher_bg.setVisibility(View.GONE);
188 holder.img_avatar.setImageResource(R.mipmap.student); 195 holder.img_avatar.setImageResource(R.mipmap.student);
189 break; 196 break;
190 case "record":// 暂时没用 197 case "record":// 暂时没用
@@ -193,6 +200,7 @@ public class ChatAdapter extends BaseAdapter { @@ -193,6 +200,7 @@ public class ChatAdapter extends BaseAdapter {
193 } else { 200 } else {
194 holder.tv_name.setText("学生"); 201 holder.tv_name.setText("学生");
195 } 202 }
  203 + holder.tv_teacher_bg.setVisibility(View.GONE);
196 holder.img_avatar.setImageResource(R.mipmap.student); 204 holder.img_avatar.setImageResource(R.mipmap.student);
197 break; 205 break;
198 } 206 }
@@ -204,6 +212,7 @@ public class ChatAdapter extends BaseAdapter { @@ -204,6 +212,7 @@ public class ChatAdapter extends BaseAdapter {
204 } else { 212 } else {
205 holder.tv_name.setText("学生"); 213 holder.tv_name.setText("学生");
206 } 214 }
  215 + holder.tv_teacher_bg.setVisibility(View.GONE);
207 holder.img_avatar.setImageResource(R.mipmap.student); 216 holder.img_avatar.setImageResource(R.mipmap.student);
208 break; 217 break;
209 case "host"://主持人/老师 218 case "host"://主持人/老师
@@ -220,6 +229,7 @@ public class ChatAdapter extends BaseAdapter { @@ -220,6 +229,7 @@ public class ChatAdapter extends BaseAdapter {
220 } else { 229 } else {
221 holder.tv_name.setText("主讲人"); 230 holder.tv_name.setText("主讲人");
222 } 231 }
  232 + holder.tv_teacher_bg.setVisibility(View.GONE);
223 holder.img_avatar.setImageResource(R.mipmap.student); 233 holder.img_avatar.setImageResource(R.mipmap.student);
224 break; 234 break;
225 case "assistant"://助教 235 case "assistant"://助教
@@ -228,6 +238,7 @@ public class ChatAdapter extends BaseAdapter { @@ -228,6 +238,7 @@ public class ChatAdapter extends BaseAdapter {
228 } else { 238 } else {
229 holder.tv_name.setText("助教"); 239 holder.tv_name.setText("助教");
230 } 240 }
  241 + holder.tv_teacher_bg.setVisibility(View.GONE);
231 holder.img_avatar.setImageResource(R.mipmap.student); 242 holder.img_avatar.setImageResource(R.mipmap.student);
232 break; 243 break;
233 case "record":// 暂时没用 244 case "record":// 暂时没用
@@ -236,6 +247,7 @@ public class ChatAdapter extends BaseAdapter { @@ -236,6 +247,7 @@ public class ChatAdapter extends BaseAdapter {
236 } else { 247 } else {
237 holder.tv_name.setText("学生"); 248 holder.tv_name.setText("学生");
238 } 249 }
  250 + holder.tv_teacher_bg.setVisibility(View.GONE);
239 holder.img_avatar.setImageResource(R.mipmap.student); 251 holder.img_avatar.setImageResource(R.mipmap.student);
240 break; 252 break;
241 } 253 }
@@ -45,11 +45,12 @@ public class Message { @@ -45,11 +45,12 @@ public class Message {
45 45
46 private Boolean isSend; 46 private Boolean isSend;
47 private Boolean sendSucces; 47 private Boolean sendSucces;
48 - private Date time; 48 + private String time;
  49 + public boolean TimeIsShow;
49 50
50 public Message(int type, int state, String userRole,String fromUserName, 51 public Message(int type, int state, String userRole,String fromUserName,
51 String fromUserAvatar, String toUserName, String toUserAvatar, 52 String fromUserAvatar, String toUserName, String toUserAvatar,
52 - String content, Boolean isSend, Boolean sendSucces, Date time) { 53 + String content, Boolean isSend, Boolean sendSucces, String time) {
53 super(); 54 super();
54 this.type = type; 55 this.type = type;
55 this.state = state; 56 this.state = state;
@@ -62,6 +63,7 @@ public class Message { @@ -62,6 +63,7 @@ public class Message {
62 this.isSend = isSend; 63 this.isSend = isSend;
63 this.sendSucces = sendSucces; 64 this.sendSucces = sendSucces;
64 this.time = time; 65 this.time = time;
  66 +
65 } 67 }
66 68
67 public Long getId() { 69 public Long getId() {
@@ -144,11 +146,11 @@ public class Message { @@ -144,11 +146,11 @@ public class Message {
144 this.sendSucces = sendSucces; 146 this.sendSucces = sendSucces;
145 } 147 }
146 148
147 - public Date getTime() { 149 + public String getTime() {
148 return time; 150 return time;
149 } 151 }
150 152
151 - public void setTime(Date time) { 153 + public void setTime(String time) {
152 this.time = time; 154 this.time = time;
153 } 155 }
154 156
@@ -161,4 +163,6 @@ public class Message { @@ -161,4 +163,6 @@ public class Message {
161 } 163 }
162 164
163 165
  166 +
  167 +
164 } 168 }
@@ -30,6 +30,7 @@ import com.xdy.util.ResUtil; @@ -30,6 +30,7 @@ import com.xdy.util.ResUtil;
30 30
31 import org.kymjs.kjframe.ui.ViewInject; 31 import org.kymjs.kjframe.ui.ViewInject;
32 import org.kymjs.kjframe.utils.KJLoger; 32 import org.kymjs.kjframe.utils.KJLoger;
  33 +import org.kymjs.kjframe.utils.StringUtils;
33 34
34 import java.io.File; 35 import java.io.File;
35 import java.util.ArrayList; 36 import java.util.ArrayList;
@@ -209,22 +210,41 @@ public class ChatFragment extends AppBaseFragment<LivePresenter> implements Live @@ -209,22 +210,41 @@ public class ChatFragment extends AppBaseFragment<LivePresenter> implements Live
209 }; 210 };
210 } 211 }
211 212
  213 + private String oldTime;
  214 + private String time;
  215 +
212 @Override 216 @Override
213 public void renderChatMsg(ChatMsgEntity entity) { 217 public void renderChatMsg(ChatMsgEntity entity) {
214 if (entity != null && adapter != null) { 218 if (entity != null && adapter != null) {
215 Message message; 219 Message message;
  220 + String dataTime = StringUtils.getDataTime("HH:mm");
  221 +
216 if (entity.fromNodeId.equals(AccountUtils.getUser().getNodeId().toString())) { 222 if (entity.fromNodeId.equals(AccountUtils.getUser().getNodeId().toString())) {
  223 + if (TextUtils.isEmpty(oldTime)) {
  224 + time = oldTime = dataTime;
  225 + } else if (dataTime.equals(oldTime)) {
  226 + time = null;
  227 + } else {
  228 + time = oldTime = dataTime;
  229 + }
217 message = new Message(Message.MSG_TYPE_TEXT, Message.MSG_STATE_SUCCESS, entity.fromRole, 230 message = new Message(Message.MSG_TYPE_TEXT, Message.MSG_STATE_SUCCESS, entity.fromRole,
218 entity.fromName, "", "", 231 entity.fromName, "", "",
219 - "", entity.message, true, true, replay ? null : new Date()); 232 + "", entity.message, true, true, replay ? null : time);
220 datas.add(message); 233 datas.add(message);
221 adapter.refresh(datas); 234 adapter.refresh(datas);
222 mRealListView.setSelection(adapter.getCount() - 1); 235 mRealListView.setSelection(adapter.getCount() - 1);
223 } else { 236 } else {
224 LogUtil.i("返回的聊天内容===" + entity.message); 237 LogUtil.i("返回的聊天内容===" + entity.message);
  238 + if (TextUtils.isEmpty(oldTime)) {
  239 + time = oldTime = dataTime;
  240 + } else if (dataTime.equals(oldTime)) {
  241 + time = null;
  242 + } else {
  243 + time = oldTime = dataTime;
  244 + }
225 message = new Message(Message.MSG_TYPE_TEXT, Message.MSG_STATE_SUCCESS, entity.fromRole, "", 245 message = new Message(Message.MSG_TYPE_TEXT, Message.MSG_STATE_SUCCESS, entity.fromRole, "",
226 "", entity.fromName, "", entity.message, false, 246 "", entity.fromName, "", entity.message, false,
227 - true, replay ? null : new Date()); 247 + true, replay ? null : time);
228 datas.add(message); 248 datas.add(message);
229 adapter.refresh(datas); 249 adapter.refresh(datas);
230 mRealListView.setSelection(adapter.getCount() - 1); 250 mRealListView.setSelection(adapter.getCount() - 1);
@@ -143,8 +143,8 @@ public class DocFragment extends AppBaseFragment<LivePresenter> implements LiveC @@ -143,8 +143,8 @@ public class DocFragment extends AppBaseFragment<LivePresenter> implements LiveC
143 @Override 143 @Override
144 public WrapDocBitMapEntity call(String s) { 144 public WrapDocBitMapEntity call(String s) {
145 145
  146 + WrapDocBitMapEntity wrapDocBitMapEntity = new WrapDocBitMapEntity();
146 try { 147 try {
147 - WrapDocBitMapEntity wrapDocBitMapEntity = new WrapDocBitMapEntity();  
148 if (s == null) { 148 if (s == null) {
149 wrapDocBitMapEntity.setNoDoc(true); 149 wrapDocBitMapEntity.setNoDoc(true);
150 wrapDocBitMapEntity.setBitmap(getNoDocBitmap()); 150 wrapDocBitMapEntity.setBitmap(getNoDocBitmap());
@@ -164,7 +164,8 @@ public class DocFragment extends AppBaseFragment<LivePresenter> implements LiveC @@ -164,7 +164,8 @@ public class DocFragment extends AppBaseFragment<LivePresenter> implements LiveC
164 } catch (ExecutionException e) { 164 } catch (ExecutionException e) {
165 e.printStackTrace(); 165 e.printStackTrace();
166 } 166 }
167 - return null; 167 + wrapDocBitMapEntity.setNoDoc(true);
  168 + return wrapDocBitMapEntity;
168 } 169 }
169 }) 170 })
170 .subscribeOn(Schedulers.io()) 171 .subscribeOn(Schedulers.io())
@@ -49,6 +49,7 @@ import com.xdy.home.widget.dialog.LoginDialog; @@ -49,6 +49,7 @@ import com.xdy.home.widget.dialog.LoginDialog;
49 import com.xdy.hybird.BridgeWebView; 49 import com.xdy.hybird.BridgeWebView;
50 import com.xdy.ui.viewgroup.NoScrollViewPager; 50 import com.xdy.ui.viewgroup.NoScrollViewPager;
51 import com.xdy.util.LogUtil; 51 import com.xdy.util.LogUtil;
  52 +import com.xdy.util.NetUtil;
52 import com.xdy.util.ResUtil; 53 import com.xdy.util.ResUtil;
53 import com.xdy.util.StringUtils; 54 import com.xdy.util.StringUtils;
54 import com.xdy.util.UIUtils; 55 import com.xdy.util.UIUtils;
@@ -100,7 +101,7 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -100,7 +101,7 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
100 private ImageView initPic; 101 private ImageView initPic;
101 private boolean sdkIsOk; 102 private boolean sdkIsOk;
102 private XDYJsInterface xdyJsInterface; 103 private XDYJsInterface xdyJsInterface;
103 - LoginDialog dialog; 104 + LoginDialog mLoginDialog;
104 private boolean replay; 105 private boolean replay;
105 private PLVideoTextureView mVideoView; 106 private PLVideoTextureView mVideoView;
106 private long classId; 107 private long classId;
@@ -115,6 +116,7 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -115,6 +116,7 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
115 private RelativeLayout mPauseContainer; 116 private RelativeLayout mPauseContainer;
116 private TextView mClassName; 117 private TextView mClassName;
117 private SurfaceView mSurfaceView = null; 118 private SurfaceView mSurfaceView = null;
  119 + private AlertDialog mErrorDialog;
118 120
119 public static LiveFragment newInstance(boolean replay, @NonNull long classId, @NonNull String portal, String role, String userId) { 121 public static LiveFragment newInstance(boolean replay, @NonNull long classId, @NonNull String portal, String role, String userId) {
120 LiveFragment liveFragment = new LiveFragment(); 122 LiveFragment liveFragment = new LiveFragment();
@@ -241,13 +243,9 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -241,13 +243,9 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
241 private boolean createView() { 243 private boolean createView() {
242 244
243 if (mSurfaceView == null) { 245 if (mSurfaceView == null) {
244 - /*  
245 - * useOpenGLES2:  
246 - * If with true: Check if system supports openGLES, if supported, it will choose openGLES.  
247 - * If with false: it will set with default surfaceView;  
248 - */  
249 - mSurfaceView = NTRenderer.CreateRenderer(mRootView.getContext(), true); 246 + mSurfaceView = NTRenderer.CreateRenderer(mRootView.getContext(), false);
250 } 247 }
  248 + mSurfaceView.setZOrderMediaOverlay(true);
251 249
252 if (mSurfaceView == null) { 250 if (mSurfaceView == null) {
253 Log.i(TAG, "Create render failed.."); 251 Log.i(TAG, "Create render failed..");
@@ -261,6 +259,12 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -261,6 +259,12 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
261 protected void initData() { 259 protected void initData() {
262 260
263 if (first) { 261 if (first) {
  262 + boolean b = NetUtil.checkNetwork(getContext());
  263 + if (!b) {
  264 + showErrorDialog(R.string.home_net_unconnected);
  265 + return;
  266 + }
  267 +
264 showLoading(); 268 showLoading();
265 chatFragment.setPresenter(mPresenter); 269 chatFragment.setPresenter(mPresenter);
266 docFragment.setPresenter(mPresenter); 270 docFragment.setPresenter(mPresenter);
@@ -388,7 +392,8 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -388,7 +392,8 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
388 xdyJsInterface.onDestroy(); 392 xdyJsInterface.onDestroy();
389 xdyJsInterface = null; 393 xdyJsInterface = null;
390 } 394 }
391 - UIUtils.closeDialog(dialog); 395 + UIUtils.closeDialog(mLoginDialog);
  396 + UIUtils.closeDialog(mErrorDialog);
392 super.onDestroyView(); 397 super.onDestroyView();
393 } 398 }
394 399
@@ -397,28 +402,33 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -397,28 +402,33 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
397 pop(); 402 pop();
398 } 403 }
399 404
  405 + boolean firstReplay = true;
400 406
401 @Override 407 @Override
402 public void renderLogin(boolean show, final boolean passwordRequired) { 408 public void renderLogin(boolean show, final boolean passwordRequired) {
403 - if (replay) { 409 + if (replay && firstReplay) {
  410 + firstReplay = false;
404 //要重置进度条 411 //要重置进度条
405 if (mSeekBar != null) 412 if (mSeekBar != null)
406 mSeekBar.setMax((int) mPresenter.getRecordPlaybackMaxTime()); 413 mSeekBar.setMax((int) mPresenter.getRecordPlaybackMaxTime());
  414 + boolean pause = mPresenter.getRecordStatus();
  415 + mPresenter.pauseAndStart(!pause);
  416 + showMediaContainer(TIME_OUT);
407 } 417 }
408 if (show) { 418 if (show) {
409 - if (dialog == null)  
410 - dialog = new LoginDialog(getActivity(), passwordRequired, this);  
411 - dialog.show();  
412 - dialog.setCanceledOnTouchOutside(false);  
413 - dialog.setBtnClick(new View.OnClickListener() { 419 + if (mLoginDialog == null)
  420 + mLoginDialog = new LoginDialog(getActivity(), passwordRequired, this);
  421 + mLoginDialog.show();
  422 + mLoginDialog.setCanceledOnTouchOutside(false);
  423 + mLoginDialog.setBtnClick(new View.OnClickListener() {
414 @Override 424 @Override
415 public void onClick(View view) { 425 public void onClick(View view) {
416 - String[] nameAndPwd = dialog.getNameAndPwd(); 426 + String[] nameAndPwd = mLoginDialog.getNameAndPwd();
417 mPresenter.joinClass(passwordRequired, nameAndPwd[0], nameAndPwd[1], false, false); 427 mPresenter.joinClass(passwordRequired, nameAndPwd[0], nameAndPwd[1], false, false);
418 } 428 }
419 }); 429 });
420 - } else if (dialog != null) {  
421 - UIUtils.closeDialog(dialog); 430 + } else if (mLoginDialog != null) {
  431 + UIUtils.closeDialog(mLoginDialog);
422 } 432 }
423 } 433 }
424 434
@@ -466,8 +476,14 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -466,8 +476,14 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
466 476
467 @Override 477 @Override
468 public void stopVideo() { 478 public void stopVideo() {
469 - initPic.setImageResource(R.mipmap.no_video);  
470 - initPic.setVisibility(View.VISIBLE); 479 + getBaseActivity().runOnUiThread(new Runnable() {
  480 + @Override
  481 + public void run() {
  482 + initPic.setImageResource(R.mipmap.no_video);
  483 + initPic.setVisibility(View.VISIBLE);
  484 + }
  485 + });
  486 +
471 if (!replay) { 487 if (!replay) {
472 mPresenter.close(); 488 mPresenter.close();
473 } else { 489 } else {
@@ -595,8 +611,7 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -595,8 +611,7 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
595 611
596 @Override 612 @Override
597 public boolean onBackPressedSupport() { 613 public boolean onBackPressedSupport() {
598 - if (sdkIsOk) {  
599 - 614 + if (sdkIsOk && mPresenter.sdkIsConnected()) {
600 final AlertDialog alertDialog = new AlertDialog.Builder(getContext()) 615 final AlertDialog alertDialog = new AlertDialog.Builder(getContext())
601 .setTitle(R.string.home_quit) 616 .setTitle(R.string.home_quit)
602 .setMessage(R.string.home_leave_class) 617 .setMessage(R.string.home_leave_class)
@@ -733,6 +748,56 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live @@ -733,6 +748,56 @@ public class LiveFragment extends AppBaseFragment<LivePresenter> implements Live
733 return mSurfaceView; 748 return mSurfaceView;
734 } 749 }
735 750
  751 + @Override
  752 + public void showErrorDialog(int reason) {
  753 + if (mErrorDialog != null)
  754 + return;
  755 +
  756 + mErrorDialog = new AlertDialog.Builder(getContext())
  757 + .setTitle(R.string.home_quit)
  758 + .setMessage(reason)
  759 + .setPositiveButton(R.string.home_confirm, new DialogInterface.OnClickListener() {
  760 + @Override
  761 + public void onClick(DialogInterface dialogInterface, int i) {
  762 + dialogInterface.dismiss();
  763 + quit();
  764 + }
  765 + })
  766 + .create();
  767 +
  768 +
  769 + mErrorDialog.show();
  770 + mErrorDialog.setCanceledOnTouchOutside(false);
  771 + }
  772 +
  773 + @Override
  774 + public void showErrorDialog(String reason) {
  775 +
  776 + if (mErrorDialog != null)
  777 + return;
  778 +
  779 + mErrorDialog = new AlertDialog.Builder(getContext())
  780 + .setTitle(R.string.home_quit)
  781 + .setMessage(reason)
  782 + .setPositiveButton(R.string.home_confirm, new DialogInterface.OnClickListener() {
  783 + @Override
  784 + public void onClick(DialogInterface dialogInterface, int i) {
  785 + dialogInterface.dismiss();
  786 + quit();
  787 + }
  788 + })
  789 + .create();
  790 + mErrorDialog.show();
  791 + mErrorDialog.setCanceledOnTouchOutside(false);
  792 + }
  793 +
  794 + @Override
  795 + public void resetSeekBar() {
  796 + if (mSeekBar != null) {
  797 + setProgress();
  798 + }
  799 + }
  800 +
736 private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() { 801 private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
737 802
738 public void onStartTrackingTouch(SeekBar bar) { 803 public void onStartTrackingTouch(SeekBar bar) {
@@ -19,20 +19,26 @@ public interface Constants { @@ -19,20 +19,26 @@ public interface Constants {
19 */ 19 */
20 String CLASS_INIT_SUCCESS = "class_init_success"; 20 String CLASS_INIT_SUCCESS = "class_init_success";
21 /** 21 /**
  22 + * 接收聊天
  23 + */
  24 + String CHAT_RECEIVE_MESSAGE = "chat_receive_message";
  25 + /**
22 * 课堂加入成功 26 * 课堂加入成功
23 */ 27 */
24 String CLASS_JOIN_SUCCESS = "class_join_success"; 28 String CLASS_JOIN_SUCCESS = "class_join_success";
25 - // 接收聊天  
26 - String CHAT_RECEIVE_MESSAGE = "chat_receive_message";  
27 /** 29 /**
28 * 课堂时间更新 30 * 课堂时间更新
29 */ 31 */
30 String CLASS_UPDATE_TIMER = "class_update_timer"; 32 String CLASS_UPDATE_TIMER = "class_update_timer";
31 /** 33 /**
32 - * 课堂状态更新 34 + * 课堂状态更新 2是暂停1是开始
33 */ 35 */
34 String CLASS_UPDATE_STATUS = "class_update_status"; 36 String CLASS_UPDATE_STATUS = "class_update_status";
35 /** 37 /**
  38 + * 结束课堂
  39 + */
  40 + String CLASS_EXIT = "class_exit";
  41 + /**
36 * 视频停止 42 * 视频停止
37 */ 43 */
38 String VIDEO_STOP = "video_stop"; 44 String VIDEO_STOP = "video_stop";
@@ -82,7 +88,7 @@ public interface Constants { @@ -82,7 +88,7 @@ public interface Constants {
82 /** 88 /**
83 * 录制未开始 89 * 录制未开始
84 */ 90 */
85 - int RECORD_PLAYING= 1; 91 + int RECORD_PLAYING = 1;
86 /** 92 /**
87 * 录制暂停 93 * 录制暂停
88 */ 94 */
@@ -97,11 +103,10 @@ public interface Constants { @@ -97,11 +103,10 @@ public interface Constants {
97 int RECORD_STOP = 4; 103 int RECORD_STOP = 4;
98 104
99 105
100 -  
101 /** 106 /**
102 * 错误标记 107 * 错误标记
103 */ 108 */
104 - String LEAVE_CLASS_CODE = "20000"; 109 + int LEAVE_CLASS_CODE = 20000;
105 /** 110 /**
106 * 获取录制回放数据失败 111 * 获取录制回放数据失败
107 */ 112 */
@@ -117,6 +117,22 @@ public interface LiveContract { @@ -117,6 +117,22 @@ public interface LiveContract {
117 * @return 117 * @return
118 */ 118 */
119 SurfaceView getSurfaceView(); 119 SurfaceView getSurfaceView();
  120 +
  121 + /**
  122 + * 展示错误界面
  123 + * @param reson
  124 + */
  125 + void showErrorDialog(int reson);
  126 + /**
  127 + * 展示错误界面
  128 + * @param reson
  129 + */
  130 + void showErrorDialog(String reson);
  131 +
  132 + /**
  133 + * 重置SEEKBAR
  134 + */
  135 + void resetSeekBar();
120 } 136 }
121 137
122 interface ChatView extends BaseView { 138 interface ChatView extends BaseView {
@@ -93,6 +93,10 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -93,6 +93,10 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
93 * 是否结束了 93 * 是否结束了
94 */ 94 */
95 private boolean isOver; 95 private boolean isOver;
  96 + /**
  97 + * SDK是否处于连接状态
  98 + */
  99 + private boolean connceted;
96 100
97 @Inject 101 @Inject
98 public LivePresenter(LiveContract.Model model, 102 public LivePresenter(LiveContract.Model model,
@@ -206,6 +210,9 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -206,6 +210,9 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
206 String pa = responseEntity.getParam(); 210 String pa = responseEntity.getParam();
207 211
208 switch (msg) { 212 switch (msg) {
  213 + case Constants.CLASS_EXIT:
  214 + mRootView.showErrorDialog(R.string.home_class_is_over);
  215 + break;
209 case Constants.CLASS_UPDATE_TIMER: 216 case Constants.CLASS_UPDATE_TIMER:
210 handleTime(pa); 217 handleTime(pa);
211 break; 218 break;
@@ -233,6 +240,7 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -233,6 +240,7 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
233 case Constants.CLASS_INIT_SUCCESS: //课堂初始化成功 240 case Constants.CLASS_INIT_SUCCESS: //课堂初始化成功
234 InitResponseEntity initRes = GsonUtil.json2Bean(pa, InitResponseEntity.class); 241 InitResponseEntity initRes = GsonUtil.json2Bean(pa, InitResponseEntity.class);
235 if (initRes != null) { 242 if (initRes != null) {
  243 + connceted = true;
236 mRootView.renderLogin(true, initRes.isPasswordRequired()); 244 mRootView.renderLogin(true, initRes.isPasswordRequired());
237 } else { 245 } else {
238 mRootView.quit(); 246 mRootView.quit();
@@ -241,6 +249,7 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -241,6 +249,7 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
241 case Constants.CLASS_JOIN_SUCCESS: 249 case Constants.CLASS_JOIN_SUCCESS:
242 UserEntity user = GsonUtil.json2Bean(pa, UserEntity.class); 250 UserEntity user = GsonUtil.json2Bean(pa, UserEntity.class);
243 if (user != null) { 251 if (user != null) {
  252 + connceted = true;
244 AccountUtils.saveUser(user); 253 AccountUtils.saveUser(user);
245 recordPlaybackMaxTime = user.getRecordPlaybackMaxTime(); 254 recordPlaybackMaxTime = user.getRecordPlaybackMaxTime();
246 String className = user.getClassName(); 255 String className = user.getClassName();
@@ -326,6 +335,10 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -326,6 +335,10 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
326 mModel.initRecordPlayback(classId, portal, userRole, userId); 335 mModel.initRecordPlayback(classId, portal, userRole, userId);
327 //停止视频 336 //停止视频
328 mRootView.stopVideo(); 337 mRootView.stopVideo();
  338 + currentTime = 0;
  339 + mRootView.resetSeekBar();
  340 + docView.clear();
  341 + chatView.clearChatHistory();
329 } 342 }
330 break; 343 break;
331 case Constants.RECORD_PAUSE: 344 case Constants.RECORD_PAUSE:
@@ -433,12 +446,22 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -433,12 +446,22 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
433 private void handleError(String param) { 446 private void handleError(String param) {
434 447
435 ErrorEvent errorEvent = GsonUtil.json2Bean(param, ErrorEvent.class); 448 ErrorEvent errorEvent = GsonUtil.json2Bean(param, ErrorEvent.class);
  449 +
436 if (errorEvent != null) { 450 if (errorEvent != null) {
437 - String reson = errorEvent.getReson();  
438 - if (!TextUtils.isEmpty(reson)) {  
439 - mRootView.showMessage(reson); 451 + String reason = errorEvent.getReson();
  452 + if (!TextUtils.isEmpty(reason) && !(Constants.LEAVE_CLASS_CODE == errorEvent.getCode())) {
  453 + connceted = false;
  454 + mRootView.showMessage(reason);
  455 + mRootView.quit();
  456 + } else {
  457 + if (!quit) {
  458 + connceted = false;
  459 + //MCU因非人为断开了链接(网络原因),提示框提示。如果是结束课堂,class_exit会提前收到,所以会先提示那个框
  460 + mRootView.showErrorDialog(R.string.home_net_unconnected);
  461 + } else {//手动退出课堂
  462 + mRootView.quit();
  463 + }
440 } 464 }
441 - mRootView.quit();  
442 } 465 }
443 } 466 }
444 467
@@ -774,13 +797,9 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -774,13 +797,9 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
774 private boolean pause = true; 797 private boolean pause = true;
775 798
776 public void pauseAndStart(boolean b) { 799 public void pauseAndStart(boolean b) {
777 - if (b) 800 + if (b) {
778 mModel.pauseRecordPlayback(); 801 mModel.pauseRecordPlayback();
779 - else {  
780 - if (isOver) {  
781 - docView.clear();  
782 - chatView.clearChatHistory();  
783 - } 802 + } else {
784 mModel.startRecordPlayback(); 803 mModel.startRecordPlayback();
785 } 804 }
786 } 805 }
@@ -811,6 +830,11 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -811,6 +830,11 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
811 this.currentTime = currentTime; 830 this.currentTime = currentTime;
812 } 831 }
813 832
  833 + public boolean sdkIsConnected() {
  834 +
  835 + return connceted;
  836 + }
  837 +
814 838
815 class EventHande implements SmartEventCallback { 839 class EventHande implements SmartEventCallback {
816 @Override 840 @Override
@@ -818,8 +842,6 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -818,8 +842,6 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
818 switch (code) { 842 switch (code) {
819 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED: 843 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
820 Log.i(TAG, "开始。。"); 844 Log.i(TAG, "开始。。");
821 - if (videoMode)  
822 - mRootView.hideInitPic();  
823 break; 845 break;
824 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING: 846 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
825 Log.i(TAG, "连接中。。"); 847 Log.i(TAG, "连接中。。");
@@ -838,6 +860,8 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac @@ -838,6 +860,8 @@ public class LivePresenter extends BasePresenter<LiveContract.Model, LiveContrac
838 break; 860 break;
839 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO: 861 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
840 Log.i(TAG, "分辨率信息: width: " + param1 + ", height: " + param2); 862 Log.i(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
  863 + if (videoMode)
  864 + mRootView.hideInitPic();
841 break; 865 break;
842 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED: 866 case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
843 Log.i(TAG, "收不到媒体数据,可能是url错误。。"); 867 Log.i(TAG, "收不到媒体数据,可能是url错误。。");
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:my="http://schemas.android.com/apk/res-auto" 3 xmlns:my="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent" 5 android:layout_width="match_parent"
5 android:layout_height="wrap_content" 6 android:layout_height="wrap_content"
6 android:orientation="vertical" 7 android:orientation="vertical"
@@ -29,26 +30,29 @@ @@ -29,26 +30,29 @@
29 android:id="@+id/chat_item_avatar" 30 android:id="@+id/chat_item_avatar"
30 style="@style/home_chat_item_avatar" 31 style="@style/home_chat_item_avatar"
31 android:layout_alignParentLeft="true"/> 32 android:layout_alignParentLeft="true"/>
  33 +
32 <LinearLayout 34 <LinearLayout
33 - android:layout_marginLeft="@dimen/ui_DIMEN_20.0PX"  
34 android:id="@+id/ll_item_name_parent" 35 android:id="@+id/ll_item_name_parent"
35 - android:orientation="horizontal"  
36 - android:layout_toRightOf="@id/chat_item_avatar"  
37 android:layout_width="wrap_content" 36 android:layout_width="wrap_content"
38 - android:layout_height="wrap_content"> 37 + android:layout_height="wrap_content"
  38 + android:layout_marginLeft="@dimen/ui_DIMEN_20.0PX"
  39 + android:layout_toRightOf="@id/chat_item_avatar"
  40 + android:orientation="horizontal">
  41 +
39 <TextView 42 <TextView
40 android:id="@+id/chat_item_taacher_bg" 43 android:id="@+id/chat_item_taacher_bg"
41 - android:textColor="@color/white"  
42 - android:text="老师"  
43 - android:visibility="gone" 44 + android:layout_width="wrap_content"
  45 + android:layout_height="wrap_content"
  46 + android:layout_marginRight="@dimen/ui_DIMEN_8.0PX"
  47 + android:background="@drawable/home_chat_teacher_bg"
  48 + android:gravity="center"
44 android:paddingLeft="@dimen/ui_DIMEN_10.0PX" 49 android:paddingLeft="@dimen/ui_DIMEN_10.0PX"
45 android:paddingRight="@dimen/ui_DIMEN_10.0PX" 50 android:paddingRight="@dimen/ui_DIMEN_10.0PX"
46 - android:gravity="center"  
47 - android:layout_marginRight="@dimen/ui_DIMEN_8.0PX" 51 + android:text="老师"
  52 + android:textColor="@color/white"
48 android:textSize="@dimen/ui_DIMEN_20.0PX" 53 android:textSize="@dimen/ui_DIMEN_20.0PX"
49 - android:background="@drawable/home_chat_teacher_bg"  
50 - android:layout_width="wrap_content"  
51 - android:layout_height="wrap_content" /> 54 + android:visibility="gone"/>
  55 +
52 <TextView 56 <TextView
53 android:id="@+id/chat_item_name" 57 android:id="@+id/chat_item_name"
54 android:layout_width="wrap_content" 58 android:layout_width="wrap_content"
@@ -59,7 +63,6 @@ @@ -59,7 +63,6 @@
59 </LinearLayout> 63 </LinearLayout>
60 64
61 65
62 -  
63 <RelativeLayout 66 <RelativeLayout
64 android:id="@+id/chat_item_layout_content" 67 android:id="@+id/chat_item_layout_content"
65 style="@style/home_chat_item_content" 68 style="@style/home_chat_item_content"
@@ -72,12 +75,12 @@ @@ -72,12 +75,12 @@
72 android:id="@+id/chat_item_content_text" 75 android:id="@+id/chat_item_content_text"
73 style="@style/home_chat_item_text_content" 76 style="@style/home_chat_item_text_content"
74 android:layout_centerInParent="true" 77 android:layout_centerInParent="true"
  78 + android:background="@drawable/chat_pop_receive"
75 android:gravity="start|center_vertical" 79 android:gravity="start|center_vertical"
76 android:paddingLeft="@dimen/ui_DIMEN_30.0PX" 80 android:paddingLeft="@dimen/ui_DIMEN_30.0PX"
77 android:paddingRight="@dimen/ui_DIMEN_10.0PX" 81 android:paddingRight="@dimen/ui_DIMEN_10.0PX"
78 -  
79 - android:background="@drawable/chat_pop_receive"  
80 - my:emojiconSize="@dimen/ui_DIMEN_40.0PX"/> 82 + my:emojiconSize="@dimen/ui_DIMEN_40.0PX"
  83 + tools:text="fasdfasdfasdfasdfasdfasdfasdfasddfasdfasdfasdfasdffasdfasdfsadfsadfasddfasdfasfdasdfasdfsafasdfadf"/>
81 84
82 <ImageView 85 <ImageView
83 android:id="@+id/chat_item_content_image" 86 android:id="@+id/chat_item_content_image"
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:my="http://schemas.android.com/apk/res-auto" 3 xmlns:my="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent" 5 android:layout_width="match_parent"
5 android:layout_height="wrap_content" 6 android:layout_height="wrap_content"
6 android:orientation="vertical" 7 android:orientation="vertical"
@@ -71,11 +72,12 @@ @@ -71,11 +72,12 @@
71 style="@style/home_chat_item_text_content" 72 style="@style/home_chat_item_text_content"
72 android:layout_centerVertical="true" 73 android:layout_centerVertical="true"
73 android:background="@drawable/chat_pop_send" 74 android:background="@drawable/chat_pop_send"
74 - android:gravity="end|center_vertical" 75 + android:gravity="start|center_vertical"
75 android:textColor="@color/white" 76 android:textColor="@color/white"
76 android:includeFontPadding="false" 77 android:includeFontPadding="false"
77 android:paddingLeft="@dimen/ui_DIMEN_10.0PX" 78 android:paddingLeft="@dimen/ui_DIMEN_10.0PX"
78 android:paddingRight="@dimen/ui_DIMEN_30.0PX" 79 android:paddingRight="@dimen/ui_DIMEN_30.0PX"
  80 + tools:text="fasdfasdfasdfasdfasdfasdfasdfasddfasdfasdfasdfsadfsadfasddfasdfasfdasdfasdfsafasdfadf"
79 my:emojiconSize="@dimen/ui_DIMEN_40.0PX"/> 81 my:emojiconSize="@dimen/ui_DIMEN_40.0PX"/>
80 82
81 <ImageView 83 <ImageView
@@ -13,13 +13,13 @@ @@ -13,13 +13,13 @@
13 style="@style/home_site_input_style" 13 style="@style/home_site_input_style"
14 android:layout_marginTop="@dimen/ui_DIMEN_20.0PX"> 14 android:layout_marginTop="@dimen/ui_DIMEN_20.0PX">
15 15
16 - <!-- 709902904 472732494 2067973545--> 16 + <!-- 709902904 472732494 2067973545 1895498438-->
17 <android.support.v7.widget.AppCompatEditText 17 <android.support.v7.widget.AppCompatEditText
18 android:id="@+id/acet_classid" 18 android:id="@+id/acet_classid"
19 style="@style/ui_match_wrap" 19 style="@style/ui_match_wrap"
20 android:hint="@string/home_classid_hint" 20 android:hint="@string/home_classid_hint"
21 android:inputType="number" 21 android:inputType="number"
22 - android:text="2067973545"/> 22 + android:text="472732494"/>
23 </android.support.design.widget.TextInputLayout> 23 </android.support.design.widget.TextInputLayout>
24 24
25 <android.support.design.widget.TextInputLayout 25 <android.support.design.widget.TextInputLayout
@@ -17,11 +17,13 @@ @@ -17,11 +17,13 @@
17 <string name="home_password_cannot_be_null">密码不能为空</string> 17 <string name="home_password_cannot_be_null">密码不能为空</string>
18 <string name="home_confirm">确认</string> 18 <string name="home_confirm">确认</string>
19 <string name="home_quit">退出</string> 19 <string name="home_quit">退出</string>
20 - <string name="home_leave_class">是否离开课堂</string> 20 + <string name="home_leave_class">您确定要退出课堂吗?</string>
  21 + <string name="home_net_unconnected">您的设备网络断开状态,请重新进入</string>
21 <string name="home_cancel">取消</string> 22 <string name="home_cancel">取消</string>
22 <string name="home_no_stream">暂无推流可用</string> 23 <string name="home_no_stream">暂无推流可用</string>
23 <string name="home_parse_error">解析出错</string> 24 <string name="home_parse_error">解析出错</string>
24 <string name="home_cannot_push_no_camere">无法获取摄像头权限,不能推流</string> 25 <string name="home_cannot_push_no_camere">无法获取摄像头权限,不能推流</string>
25 <string name="home_no_audio_permission">无法传输音频,请检查你的麦克风权限</string> 26 <string name="home_no_audio_permission">无法传输音频,请检查你的麦克风权限</string>
26 <string name="home_no_resouce_to_open">暂无可用音视频</string> 27 <string name="home_no_resouce_to_open">暂无可用音视频</string>
  28 + <string name="home_class_is_over">课堂已结束</string>
27 </resources> 29 </resources>