Commit 20b3bf3c authored by zhangww's avatar zhangww
Browse files

3.16.0

1.添加答题器相关功能
2.优化网络波动造成的播放视频后的自动重连功能
3.功能优化
parent 0ab4cfa5
......@@ -10,6 +10,7 @@ android {
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
buildTypes {
......@@ -32,30 +33,31 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "androidx.multidex:multidex:2.0.1"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
//获得场景视频SDK,必须引入
implementation 'com.bokecc:CCVOD:3.15.4'
//播放加密视频必须引用drm
implementation 'com.bokecc:CCVOD:3.16.0'
implementation 'com.bokecc:drm:1.2.1'
//使用DWIjkMediaPlayer 倍速播放器引入
// implementation 'com.bokecc:speedplay:2.19.0'
//上传视频时使用压缩功能时需要引用
implementation 'com.bokecc:CompressVideoLib:1.0.0'
//使用投屏功能需要引用
implementation 'com.bokecc:ProjectionLib:1.7.0'
//使用Vr播放功能时需要引入
implementation 'com.bokecc:VrPlayLib:1.0.0'
implementation 'com.bokecc:CompressVideoLib:1.0.0'
//使用投屏功能需要引用
//弹幕
implementation 'com.github.ctiao:DanmakuFlameMaster:0.9.25'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
//noinspection GradleCompatible
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.umeng.umsdk:common:9.4.0'
implementation 'com.umeng.umsdk:asms:1.2.3'
implementation 'com.umeng.umsdk:apm:1.3.1'
}
......@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
......@@ -12,7 +13,7 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:name=".HuodeApplication"
android:name=".HuoDeApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
......
......@@ -2,13 +2,14 @@ package com.bokecc.vod;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.bokecc.vod.utils.MultiUtils;
......
......@@ -8,19 +8,16 @@ package com.bokecc.vod;
public class ConfigUtil {
/**
* 账号ID 可以替换为自己的USER_ID
* 391E6E3340A00767
*/
public static final String USER_ID = "391E6E3340A00767";
/**
* 可以替换为自己的API_KEY
* T8WdOUuvFEiOsou1xjDr4U73v12M7iNa
*/
public static final String API_KEY = "T8WdOUuvFEiOsou1xjDr4U73v12M7iNa";
/**
* 获取视频信息的地址
*/
public final static String DATA_URL = "https://p.bokecc.com/demo/videoinfo.json";
public final static String DATA_URL = "n";
/**
* 配置下载文件路径
......
package com.bokecc.vod;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.widget.Toast;
import androidx.multidex.MultiDexApplication;
import com.bokecc.sdk.mobile.download.VodDownloadManager;
import com.bokecc.sdk.mobile.drm.DRMServer;
import com.bokecc.sdk.mobile.util.DWSdkStorage;
import com.bokecc.sdk.mobile.util.DWStorageUtil;
import com.bokecc.vod.data.ObjectBox;
import com.bokecc.vod.utils.MultiUtils;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
public class HuodeApplication extends Application {
/**
* HuodeApplication
* @author Zhang
*/
@SuppressLint("StaticFieldLeak")
public class HuoDeApplication extends MultiDexApplication {
private static DRMServer drmServer;
public static Context context;
......@@ -28,11 +38,12 @@ public class HuodeApplication extends Application {
ObjectBox.init(this);
initDWStorage();
startDRMServer();
//初始化VodDownloadManager
String downloadPath = MultiUtils.createDownloadPath();
//使用VodDownloadManager需要以单例VodDownloadManager.getInstance()的形式调用
VodDownloadManager.getInstance().init(HuodeApplication.getContext(), ConfigUtil.USER_ID, ConfigUtil.API_KEY, downloadPath);
VodDownloadManager.getInstance().init(HuoDeApplication.getContext(), ConfigUtil.USER_ID, ConfigUtil.API_KEY, downloadPath);
UMConfigure.init( context, getString(R.string.umeng_app_key), "HuoDeVod", 0,null);
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO);
}
public static Context getContext() {
......@@ -42,13 +53,15 @@ public class HuodeApplication extends Application {
public static SharedPreferences getSp(){
return sp;
}
// 启动DRMServer
/**
* 启动DRMServer
*/
public void startDRMServer() {
if (drmServer == null) {
drmServer = new DRMServer();
drmServer.setRequestRetryCount(20);
}
try {
drmServer.start();
setDrmServerPort(drmServer.getPort());
......@@ -58,9 +71,8 @@ public class HuodeApplication extends Application {
}
private void initDWStorage() {
DWSdkStorage myDWSdkStorage = new DWSdkStorage() {
private SharedPreferences sp = getApplicationContext().getSharedPreferences("mystorage", MODE_PRIVATE);
DWSdkStorage myStorage = new DWSdkStorage() {
private final SharedPreferences sp = getApplicationContext().getSharedPreferences("mystorage", MODE_PRIVATE);
@Override
public void put(String key, String value) {
SharedPreferences.Editor editor = sp.edit();
......@@ -73,8 +85,7 @@ public class HuodeApplication extends Application {
return sp.getString(key, "");
}
};
DWStorageUtil.setDWSdkStorage(myDWSdkStorage);
DWStorageUtil.setDWSdkStorage(myStorage);
}
@Override
......@@ -90,7 +101,7 @@ public class HuodeApplication extends Application {
}
public void setDrmServerPort(int drmServerPort) {
this.drmServerPort = drmServerPort;
HuoDeApplication.drmServerPort = drmServerPort;
}
public static DRMServer getDRMServer() {
......
......@@ -5,10 +5,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
......@@ -17,6 +13,11 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.bokecc.sdk.mobile.download.DownloadOperator;
import com.bokecc.sdk.mobile.download.VodDownloadBean;
import com.bokecc.sdk.mobile.download.VodDownloadManager;
......
package com.bokecc.vod.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bokecc.sdk.mobile.entry.AnswerSheetInfo;
import com.bokecc.vod.R;
import com.bokecc.vod.callback.ChoiceSelectListener;
import java.util.ArrayList;
import java.util.List;
/**
* ChoiceAdapter
*
* @author Zhang
*/
public class ChoiceAdapter extends RecyclerView.Adapter<ChoiceAdapter.ChoiceHolder> {
private final Context context;
private final List<AnswerSheetInfo.Answer> contentList;
private final List<AnswerSheetInfo.Answer> selectedAnswer;
private boolean multiple;
private int perSelectIndex = -1;
private ChoiceSelectListener choiceSelectListener;
public ChoiceAdapter(Context context, List<AnswerSheetInfo.Answer> contentList) {
this.context = context;
this.contentList = contentList;
selectedAnswer = new ArrayList<>();
}
public void setChoiceSelectListener(ChoiceSelectListener choiceSelectListener) {
this.choiceSelectListener = choiceSelectListener;
}
public void setMultiple(boolean multiple) {
this.multiple = multiple;
}
public boolean isMultiple() {
return multiple;
}
@NonNull
@Override
public ChoiceHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_choice, parent, false);
return new ChoiceHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ChoiceHolder holder, int position) {
holder.choiceItem.setText(contentList.get(position).getContent());
holder.choiceItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean currentSelected;
if (!isMultiple()) {
if (perSelectIndex == holder.getLayoutPosition()) {
return;
}
holder.choiceItem.setBackgroundResource(R.mipmap.answer_selected);
selectedAnswer.clear();
selectedAnswer.add(contentList.get(holder.getLayoutPosition()));
currentSelected = true;
if (perSelectIndex != -1) {
contentList.get(perSelectIndex).setSelect(false);
}
contentList.get(holder.getLayoutPosition()).setSelect(true);
} else {
if (selectedAnswer.contains(contentList.get(holder.getLayoutPosition()))){
selectedAnswer.remove(contentList.get(holder.getLayoutPosition()));
contentList.get(holder.getLayoutPosition()).setSelect(false);
currentSelected = false;
} else {
selectedAnswer.add(contentList.get(holder.getLayoutPosition()));
contentList.get(holder.getLayoutPosition()).setSelect(true);
currentSelected = true;
}
}
if (choiceSelectListener != null) {
choiceSelectListener.onChoiceSelectStateChange(selectedAnswer, holder.getLayoutPosition(), perSelectIndex, currentSelected);
}
perSelectIndex = holder.getLayoutPosition();
}
});
}
public List<AnswerSheetInfo.Answer> getSelectedAnswer() {
return selectedAnswer == null ? new ArrayList<AnswerSheetInfo.Answer>() : selectedAnswer;
}
@Override
public int getItemCount() {
return contentList == null ? 0 : contentList.size();
}
public static class ChoiceHolder extends RecyclerView.ViewHolder {
public Button choiceItem;
public ChoiceHolder(@NonNull View itemView) {
super(itemView);
choiceItem = itemView.findViewById(R.id.choiceItem);
}
}
}
package com.bokecc.vod.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.recyclerview.widget.RecyclerView;
import com.bokecc.vod.R;
import com.bokecc.vod.data.DanmuColorInfo;
......
......@@ -2,8 +2,6 @@ package com.bokecc.vod.adapter;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
......@@ -14,6 +12,9 @@ import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
import com.bokecc.sdk.mobile.util.HttpUtil;
import com.bokecc.vod.R;
import com.bokecc.vod.data.ExeQuestion;
......
......@@ -16,8 +16,8 @@ import java.util.List;
public class PlayListAdapter extends BaseAdapter {
private List<HuodeVideoInfo> datas;
private LayoutInflater layoutInflater;
private Context context;
private final LayoutInflater layoutInflater;
private final Context context;
public PlayListAdapter(Context context, List<HuodeVideoInfo> datas) {
this.context = context;
......@@ -46,43 +46,42 @@ public class PlayListAdapter extends BaseAdapter {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.item_play_list, null);
holder = new ViewHolder();
holder.iv_video_img = (ImageView) convertView.findViewById(R.id.iv_video_img);
holder.iv_select_button = (ImageView) convertView.findViewById(R.id.iv_select_button);
holder.tv_video_title = (TextView) convertView.findViewById(R.id.tv_video_title);
holder.tv_video_time = (TextView) convertView.findViewById(R.id.tv_video_time);
holder.ivVideoImg = (ImageView) convertView.findViewById(R.id.iv_video_img);
holder.ivSelectButton = (ImageView) convertView.findViewById(R.id.iv_select_button);
holder.tvVideoTitle = (TextView) convertView.findViewById(R.id.tv_video_title);
holder.tvVideoTime = (TextView) convertView.findViewById(R.id.tv_video_time);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
HuodeVideoInfo videoInfo = datas.get(position);
if (videoInfo != null) {
MultiUtils.showCornerVideoCover(holder.iv_video_img,videoInfo.getVideoCover());
holder.tv_video_title.setText(videoInfo.getVideoTitle());
holder.tv_video_time.setText(videoInfo.getVideoTime());
MultiUtils.showCornerVideoCover(holder.ivVideoImg,videoInfo.getVideoCover());
holder.tvVideoTitle.setText(videoInfo.getVideoTitle());
holder.tvVideoTime.setText(videoInfo.getVideoTime());
if (videoInfo.isShowSelectButton()){
holder.iv_select_button.setVisibility(View.VISIBLE);
holder.ivSelectButton.setVisibility(View.VISIBLE);
}else {
holder.iv_select_button.setVisibility(View.GONE);
holder.ivSelectButton.setVisibility(View.GONE);
}
if (videoInfo.isSelectedDownload()){
holder.iv_select_button.setImageResource(R.mipmap.iv_selected);
holder.ivSelectButton.setImageResource(R.mipmap.iv_selected);
}else {
holder.iv_select_button.setImageResource(R.mipmap.iv_unselected);
holder.ivSelectButton.setImageResource(R.mipmap.iv_unselected);
}
if (videoInfo.isSelected()){
holder.tv_video_title.setTextColor(context.getResources().getColor(R.color.orange));
holder.tvVideoTitle.setTextColor(context.getResources().getColor(R.color.orange));
}else {
holder.tv_video_title.setTextColor(context.getResources().getColor(R.color.videoTitle));
holder.tvVideoTitle.setTextColor(context.getResources().getColor(R.color.videoTitle));
}
}
return convertView;
}
class ViewHolder {
ImageView iv_video_img;
ImageView iv_select_button;
TextView tv_video_title;
TextView tv_video_time;
static class ViewHolder {
ImageView ivVideoImg;
ImageView ivSelectButton;
TextView tvVideoTitle;
TextView tvVideoTime;
}
}
package com.bokecc.vod.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bokecc.sdk.mobile.entry.AnswerCommitResult;
import com.bokecc.sdk.mobile.entry.AnswerSheetInfo;
import com.bokecc.vod.R;
import com.bokecc.vod.utils.MultiUtils;
import java.util.List;
/**
* StatisticsAdapter
* @author Zhang
*/
public class StatisticsAdapter extends RecyclerView.Adapter<StatisticsAdapter.StatisticsHolder> {
private final Context context;
private final List<AnswerCommitResult> resultList;
private final AnswerSheetInfo answerSheetInfo;
public StatisticsAdapter(Context context, AnswerSheetInfo answerSheetInfo,List<AnswerCommitResult> resultList) {
this.context=context;
this.answerSheetInfo=answerSheetInfo;
this.resultList=resultList;
}
@NonNull
@Override
public StatisticsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.item_statistics,parent,false);
return new StatisticsHolder(view);
}
@SuppressLint("DefaultLocale")
@Override
public void onBindViewHolder(@NonNull StatisticsHolder holder, int position) {
holder.selectScale.setText(String.format("%d%%", resultList.get(position).getScale()));
holder.selectNum.setText(String.valueOf(resultList.get(position).getNum()));
float i = resultList.get(position).getScale() / 100.00f;
int height = (int) (MultiUtils.dipToPx(context,88)*i);
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,height);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
holder.selectScaleView.setLayoutParams(params);
AnswerSheetInfo.Answer answerInfoById = getAnswerInfoById(resultList.get(position).getId());
if (answerInfoById!=null){
holder.answerContent.setText(answerInfoById.getContent());
if (answerInfoById.isRight()){
holder.answerContent.setTextColor(Color.parseColor("#1BBD79"));
holder.selectScaleView.setBackground(context.getResources().getDrawable(R.drawable.shape_statistics_right_bg));
}else {
holder.answerContent.setTextColor(Color.parseColor("#F55757"));
holder.selectScaleView.setBackground(context.getResources().getDrawable(R.drawable.shape_statistics_wrong_bg));
}
holder.selectCurrentResult.setVisibility(answerInfoById.isSelect()?View.VISIBLE:View.GONE);
}
}
private AnswerSheetInfo.Answer getAnswerInfoById(int id){
for (AnswerSheetInfo.Answer answer:answerSheetInfo.getAnswers()){
if (answer.getId()==id){
return answer;
}
}
return null;
}
@Override
public int getItemCount() {
return resultList==null?0:resultList.size();
}
static class StatisticsHolder extends RecyclerView.ViewHolder{
View selectScaleView;
TextView selectScale,selectNum;
ImageView selectCurrentResult;
TextView answerContent;
public StatisticsHolder(@NonNull View itemView) {
super(itemView);
selectScaleView=itemView.findViewById(R.id.selectScaleView);
selectScale=itemView.findViewById(R.id.selectScale);
selectNum=itemView.findViewById(R.id.selectNum);
selectCurrentResult=itemView.findViewById(R.id.selectCurrentResult);
answerContent=itemView.findViewById(R.id.answerContent);
}
}
}
package com.bokecc.vod.callback;
/**
* AnswerSheetCallback
* @author Zhang
*/
public interface AnswerSheetCallback {
/**
* 判断题,选择判断正确选项
*/
void onJudgeWrightOption();
/**
* 判断题,选择判断错误选项
*/
void onJudgeWrongOption();
/**
* 判断题,选择判断错误选项