huangxinbao

add drop resource

正在显示 138 个修改的文件 包含 2815 行增加2030 行删除
... ... @@ -16,7 +16,10 @@ android {
}
buildTypes {
release {
//是否混淆
minifyEnabled false
zipAlignEnabled true
// shrinkResources true//去除无用的resource文件,第一次使用
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
... ... @@ -32,7 +35,6 @@ dependencies {
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile project(':xdy')
compile files('libs/pldroid-player-1.5.1.jar')
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.5.1'
... ... @@ -43,15 +45,16 @@ dependencies {
compile 'org.kymjs.kjframe:kjframe:2.6'
compile 'io.reactivex:rxjava:1.0.9'
compile 'io.reactivex:rxandroid:0.24.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
// compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.nineoldandroids:library:2.4.0'
compile 'me.yokeyword:fragmentation:0.10.3'
compile 'com.qiniu:happy-dns:0.2.+'
compile 'com.android.support:support-v4:25.3.1'
// compile 'com.android.support:support-v4:25.3.1'
testCompile 'junit:junit:4.12'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
compile 'com.qiniu:happy-dns:0.2.+'
compile 'org.greenrobot:eventbus:3.0.0'
compile 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
compile project(':iOS_Dialog_Library')
compile project(':xdy')
}
... ...
... ... @@ -15,3 +15,10 @@
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keep class com.eventhandle.**{*;}
-keep class com.ntjbase.**{*;}
-keep class com.videoengine.**{*;}
-keep class com.voiceengine.**{*;}
-keep class com.mang.xdy.**{*;}
\ No newline at end of file
... ...
package com.mang.xdy.demo;
package com.mang.xuedianyun.android;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mang.xdy.demo">
package="com.mang.xuedianyun.android">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
... ... @@ -36,13 +36,13 @@
<application
android:name=".application.XdyApplicaiton"
android:name="com.mang.xuedianyun.android.application.XdyApplicaiton"
android:allowBackup="true"
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
<activity android:name="com.mang.xuedianyun.android.MainActivity"
android:windowSoftInputMode="adjustPan|stateHidden"
android:screenOrientation="portrait">
<intent-filter>
... ... @@ -51,10 +51,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activity.VideoPlayActivity"
<activity android:name="com.mang.xuedianyun.android.activity.VideoPlayActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden"
>
</activity>
</application>
... ...
package com.mang.xdy.demo;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import com.google.gson.Gson;
import com.mang.xdy.demo.activity.VideoPlayActivity;
import com.mang.xdy.demo.bean.JoinClassBean;
import com.mang.xdy.demo.utils.ToastUtil;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edt_home_classId)
EditText edtHomeClassId;
@BindView(R.id.edt_home_role)
EditText edtHomeRole;
@BindView(R.id.edt_home_serviceIp)
EditText edtHomeServiceIp;
@BindView(R.id.edt_home_userId)
EditText edtHomeUserId;
@BindView(R.id.btn_home_enter_class)
Button btnHomeEnterClass;
@BindView(R.id.btn_home_enter_publisher)
Button btn_home_enter_publisher;
@BindView(R.id.rl_home_close)
RelativeLayout rl_home_close;
/*一进来就要初始化,让后再调 加入课堂*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rl_home_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@OnClick({R.id.btn_home_enter_class,R.id.btn_home_enter_publisher})
public void onViewClicked(View view) {
if(TextUtils.isEmpty(joinClass())){
return;
}
ArrayList<String> arrayList=new ArrayList<>();
switch (view.getId()){
case R.id.btn_home_enter_class:
Intent intent=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("normal");
intent.putStringArrayListExtra("init",arrayList);
startActivity(intent);
break;
case R.id.btn_home_enter_publisher:
Intent intents=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("");
intents.putStringArrayListExtra("init",arrayList);
startActivity(intents);
break;
}
}
private String classId="";
private String userRole="";
private String serviceIp="";
private String userId="";
public boolean getLoginInfo(){
classId=edtHomeClassId.getText().toString();
userRole=edtHomeRole.getText().toString();
serviceIp=edtHomeServiceIp.getText().toString();
userId=edtHomeUserId.getText().toString();
if(TextUtils.isEmpty(classId)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_classId),this);
return false;
}
if(TextUtils.isEmpty(serviceIp)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_portal),this);
return false;
}
if(TextUtils.isEmpty(userRole)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_role),this);
return false;
}
if(TextUtils.isEmpty(userId)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_userId),this);
return false;
}
return true;
}
public String joinClass(){
if(getLoginInfo()) {
JoinClassBean joinClassBean = new JoinClassBean();
joinClassBean.setClassId(Integer.parseInt(classId));
joinClassBean.setUserRole(userRole);
joinClassBean.setPortal(serviceIp);
joinClassBean.setUserId(Integer.parseInt(userId));
joinClassBean.setUserName("");
String joinclass = new Gson().toJson(joinClassBean);
// XdyLogUtil.e("init 初始化", joinclass);
return joinclass;
}else{
return "";
}
}
}
package com.mang.xuedianyun.android;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import com.google.gson.Gson;
import com.mang.xuedianyun.android.activity.VideoPlayActivity;
import com.mang.xuedianyun.android.bean.JoinClassBean;
import com.mang.xuedianyun.android.utils.ToastUtil;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edt_home_classId)
EditText edtHomeClassId;
@BindView(R.id.edt_home_role)
EditText edtHomeRole;
@BindView(R.id.edt_home_serviceIp)
EditText edtHomeServiceIp;
@BindView(R.id.edt_home_userId)
EditText edtHomeUserId;
@BindView(R.id.btn_home_enter_class)
Button btnHomeEnterClass;
@BindView(R.id.btn_home_enter_publisher)
Button btn_home_enter_publisher;
@BindView(R.id.rl_home_close)
RelativeLayout rl_home_close;
/*一进来就要初始化,让后再调 加入课堂*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rl_home_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@OnClick({R.id.btn_home_enter_class,R.id.btn_home_enter_publisher})
public void onViewClicked(View view) {
if(TextUtils.isEmpty(joinClass())){
return;
}
ArrayList<String> arrayList=new ArrayList<>();
switch (view.getId()){
case R.id.btn_home_enter_class:
Intent intent=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("normal");
intent.putStringArrayListExtra("init",arrayList);
startActivity(intent);
break;
case R.id.btn_home_enter_publisher:
Intent intents=new Intent(MainActivity.this, VideoPlayActivity.class);
arrayList.clear();
arrayList.add(joinClass());
arrayList.add("");
intents.putStringArrayListExtra("init",arrayList);
startActivity(intents);
break;
}
}
private String classId="";
private String userRole="";
private String serviceIp="";
private String userId="";
public boolean getLoginInfo(){
classId=edtHomeClassId.getText().toString();
userRole=edtHomeRole.getText().toString();
serviceIp=edtHomeServiceIp.getText().toString();
userId=edtHomeUserId.getText().toString();
if(TextUtils.isEmpty(classId)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_classId),this);
return false;
}
if(TextUtils.isEmpty(serviceIp)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_portal),this);
return false;
}
if(TextUtils.isEmpty(userRole)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_role),this);
return false;
}
if(TextUtils.isEmpty(userId)){
ToastUtil.showToast(getResources().getString(R.string.main_login_error_userId),this);
return false;
}
return true;
}
public String joinClass(){
if(getLoginInfo()) {
JoinClassBean joinClassBean = new JoinClassBean();
joinClassBean.setClassId(Integer.parseInt(classId));
joinClassBean.setUserRole(userRole);
joinClassBean.setPortal(serviceIp);
joinClassBean.setUserId(Integer.parseInt(userId));
joinClassBean.setUserName("");
String joinclass = new Gson().toJson(joinClassBean);
// XdyLogUtil.e("init 初始化", joinclass);
return joinclass;
}else{
return "";
}
}
}
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.adapter;
package com.mang.xuedianyun.android.adapter;
import android.content.Context;
import android.text.TextUtils;
... ... @@ -28,12 +28,12 @@ import android.widget.TextView;
import com.mang.xdy.common.Constants;
import com.mang.xdy.utils.SPUtil;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.bean.JoinClassSuccessEntity;
import com.mang.xdy.demo.bean.Message;
import com.mang.xdy.demo.fragment.ChatFragment;
import com.mang.xdy.demo.utils.JsonUtil;
import com.mang.xdy.demo.widget.chat.UrlUtils;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.bean.JoinClassSuccessEntity;
import com.mang.xuedianyun.android.bean.Message;
import com.mang.xuedianyun.android.fragment.ChatFragment;
import com.mang.xuedianyun.android.utils.JsonUtil;
import com.mang.xuedianyun.android.widget.chat.UrlUtils;
import org.kymjs.kjframe.KJBitmap;
... ...
... ... @@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.adapter;
package com.mang.xuedianyun.android.adapter;
import android.widget.AbsListView;
import android.widget.ImageView;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.bean.Faceicon;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.bean.Faceicon;
import org.kymjs.kjframe.KJBitmap;
import org.kymjs.kjframe.widget.AdapterHolder;
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.adapter;
package com.mang.xuedianyun.android.adapter;
import android.graphics.Bitmap;
import android.os.Bundle;
... ... @@ -23,13 +23,13 @@ import android.support.v4.app.FragmentStatePagerAdapter;
import android.widget.ImageView;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.widget.chat.ChatFunctionFragment;
import com.mang.xdy.demo.widget.chat.FacePageFragment;
import com.mang.xdy.demo.widget.chat.KJChatKeyboard;
import com.mang.xdy.demo.widget.chat.OnOperationListener;
import com.mang.xdy.demo.widget.chat.PagerSlidingTabStrip;
import com.mang.xdy.demo.widget.emoji.EmojiPageFragment;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.widget.chat.ChatFunctionFragment;
import com.mang.xuedianyun.android.widget.chat.FacePageFragment;
import com.mang.xuedianyun.android.widget.chat.KJChatKeyboard;
import com.mang.xuedianyun.android.widget.chat.OnOperationListener;
import com.mang.xuedianyun.android.widget.chat.PagerSlidingTabStrip;
import com.mang.xuedianyun.android.widget.emoji.EmojiPageFragment;
import org.kymjs.kjframe.bitmap.BitmapCreate;
... ...
package com.mang.xdy.demo.adapter;
package com.mang.xuedianyun.android.adapter;
/**
* Created by huang on 2017/4/9.
... ... @@ -9,9 +9,8 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.mang.xdy.demo.fragment.ChatFragment;
import com.mang.xdy.demo.fragment.DocFragment;
import com.mang.xdy.demo.fragment.PageFragment;
import com.mang.xuedianyun.android.fragment.ChatFragment;
import com.mang.xuedianyun.android.fragment.DocFragment;
import java.util.ArrayList;
import java.util.List;
... ...
package com.mang.xdy.demo.application;
package com.mang.xuedianyun.android.application;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import com.mang.xdy.core.XdySdk;
import com.mang.xdy.demo.utils.ResUtil;
import com.mang.xuedianyun.android.utils.ResUtil;
/**
* Created by abao on 2017/3/30.
... ...
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
import java.util.List;
import java.util.List;
/**
* Created by Admin on 2017/3/27.
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
import java.io.Serializable;
... ...
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
/**
* Created by abao on 2017/4/10. 加入课堂
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
/**
* 聊天消息javabean
... ...
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
/**
* Created by Admin on 2017/3/26.
... ...
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
public class ResponseEntity {
private String type;
... ...
package com.mang.xdy.demo.bean;
package com.mang.xuedianyun.android.bean;
// FIXME generate failure method set and get MediaId
// FIXME generate failure field _$Replay151
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.view.View;
import android.view.animation.Interpolator;
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.app.Dialog;
import android.content.Context;
... ... @@ -15,7 +15,7 @@ import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.LinearLayout;
import com.mang.xdy.demo.utils.DisplayUtil;
import com.mang.xuedianyun.android.utils.DisplayUtil;
import com.nineoldandroids.animation.Animator;
import java.lang.ref.WeakReference;
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.content.Context;
import android.view.Gravity;
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.content.Context;
import android.view.MotionEvent;
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.content.Context;
import android.graphics.Color;
... ... @@ -9,7 +9,7 @@ import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
public class NormalDialog extends BaseDialog {
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
import android.content.Context;
import android.graphics.Color;
... ... @@ -9,7 +9,7 @@ import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
/**
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
public interface OnBtnClick {
void onBtnClick();
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
public interface OnBtnLeftClick {
void onBtnLeftClick();
... ...
package com.mang.xdy.demo.dialog;
package com.mang.xuedianyun.android.dialog;
public interface OnBtnRightClick {
void onBtnRightClick();
... ...
package com.mang.xdy.demo.fragment;
package com.mang.xuedianyun.android.fragment;
import android.content.Context;
import android.os.Bundle;
... ... @@ -18,17 +18,17 @@ import com.google.gson.Gson;
import com.mang.xdy.common.Constants;
import com.mang.xdy.utils.SPUtil;
import com.mang.xdy.core.XdySdk;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.adapter.ChatAdapter;
import com.mang.xdy.demo.bean.ChatMsgEntity;
import com.mang.xdy.demo.bean.Faceicon;
import com.mang.xdy.demo.bean.JoinClassSuccessEntity;
import com.mang.xdy.demo.bean.Message;
import com.mang.xdy.demo.bean.SendChatMsgEntity;
import com.mang.xdy.demo.utils.JsonUtil;
import com.mang.xdy.demo.widget.chat.KJChatKeyboard;
import com.mang.xdy.demo.widget.chat.OnOperationListener;
import com.mang.xdy.demo.widget.emoji.DisplayRules;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.adapter.ChatAdapter;
import com.mang.xuedianyun.android.bean.ChatMsgEntity;
import com.mang.xuedianyun.android.bean.Faceicon;
import com.mang.xuedianyun.android.bean.JoinClassSuccessEntity;
import com.mang.xuedianyun.android.bean.Message;
import com.mang.xuedianyun.android.bean.SendChatMsgEntity;
import com.mang.xuedianyun.android.utils.JsonUtil;
import com.mang.xuedianyun.android.widget.chat.KJChatKeyboard;
import com.mang.xuedianyun.android.widget.chat.OnOperationListener;
import com.mang.xuedianyun.android.widget.emoji.DisplayRules;
import com.mang.xdy.listener.ObserverListener;
import com.mang.xdy.utils.XdyLogUtil;
... ...
package com.mang.xdy.demo.fragment;
package com.mang.xuedianyun.android.fragment;
import android.content.Context;
import android.graphics.Bitmap;
... ... @@ -11,21 +11,20 @@ import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import com.bumptech.glide.Glide;
import com.mang.xdy.common.Constants;
import com.mang.xdy.core.XdySdk;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.base.BaseRunnable;
import com.mang.xdy.demo.bean.DocEntity;
import com.mang.xdy.demo.bean.WhiteboardUpdateEntity;
import com.mang.xdy.demo.bean.WrapDocBitMapEntity;
import com.mang.xdy.demo.utils.JsonUtil;
import com.mang.xdy.demo.utils.ToastUtil;
import com.mang.xdy.demo.widget.CanvasView;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.base.BaseRunnable;
import com.mang.xuedianyun.android.bean.DocEntity;
import com.mang.xuedianyun.android.bean.WhiteboardUpdateEntity;
import com.mang.xuedianyun.android.bean.WrapDocBitMapEntity;
import com.mang.xuedianyun.android.utils.JsonUtil;
import com.mang.xuedianyun.android.utils.ToastUtil;
import com.mang.xuedianyun.android.widget.CanvasView;
import com.mang.xdy.listener.ObserverListener;
import com.mang.xdy.utils.XdyLogUtil;
... ... @@ -85,7 +84,7 @@ public class DocFragment extends Fragment implements ObserverListener{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ToastUtil.showToastshort("图片加载失败",mContext);
ToastUtil.showToastshort(getResources().getString(R.string.imge_load_error),mContext);
}
};
... ... @@ -99,17 +98,15 @@ public class DocFragment extends Fragment implements ObserverListener{
public void init(){
Bundle arguments = getArguments();
if(arguments!=null)
replay = arguments.getBoolean("replay");
DisplayMetrics metric = new DisplayMetrics();
getWindowWith(metric);
docUrlTransformBitmap(null);
// mCanvasView.setZOrderMediaOverlay(false);
// mCanvasView.setZOrderOnTop(false);
//// mCanvasView.getHolder().setFormat(SurfaceView.TRANSPARENT);
// mCanvasView.getHolder().setFormat(SurfaceView.TRANSPARENT);
if(replay) {
mCanvasView.setZOrderMediaOverlay(true);
}
}
private void getWindowWith(DisplayMetrics metric) {
... ... @@ -237,7 +234,7 @@ public class DocFragment extends Fragment implements ObserverListener{
public void call(WrapDocBitMapEntity resource) {
if (resource.getBitmap() == null) {
ToastUtil.showToastshort("图片获取失败",mContext);
ToastUtil.showToastshort(getResources().getString(R.string.imge_load_error),mContext);
Bitmap bitmap = getEmptyBitmap();
mCanvasView.setBitmap(bitmap, false);
} else {
... ...
package com.mang.xdy.demo.fragment;
package com.mang.xuedianyun.android.fragment;
import android.os.Bundle;
... ... @@ -9,7 +9,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
/**
... ...
package com.mang.xdy.demo.fragment;
package com.mang.xuedianyun.android.fragment;
import android.os.Bundle;
... ... @@ -7,12 +7,13 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
/**
* A simple {@link Fragment} subclass.
* Use the {@link PublishFragment#newInstance} factory method to
* create an instance of this fragment.
* @deprecated
*/
public class PublishFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
... ...
package com.mang.xdy.demo.utils;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
package com.mang.xuedianyun.android.utils;
import android.annotation.SuppressLint;
import android.app.Activity;
... ...
package com.mang.xdy.demo.utils;
package com.mang.xuedianyun.android.utils;
import android.text.TextUtils;
import android.util.Log;
... ...
package com.mang.xdy.demo.utils;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.StringRes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
package com.mang.xuedianyun.android.utils;
import android.content.Context;
import android.content.res.Resources;
... ...
package com.mang.xdy.demo.utils;
package com.mang.xuedianyun.android.utils;
import android.content.Context;
import android.widget.Toast;
... ...
... ... @@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.utils.cache;
package com.mang.xuedianyun.android.utils.cache;
import android.content.Context;
import android.graphics.Bitmap;
... ...
package com.mang.xdy.demo.utils.cache;
package com.mang.xuedianyun.android.utils.cache;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
... ...
package com.mang.xdy.demo.widget;
package com.mang.xuedianyun.android.widget;
import android.content.Context;
import android.graphics.Bitmap;
... ... @@ -17,13 +17,12 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.bean.AnnotaionEntity;
import com.mang.xdy.demo.bean.PointGroupEntity;
import com.mang.xdy.demo.bean.PointXY;
import com.mang.xdy.demo.utils.DisplayUtil;
import com.mang.xdy.demo.utils.ResUtil;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.bean.AnnotaionEntity;
import com.mang.xuedianyun.android.bean.PointGroupEntity;
import com.mang.xuedianyun.android.bean.PointXY;
import com.mang.xuedianyun.android.utils.DisplayUtil;
import com.mang.xuedianyun.android.utils.ResUtil;
import java.util.ArrayList;
import java.util.Iterator;
... ...
package com.mang.xuedianyun.android.widget.answersheet;
import android.content.Context;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.utils.ToastUtil;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Created by abao on 2017/5/5.
* @deprecated
*/
public class AnswerSheetView extends RelativeLayout {
/*单选多选类型*/
public final static int ANSWER_TYPE_SINGLE_OR_MORE = 1;
/*对错类型*/
public final static int ANSWER_TYPE_RIGHT_OR_WRONG = 2;
/*填空*/
public final static int ANSWER_TYPE_FILLING = 3;
/*单前的type*/
private static int ANSWER_CURRENT_TYPE = 1;
/*倒计时时间 s*/
public static int ANSWER_TIMEOUT = 30;
@BindView(R.id.tv_exam_countdown)
TextView tvExamCountdown;
@BindView(R.id.rel_home_tv_exam_countdown)
RelativeLayout relHomeTvExamCountdown;
@BindView(R.id.cb_exam_A)
CheckBox cbExamA;
@BindView(R.id.cb_exam_B)
CheckBox cbExamB;
@BindView(R.id.cb_exam_C)
CheckBox cbExamC;
@BindView(R.id.cb_exam_D)
CheckBox cbExamD;
@BindView(R.id.ll_exam_SingleOrMore)
LinearLayout llExamSingleOrMore;
@BindView(R.id.rb_exam_R)
RadioButton rbExamR;
@BindView(R.id.rb_exam_W)
RadioButton rbExamW;
@BindView(R.id.ll_exam_selectRightOrWrong)
LinearLayout llExamSelectRightOrWrong;
@BindView(R.id.ll_exam_filling)
LinearLayout llExamFilling;
@BindView(R.id.tv_exam_up)
TextView tvExamUp;
@BindView(R.id.tv_exam_cancle)
TextView tvExamCancle;
@BindView(R.id.ll_exam_submit)
LinearLayout llExamSubmit;
@BindView(R.id.rel_exam_layout)
RelativeLayout relExamLayout;
@BindView(R.id.ll_exam_answer)
LinearLayout llExamAnswer;
private AnswerCount mAnswerCount;
private StringBuffer sb = new StringBuffer();
private Context mContext;
private String character_close="关闭";
private String character_cancle="放弃";
Display display;
private OnAnswerLayoutChangeListener onAnswerLayoutChangeListener;
public interface OnAnswerLayoutChangeListener{
/**
* 改变显示布局的大小
* @param
*/
void setAnswerSheetFramLayout(int num);
void setAnswerSheetNormal(int num);
}
public void setOnAnswerLayoutChangeListener(OnAnswerLayoutChangeListener onAnswerLayoutChangeListener){
this.onAnswerLayoutChangeListener=onAnswerLayoutChangeListener;
}
public AnswerSheetView(Context context) {
this(context, null);
}
public AnswerSheetView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AnswerSheetView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
View view = initView(context);
this.addView(view);
}
public View initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.item_answer, null);
ButterKnife.bind(this, view);
return view;
}
/*选择答题类型*/
public void selectAnswerSheetType(int type) {
tvExamCountdown.setText("_s");
llExamAnswer.setVisibility(View.GONE);
tvExamUp.setVisibility(View.VISIBLE);
tvExamCancle.setText(character_cancle);
switch (type) {
case ANSWER_TYPE_SINGLE_OR_MORE:
ANSWER_CURRENT_TYPE = ANSWER_TYPE_SINGLE_OR_MORE;
llExamSingleOrMore.setVisibility(View.VISIBLE);
llExamSelectRightOrWrong.setVisibility(View.GONE);
llExamFilling.setVisibility(View.GONE);
break;
case ANSWER_TYPE_RIGHT_OR_WRONG:
ANSWER_CURRENT_TYPE = ANSWER_TYPE_RIGHT_OR_WRONG;
llExamSingleOrMore.setVisibility(View.GONE);
llExamSelectRightOrWrong.setVisibility(View.VISIBLE);
llExamFilling.setVisibility(View.GONE);
break;
case ANSWER_TYPE_FILLING:
ANSWER_CURRENT_TYPE = ANSWER_TYPE_FILLING;
llExamSingleOrMore.setVisibility(View.GONE);
llExamSelectRightOrWrong.setVisibility(View.GONE);
llExamFilling.setVisibility(View.VISIBLE);
break;
}
}
@OnClick({R.id.tv_exam_up, R.id.tv_exam_cancle})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.tv_exam_up:
//提交需要获取结果,清除数据,时间清理
// relExamLayout.setVisibility(GONE);
handleAnswer(ANSWER_CURRENT_TYPE);
ToastUtil.showToastshort("选择答案:" + sb.toString() + sb.length(), mContext);
recoverStatus();
setSubmitAnswer();
break;
case R.id.tv_exam_cancle:
recoverStatus();
// if(character_cancle.equals(tvExamCancle)) {
// setAnsNormalLayout(53);
// }else{
//
// }
if(relExamLayout.isShown()){
relExamLayout.setVisibility(GONE);
}
break;
}
}
/*开始倒计时*/
public void startCountTimer(int time) {
ANSWER_TIMEOUT = time;
cancleCountTimer();
mAnswerCount = new AnswerCount(ANSWER_TIMEOUT * 1000, 1000);
mAnswerCount.start();
//提交需要获取结果,清除数据,时间清理
relExamLayout.setVisibility(VISIBLE);
}
/*销毁倒计时*/
public void cancleCountTimer() {
if (mAnswerCount != null) {
mAnswerCount.cancel();
}
}
/**
* 处理结果,拼装答案
*
* @param type
*/
public void handleAnswer(int type) {
switch (type) {
case ANSWER_TYPE_SINGLE_OR_MORE:
handleSingleOrMore();
break;
case ANSWER_TYPE_RIGHT_OR_WRONG:
handleRightOrWrong();
break;
case ANSWER_TYPE_FILLING:
break;
}
}
/*单选,多选答案拼接*/
public void handleSingleOrMore() {
sb.setLength(0);
if (cbExamA.isChecked()) {
sb.append("A");
}
if (cbExamB.isChecked()) {
sb.append("B");
}
if (cbExamC.isChecked()) {
sb.append("C");
}
if (cbExamD.isChecked()) {
sb.append("D");
}
}
/*处理对错*/
public void handleRightOrWrong() {
sb.setLength(0);
if (rbExamR.isChecked()) {
sb.append("对");
} else {
sb.append("错");
}
}
/*恢复状态*/
public void recoverStatus() {
switch (ANSWER_CURRENT_TYPE) {
case ANSWER_TYPE_SINGLE_OR_MORE:
cbExamA.setChecked(false);
cbExamB.setChecked(false);
cbExamC.setChecked(false);
cbExamD.setChecked(false);
break;
case ANSWER_TYPE_RIGHT_OR_WRONG:
rbExamR.setChecked(true);
rbExamW.setChecked(false);
break;
case ANSWER_TYPE_FILLING:
break;
}
}
/*隐藏所有题目*/
private void hideAllTitle(){
llExamSingleOrMore.setVisibility(View.GONE);
llExamSelectRightOrWrong.setVisibility(View.GONE);
llExamFilling.setVisibility(View.GONE);
}
/*设置显示答案布局大小*/
public void setAnswerLayout(int num){
if(onAnswerLayoutChangeListener!=null) {
onAnswerLayoutChangeListener.setAnswerSheetFramLayout(num);
}
}
/*设置显示答案布局大小*/
public void setAnsNormalLayout(int num){
if(onAnswerLayoutChangeListener!=null) {
onAnswerLayoutChangeListener.setAnswerSheetNormal(num);
}
}
/*提交答案 设置*/
private void setSubmitAnswer(){
hideAllTitle();
llExamAnswer.setVisibility(View.VISIBLE);
cancleCountTimer();
tvExamUp.setVisibility(View.GONE);
tvExamCancle.setText(character_close);
setAnswerLayout(100);
}
@OnClick(R.id.ll_exam_answer)
public void onViewClicked() {
}
/*倒计时处理*/
class AnswerCount extends CountDownTimer {
/**
* @param millisInFuture The number of millis in the future from the call
* to {@link #start()} until the countdown is done and {@link #onFinish()}
* is called.
* @param countDownInterval The interval along the way to receive
* {@link #onTick(long)} callbacks.
*/
public AnswerCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
if (millisUntilFinished < 10) {
tvExamCountdown.setText(" " + millisUntilFinished / 1000 + "s");
} else {
tvExamCountdown.setText(millisUntilFinished / 1000 + "s");
}
}
@Override
public void onFinish() {
//这个结束应该做自动提交答案的工作
tvExamCountdown.setText("0s");
}
}
}
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import android.os.Bundle;
import android.view.LayoutInflater;
... ... @@ -22,7 +22,7 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
import org.kymjs.kjframe.ui.SupportFragment;
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import android.app.Activity;
import android.graphics.Color;
... ... @@ -36,9 +36,9 @@ import android.widget.RadioButton;
import android.widget.RadioGroup;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.adapter.FaceAdapter;
import com.mang.xdy.demo.bean.Faceicon;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.adapter.FaceAdapter;
import com.mang.xuedianyun.android.bean.Faceicon;
import org.kymjs.kjframe.ui.SupportFragment;
import org.kymjs.kjframe.utils.StringUtils;
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import android.app.Activity;
import android.content.Context;
... ... @@ -29,8 +29,8 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.adapter.FaceCategroyAdapter;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.adapter.FaceCategroyAdapter;
import java.util.List;
... ...
... ... @@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import com.mang.xdy.demo.bean.Faceicon;
import com.mang.xuedianyun.android.bean.Faceicon;
/**
* 表情栏顶部按钮的监听器
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import android.annotation.SuppressLint;
import android.content.Context;
... ... @@ -39,7 +39,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
import java.util.Locale;
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import android.graphics.Rect;
import android.view.View;
... ...
package com.mang.xdy.demo.widget.chat;
package com.mang.xuedianyun.android.widget.chat;
import android.content.Context;
import android.content.Intent;
... ...
package com.mang.xuedianyun.android.widget.dialog;
import android.app.Dialog;
import android.content.Context;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.mang.xuedianyun.android.R;
import butterknife.ButterKnife;
/**
* Created by abao on 2017/5/9.
* @deprecated
*/
public class AnswText {
/*单选多选类型*/
public final static int ANSWER_TYPE_SINGLE_OR_MORE = 1;
/*对错类型*/
public final static int ANSWER_TYPE_RIGHT_OR_WRONG = 2;
/*填空*/
public final static int ANSWER_TYPE_FILLING = 3;
/*单前的type*/
private static int ANSWER_CURRENT_TYPE = 1;
/*倒计时时间 s*/
public static int ANSWER_TIMEOUT = 30;
private StringBuffer sb = new StringBuffer();
private Context mContext;
private String character_close="关闭";
private String character_cancle="放弃";
private OnAnswerLayoutChangeListener onAnswerLayoutChangeListener;
public interface OnAnswerLayoutChangeListener{
/**
* 改变显示布局的大小
* @param
*/
void setAnswerSheetFramLayout(int num);
void setAnswerSheetNormal(int num);
}
public void setOnAnswerLayoutChangeListener(OnAnswerLayoutChangeListener onAnswerLayoutChangeListener){
this.onAnswerLayoutChangeListener=onAnswerLayoutChangeListener;
}
private Context context;
private Dialog dialog;
private TextView txt_title;
private TextView txt_cancel;
private LinearLayout lLayout_content;
private ScrollView sLayout_content;
private boolean showTitle = false;
// private List<ActionSheetDialog.SheetItem> sheetItemList;
private Display display;
public AnswText(Context context) {
this.context = context;
this.mContext=context;
WindowManager windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
display = windowManager.getDefaultDisplay();
}
public AnswText builder() {
View view = LayoutInflater.from(context).inflate(
R.layout.view_text, null);
ButterKnife.bind(this,view);
view.setMinimumWidth(display.getWidth());
dialog = new Dialog(context, R.style.ActionSheetDialogStyle);
dialog.setContentView(view);
Window dialogWindow = dialog.getWindow();
dialogWindow.setGravity(Gravity.LEFT | Gravity.BOTTOM);
// dialogWindow.setGravity( Gravity.BOTTOM);
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.x = 0;
lp.y = 0;
dialogWindow.setAttributes(lp);
return this;
}
public void show() {
dialog.show();
}
}
... ...
package com.mang.xdy.demo.widget.dialog;
package com.mang.xuedianyun.android.widget.dialog;
import android.app.Dialog;
import android.content.Context;
... ... @@ -12,15 +12,14 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.utils.ToastUtil;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.utils.ToastUtil;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
... ...
package com.mang.xdy.demo.widget.dialog;
package com.mang.xuedianyun.android.widget.dialog;
import android.content.Context;
import android.view.Gravity;
... ... @@ -7,8 +7,8 @@ import android.widget.Button;
import android.widget.EditText;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.dialog.BaseDialog;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.dialog.BaseDialog;
import com.mang.xdy.utils.UIUtils;
import org.greenrobot.eventbus.EventBus;
... ...
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
import android.view.KeyEvent;
import android.widget.EditText;
... ...
... ... @@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
import android.widget.AbsListView;
import android.widget.TextView;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
import org.kymjs.kjframe.widget.AdapterHolder;
import org.kymjs.kjframe.widget.KJAdapter;
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
import android.app.Activity;
import android.os.Bundle;
... ... @@ -31,8 +31,8 @@ import android.widget.RadioButton;
import android.widget.RadioGroup;
import com.mang.xdy.demo.R;
import com.mang.xdy.demo.widget.chat.OnOperationListener;
import com.mang.xuedianyun.android.R;
import com.mang.xuedianyun.android.widget.chat.OnOperationListener;
import org.kymjs.kjframe.ui.SupportFragment;
... ...
... ... @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
/**
* emoji表情的javabean
... ...
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
import com.mang.xdy.demo.R;
import com.mang.xuedianyun.android.R;
import java.util.ArrayList;
import java.util.HashMap;
... ...
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
import android.content.Context;
import android.content.res.TypedArray;
... ...
package com.mang.xdy.demo.widget.emoji;
package com.mang.xuedianyun.android.widget.emoji;
import android.content.Context;
import android.content.res.TypedArray;
... ...
package com.mang.xdy.demo.widget.view;
package com.mang.xuedianyun.android.widget.view;
import android.content.Context;
import android.os.Build;
... ... @@ -7,7 +7,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.mang.xdy.demo.utils.DisplayUtil;
import com.mang.xuedianyun.android.utils.DisplayUtil;
public class AutoAdaptHeaderViewGroup extends RelativeLayout {
... ...
package com.mang.xdy.demo.widget.view;
package com.mang.xuedianyun.android.widget.view;
import android.content.Context;
import android.support.v4.view.ViewPager;
... ...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/home_btn_green_press" android:state_pressed="true"></item>
<item android:drawable="@color/home_btn_green_press" android:state_checked="true"></item>
<item android:drawable="@color/home_btn_green"></item>
</selector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/answer_select" android:state_checked="true" />
<item android:drawable="@drawable/answer_unselect" />
</selector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/spreadback" android:state_checked="true" />
<item android:drawable="@drawable/foldback" />
</selector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false" >
<solid android:color="@color/colorSkyBlue" />
<!--<padding-->
<!--android:left="2dp"-->
<!--android:top="1dp"-->
<!--android:right="2dp"-->
<!--android:bottom="1dp" />-->
<!--<solid-->
<!--android:color="@color/actionsheet_red" />-->
<!--<stroke-->
<!--android:width="1dp"-->
<!--android:color="@android:color/white" />-->
<size android:width="18dp"
android:height="18dp" />
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false" >
<solid android:color="@color/actionsheet_red" />
<!--<padding-->
<!--android:left="2dp"-->
<!--android:top="1dp"-->
<!--android:right="2dp"-->
<!--android:bottom="1dp" />-->
<!--<solid-->
<!--android:color="@color/actionsheet_red" />-->
<!--<stroke-->
<!--android:width="1dp"-->
<!--android:color="@android:color/white" />-->
<size android:width="18dp"
android:height="18dp" />
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 圆角 -->
<corners android:radius="16dp" />
<!-- 填充颜色 -->
<solid android:color="@color/colorSkyBlue" />
<!--&lt;!&ndash;内边距&ndash;&gt;-->
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 圆角 -->
<corners android:radius="16dp" />
<!-- 填充颜色 -->
<solid android:color="@color/colorGrey" />
<!--内边距-->
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
\ No newline at end of file
... ...
... ... @@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.MainActivity">
tools:context="com.mang.xuedianyun.android.MainActivity">
<RelativeLayout
android:id="@+id/rl_home_close"
android:layout_width="@dimen/ui_DIMEN_98.0PX"
... ...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_video_play"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#e3e4e6"
tools:context="com.mang.xuedianyun.android.activity.VideoPlayActivity">
<RelativeLayout
android:id="@+id/avg_videoPlay_back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:paddingLeft="@dimen/ui_DIMEN_20.0PX"
android:paddingRight="@dimen/ui_DIMEN_20.0PX">
<ImageView
android:id="@+id/img_videoPlay_back"
android:layout_width="wrap_content"
android:layout_height="@dimen/ui_titlebar_height"
android:paddingRight="10dp"
android:paddingLeft="15dp"
android:src="@mipmap/back"/>
<TextView
android:layout_toRightOf="@+id/img_videoPlay_back"
android:layout_width="wrap_content"
style="@style/ui_wrapTvBaseStyle"
android:layout_height="@dimen/ui_titlebar_height"
android:text="@string/home_title_back"
android:gravity="center"
android:textColor="@color/white"
android:visibility="gone"
/>
<TextView
android:id="@+id/tv_videoPlay_className"
style="@style/ui_wrapTvBaseStyle"
android:layout_height="@dimen/ui_titlebar_height"
android:gravity="center"
android:layout_centerHorizontal="true"
android:textColor="@color/white"
android:layout_toRightOf="@+id/img_videoPlay_back"
tools:text="dfdfdfdfdfdf"
android:textSize="@dimen/ui_DIMEN_34.0PX"/>
</RelativeLayout>
<!--白板+right-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_below="@+id/avg_videoPlay_back"
android:layout_above="@+id/fl_media"
>
<LinearLayout
android:id="@+id/ll_videoPlay_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:layout_alignParentRight="true"
>
<RelativeLayout
android:id="@+id/rel_videoPlay_play"
android:layout_width="255dp"
android:layout_alignParentRight="true"
android:layout_weight="1"
android:layout_height="wrap_content">
<com.pili.pldroid.player.widget.PLVideoTextureView
android:id="@+id/img_playVideo_replay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
<SurfaceView
android:id="@+id/surfaceview_playVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="@+id/img_playVideo_novideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/novideo"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentRight="true"
android:id="@+id/linearLayout">
</LinearLayout>
</RelativeLayout>
<!--推流-->
<RelativeLayout
android:id="@+id/rel_videoPlay_publish"
android:layout_width="255dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="@+id/rel_videoPlay_play"
android:layout_alignParentRight="true"
android:layout_alignLeft="@+id/rel_videoPlay_play"
android:layout_marginTop="8dp"
>
<SurfaceView
android:id="@+id/sur_plaVideo_publish"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<FrameLayout
android:id="@+id/fra_videoPlay_student_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/student"
tools:visibility="visible"
android:layout_gravity="center"
android:scaleType="fitCenter"
/>
</FrameLayout>
<ImageView
android:id="@+id/img_playVideo_publishAudio"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/audio_mode"
android:visibility="gone"
tools:visibility="visible"
android:scaleType="fitCenter"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<FrameLayout
android:id="@+id/fra_videoPlay_start"
android:layout_width="50dp"
android:layout_height="50dp"
tools:visibility="visible"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
>
<ImageView
android:id="@+id/img_videoPlay_start"
android:layout_width="20dp"
android:layout_height="12dp"
android:layout_marginTop="20dp"
android:layout_marginLeft="5dp"
android:background="@mipmap/camera_normal2x"
/>
</FrameLayout>
<!--音频-->
<FrameLayout
android:id="@+id/fra_videoPlay_start_audio"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_toRightOf="@+id/fra_videoPlay_start"
tools:visibility="visible"
android:layout_alignParentBottom="true"
>
<ImageView
android:id="@+id/img_videoPlay_start_audio"
android:layout_width="12dp"
android:layout_height="20dp"
android:layout_marginTop="15dp"
android:background="@mipmap/mic_normal2x"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/fra_videoPlay_stopPublish"
android:layout_width="70dp"
android:layout_height="50dp"
android:visibility="gone"
tools:visibility="visible"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_alignBottom="@+id/sur_plaVideo_publish"
>
<ImageView
android:id="@+id/img_videoPlay_stopPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:enabled="false"
android:background="@mipmap/hangup_normal2x"
/>
</FrameLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_videoPlay_tablet_chat"
android:layout_width="255dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="8dp"
/>
</LinearLayout>
<!--Tablet文档-->
<LinearLayout
android:id="@+id/ll_videoPlay_tablet_doc"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:layout_toLeftOf="@+id/ll_videoPlay_right"
/>
</RelativeLayout>
<com.flyco.tablayout.SlidingTabLayout
android:id="@+id/stl_videoPlay_tab"
android:layout_width="match_parent"
android:layout_height="@dimen/ui_titlebar_height"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="#fafafa"
custom:tl_indicator_color="@color/home_tab_selected"
custom:tl_indicator_corner_radius="1.5dp"
custom:tl_indicator_height="@dimen/ui_DIMEN_5.0PX"
custom:tl_tab_space_equal="true"
custom:tl_textSelectColor="@color/home_tab_selected"
custom:tl_textUnselectColor="@color/home_tab_unselected"
custom:tl_textsize="@dimen/ui_DIMEN_28.0PX"/>
<com.mang.xuedianyun.android.widget.view.NoScrollViewPager
android:id="@+id/viewpager"
android:layout_below="@+id/stl_videoPlay_tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/stl_videoPlay_tab"
android:background="@android:color/white" >
</com.mang.xuedianyun.android.widget.view.NoScrollViewPager>
<FrameLayout
android:id="@+id/fl_media"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
<include
layout="@layout/home_media_controller"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
</RelativeLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_video_play"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xuedianyun.android.activity.VideoPlayActivity">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
>
<SurfaceView
android:id="@+id/surfaceview_playVideo"
android:layout_width="match_parent"
android:layout_height="200dp"
android:visibility="gone"/>
<ImageView
android:id="@+id/img_playVideo_novideo"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@mipmap/novideo"
/>
</RelativeLayout>
<SurfaceView
android:id="@+id/surfaceview_pubisherVideo"
android:layout_width="match_parent"
android:layout_height="300dp" />
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white" />
<TextView
android:id="@+id/tv_videoPlay_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_videoPlay_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送hello"
android:visibility="gone"
/>
<Button
android:id="@+id/btn_videoPlay_pubsherVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取推流地址推送视频"
android:enabled="false"
/>
<Button
android:id="@+id/btn_videoPlay_publisherAudio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取推流地址推送音频"
android:enabled="false"
/>
<Button
android:id="@+id/btn_videoPlay_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止推流"
/>
</LinearLayout>
</LinearLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="@dimen/ui_DIMEN_500.0PX"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/radius_solid_white_stroke_999"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/ui_DIMEN_20.0PX"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="@+id/dialog_edt_username"
style="@style/home_login_edit_style"
android:hint="用户名"/>
<EditText
android:id="@+id/dialog_edt_userpwd"
style="@style/home_login_edit_style"
android:hint="密码"/>
<Button
android:id="@+id/dialog_btn_enter"
android:layout_width="100dp"
android:layout_height="wrap_content"
style="@style/home_site_btn_style"
android:text="登录"
/>
</LinearLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_chat_fragment_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ebebeb"
android:orientation="vertical">
<com.mang.xuedianyun.android.widget.chat.KJChatKeyboard
android:id="@+id/chat_msg_input_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<ListView
android:id="@+id/chat_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/chat_msg_input_box"
android:cacheColorHint="#00000000"
android:divider="@null"
android:dividerHeight="8.33dp"
android:scrollbarStyle="outsideOverlay"
android:transcriptMode="normal" />
<View
android:id="@+id/view_line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/chat_listview"
android:background="#7fd8d8d8" />
<!-- -->
</RelativeLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mang.xuedianyun.android.widget.CanvasView
android:id="@+id/canvas_doc_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
\ No newline at end of file
... ...
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mang.xuedianyun.android.fragment.PublishFragment">
<!-- TODO: Update blank fragment layout -->
<SurfaceView
android:id="@+id/sur_publish"
android:layout_width="match_parent"
android:layout_height="200dp"
android:text="@string/hello_blank_fragment" />
<Button
android:id="@+id/btn_publish_gets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取推流地址,开始推流"
/>
<Button
android:id="@+id/btn_publish_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止推流"
/>
</FrameLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/frag_pager_face"
android:layout_width="match_parent"
android:layout_height="150dp">
</android.support.v4.view.ViewPager>
<RadioGroup
android:id="@+id/frag_point"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginBottom="6dip"
android:background="#00000000"
android:gravity="center"
android:orientation="horizontal">
</RadioGroup>
</LinearLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<com.mang.xuedianyun.android.widget.emoji.EmoticonsTextView
android:id="@+id/itemEmoji"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="33dp"
android:layout_height="33dp"
android:layout_margin="2dp"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="25sp"/>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="55dp"
android:layout_height="55dp"
android:gravity="center"
android:padding="5dip">
<ImageView
android:id="@+id/itemImage"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:scaleType="centerCrop"/>
</RelativeLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/ui_DIMEN_24.0PX"
android:paddingRight="@dimen/ui_DIMEN_24.0PX">
<TextView
android:id="@+id/chat_item_date"
android:layout_width="@dimen/ui_DIMEN_80.0PX"
android:layout_height="@dimen/ui_DIMEN_35.0PX"
android:layout_gravity="center_horizontal"
android:background="@drawable/home_chat_item_date_bg"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="@dimen/ui_DIMEN_22.0PX"
android:visibility="gone" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp">
<ImageView
android:id="@+id/chat_item_avatar"
style="@style/home_chat_item_avatar"
android:layout_alignParentLeft="true" />
<LinearLayout
android:id="@+id/ll_item_name_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/ui_DIMEN_20.0PX"
android:layout_toRightOf="@id/chat_item_avatar"
android:orientation="horizontal">
<TextView
android:id="@+id/chat_item_taacher_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/ui_DIMEN_8.0PX"
android:background="@drawable/home_chat_teacher_bg"
android:gravity="center"
android:paddingLeft="@dimen/ui_DIMEN_10.0PX"
android:paddingRight="@dimen/ui_DIMEN_10.0PX"
android:text="老师"
android:textColor="#ffffff"
android:textSize="@dimen/ui_DIMEN_20.0PX"
android:visibility="gone" />
<TextView
android:id="@+id/chat_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#808080"
android:textSize="@dimen/ui_DIMEN_22.0PX" />
</LinearLayout>
<RelativeLayout
android:id="@+id/chat_item_layout_content"
style="@style/home_chat_item_content"
android:layout_below="@id/ll_item_name_parent"
android:layout_centerVertical="true"
android:layout_marginTop="@dimen/ui_DIMEN_8.0PX"
android:layout_toRightOf="@id/chat_item_avatar">
<com.mang.xuedianyun.android.widget.emoji.EmoticonsTextView
android:id="@+id/chat_item_content_text"
style="@style/home_chat_item_text_content"
android:layout_centerInParent="true"
android:background="@drawable/chat_pop_receive"
android:gravity="start|center_vertical"
android:paddingLeft="@dimen/ui_DIMEN_20.0PX"
android:paddingRight="@dimen/ui_DIMEN_10.0PX"
my:emojiconSize="@dimen/ui_DIMEN_40.0PX"
tools:text="" />
<ImageView
android:id="@+id/chat_item_content_image"
style="@style/home_chat_item_image_content"
android:visibility="gone" />
</RelativeLayout>
<ImageView
android:id="@+id/chat_item_fail"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/chat_item_layout_content"
android:background="@mipmap/msg_state_fail_resend"
android:focusable="false"
android:visibility="gone" />
<ProgressBar
android:id="@+id/chat_item_progress"
style="@android:style/Widget.ProgressBar.Small.Inverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/chat_item_layout_content"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
... ...
... ... @@ -67,7 +67,7 @@
android:layout_toLeftOf="@id/chat_item_avatar"
android:gravity="end">
<com.mang.xdy.demo.widget.emoji.EmoticonsTextView
<com.mang.xuedianyun.android.widget.emoji.EmoticonsTextView
android:id="@+id/chat_item_content_text"
style="@style/home_chat_item_text_content"
android:layout_centerVertical="true"
... ...
... ... @@ -33,7 +33,7 @@
android:visibility="gone"
android:button="@null"/>
<com.mang.xdy.demo.widget.emoji.EmoticonsEditText
<com.mang.xuedianyun.android.widget.emoji.EmoticonsEditText
android:id="@+id/toolbox_et_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
... ... @@ -78,7 +78,7 @@
android:layout_width="match_parent"
android:layout_height="160dp"></android.support.v4.view.ViewPager>
<com.mang.xdy.demo.widget.chat.PagerSlidingTabStrip
<com.mang.xuedianyun.android.widget.chat.PagerSlidingTabStrip
android:id="@+id/toolbox_tabs"
android:layout_width="match_parent"
android:layout_height="40dp"
... ...
... ... @@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.MainActivity">
tools:context="com.mang.xuedianyun.android.MainActivity">
<RelativeLayout
android:id="@+id/rl_home_close"
android:layout_width="@dimen/ui_DIMEN_98.0PX"
... ... @@ -44,7 +44,7 @@
style="@style/home_input_edit_style"
android:hint="classId"
android:inputType="number"
android:text="118417229"/>
android:text="1992614331"/>
<View
style="@style/ui_divider_line_horizontal"
... ...
... ... @@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.activity.VideoPlayActivity">
tools:context="com.mang.xuedianyun.android.activity.VideoPlayActivity">
<RelativeLayout
android:id="@+id/rel_videoPlay_play"
android:layout_width="match_parent"
... ... @@ -21,13 +21,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img_playVideo_novideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/novideo"
android:scaleType="fitXY"
android:background="@mipmap/no_video"
/>
<FrameLayout
android:layout_width="match_parent"
... ... @@ -59,6 +58,12 @@
android:layout_alignParentTop="true"
android:paddingLeft="@dimen/ui_DIMEN_20.0PX"
android:paddingRight="@dimen/ui_DIMEN_20.0PX">
<LinearLayout
android:id="@+id/ll_videoPlay_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/img_videoPlay_back"
... ... @@ -76,6 +81,7 @@
android:gravity="center"
android:textColor="@color/white"
/>
</LinearLayout>
<TextView
android:id="@+id/tv_videoPlay_className"
style="@style/ui_wrapTvBaseStyle"
... ... @@ -95,6 +101,13 @@
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<com.pili.pldroid.player.widget.PLVideoTextureView
android:id="@+id/img_playVideo_pushreplay"
android:layout_width="120dp"
android:layout_height="150dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
/>
<ImageView
android:id="@+id/img_playVideo_publishAudio"
android:layout_width="150dp"
... ... @@ -164,7 +177,7 @@
custom:tl_textUnselectColor="@color/home_tab_unselected"
custom:tl_textsize="@dimen/ui_DIMEN_28.0PX"/>
<com.mang.xdy.demo.widget.view.NoScrollViewPager
<com.mang.xuedianyun.android.widget.view.NoScrollViewPager
android:id="@+id/viewpager"
android:layout_below="@+id/stl_videoPlay_tab"
android:layout_width="match_parent"
... ... @@ -172,7 +185,7 @@
android:layout_weight="1"
android:background="@android:color/white" >
</com.mang.xdy.demo.widget.view.NoScrollViewPager>
</com.mang.xuedianyun.android.widget.view.NoScrollViewPager>
<FrameLayout
... ...
... ... @@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mang.xdy.demo.activity.VideoPlayActivity">
tools:context="com.mang.xuedianyun.android.activity.VideoPlayActivity">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... ...
... ... @@ -6,7 +6,7 @@
android:background="#ebebeb"
android:orientation="vertical">
<com.mang.xdy.demo.widget.chat.KJChatKeyboard
<com.mang.xuedianyun.android.widget.chat.KJChatKeyboard
android:id="@+id/chat_msg_input_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
... ...
... ... @@ -2,7 +2,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mang.xdy.demo.widget.CanvasView
<com.mang.xuedianyun.android.widget.CanvasView
android:id="@+id/canvas_doc_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
... ...
... ... @@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mang.xdy.demo.fragment.PublishFragment">
tools:context="com.mang.xuedianyun.android.fragment.PublishFragment">
<!-- TODO: Update blank fragment layout -->
<SurfaceView
... ...
<?xml version="1.0" encoding="utf-8"?>
<com.mang.xdy.demo.widget.emoji.EmoticonsTextView
<com.mang.xuedianyun.android.widget.emoji.EmoticonsTextView
android:id="@+id/itemEmoji"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="33dp"
... ...
... ... @@ -72,7 +72,7 @@
android:layout_marginTop="@dimen/ui_DIMEN_8.0PX"
android:layout_toRightOf="@id/chat_item_avatar">
<com.mang.xdy.demo.widget.emoji.EmoticonsTextView
<com.mang.xuedianyun.android.widget.emoji.EmoticonsTextView
android:id="@+id/chat_item_content_text"
style="@style/home_chat_item_text_content"
android:layout_centerInParent="true"
... ...
... ... @@ -67,7 +67,7 @@
android:layout_toLeftOf="@id/chat_item_avatar"
android:gravity="end">
<com.mang.xdy.demo.widget.emoji.EmoticonsTextView
<com.mang.xuedianyun.android.widget.emoji.EmoticonsTextView
android:id="@+id/chat_item_content_text"
style="@style/home_chat_item_text_content"
android:layout_centerVertical="true"
... ...
... ... @@ -33,7 +33,7 @@
android:visibility="gone"
android:button="@null"/>
<com.mang.xdy.demo.widget.emoji.EmoticonsEditText
<com.mang.xuedianyun.android.widget.emoji.EmoticonsEditText
android:id="@+id/toolbox_et_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
... ... @@ -78,7 +78,7 @@
android:layout_width="match_parent"
android:layout_height="160dp"></android.support.v4.view.ViewPager>
<com.mang.xdy.demo.widget.chat.PagerSlidingTabStrip
<com.mang.xuedianyun.android.widget.chat.PagerSlidingTabStrip
android:id="@+id/toolbox_tabs"
android:layout_width="match_parent"
android:layout_height="40dp"
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tool="http://schemas.android.com/tools"
android:layout_width="match_parent"
tool:visibility="visible"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/ll_exam_spreadOrfold"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginBottom="-20dp"
android:layout_gravity="right"
android:visibility="gone"
android:orientation="vertical">
</LinearLayout>
<CheckBox
android:id="@+id/cb_exam_spreadOrfold"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginBottom="-17dp"
android:layout_gravity="right"
android:button="@null"
android:drawableRight="@drawable/selector_exam_fold"/>
<!--<CheckBox-->
<!--android:id="@+id/cb_exam_A"-->
<!--style="@style/exam_cb_style_SingleOrMore"-->
<!--android:drawableLeft="@drawable/selector_exam"-->
<!--android:text="A" />-->
<!--倒计时-->
<RelativeLayout
android:layout_width="match_parent"
android:background="#e3e3e3"
android:id="@+id/rel_exam_layout"
android:layout_height="90dp">
<RelativeLayout
android:id="@+id/rel_home_tv_exam_countdown"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_exam_countdown"
android:layout_width="23dp"
android:layout_height="15dp"
android:layout_marginRight="5dp"
android:layout_alignParentLeft="true"
android:text="__s"
android:textSize="12dp"
android:textColor="@color/actionsheet_red"
android:background="@color/white"
/>
</RelativeLayout>
<RelativeLayout
android:layout_marginLeft="5dp"
android:layout_toRightOf="@+id/rel_home_tv_exam_countdown"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--单选多选-->
<LinearLayout
android:id="@+id/ll_exam_SingleOrMore"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/ll_exam_submit"
android:gravity="center"
android:visibility="gone"
android:orientation="horizontal"
>
<CheckBox
android:id="@+id/cb_exam_A"
style="@style/exam_cb_style_SingleOrMore"
android:drawableLeft="@drawable/selector_exam"
android:text="A" />
<CheckBox
android:id="@+id/cb_exam_B"
style="@style/exam_cb_style_SingleOrMore"
android:drawableLeft="@drawable/selector_exam"
android:text="B" />
<CheckBox
android:id="@+id/cb_exam_C"
style="@style/exam_cb_style_SingleOrMore"
android:drawableLeft="@drawable/selector_exam"
android:text="C" />
<CheckBox
android:id="@+id/cb_exam_D"
style="@style/exam_cb_style_SingleOrMore"
android:drawableLeft="@drawable/selector_exam"
android:text="D" />
</LinearLayout>
<!--对错-->
<LinearLayout
android:id="@+id/ll_exam_selectRightOrWrong"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/ll_exam_submit"
android:gravity="center"
android:visibility="gone"
tool:visibility="visible"
android:orientation="horizontal"
>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/rb_exam_R"
style="@style/exam_cb_style_RightOrWrong"
android:drawableLeft="@drawable/selector_exam"
android:checked="true"
android:text="对" />
<RadioButton
android:id="@+id/rb_exam_W"
style="@style/exam_cb_style_RightOrWrong"
android:drawableLeft="@drawable/selector_exam"
android:text="错" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_exam_filling"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/ll_exam_submit"
android:gravity="center"
android:visibility="gone"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="一"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="二"
/>
<EditText
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLength="20"
android:singleLine="true"
android:hint="输入答案"
/>
</LinearLayout>
<!--答案-->
<LinearLayout
android:id="@+id/ll_exam_answer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/ll_exam_submit"
android:gravity="center|left"
android:visibility="gone"
tool:visibility="visible"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的答案:"
/>
<LinearLayout
android:id="@+id/ll_exam_Myanswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正确答案:"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="4dp"
android:background="@mipmap/lv_bj"
android:gravity="center"
android:textColor="@android:color/white"
android:text="C"
android:visibility="gone"
/>
<LinearLayout
android:id="@+id/ll_exam_Correctanswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="正确率:"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20%"
/>
</LinearLayout>
</LinearLayout>
<!--提交-->
<LinearLayout
android:id="@+id/ll_exam_submit"
android:layout_width="100dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginLeft="10dp"
android:layout_alignParentRight="true"
>
<TextView
android:id="@+id/tv_exam_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提交"
android:layout_gravity="center_vertical"
android:textColor="@android:color/white"
android:background="@drawable/shape_bg_full_circle_blue"
android:layout_marginRight="10dp"
android:textSize="12sp"
/>
<TextView
android:id="@+id/tv_exam_cancle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="放弃"
android:layout_gravity="center_vertical"
android:textColor="@android:color/white"
android:background="@drawable/shape_bg_full_circle_grey"
android:layout_marginRight="8dp"
android:textSize="12sp"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
... ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#e3e3e3"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:text="wo jiusldjflkdjf"
android:layout_height="wrap_content" />
</LinearLayout>
\ No newline at end of file
... ...
... ... @@ -30,6 +30,8 @@
<string name="home_title_back">Back</string>
<string name="home_msg_play_audio_init">Audio playback initialization</string>
<string name="home_msg_play_video_init">Video playback initialization</string>
<string name="imge_load_error">Pictures for failure</string>
<!--登录-->
<string name="main_login_error_classId">Please enter class number</string>
<string name="main_login_error_portal">Please enter portal</string>
... ...
... ... @@ -30,6 +30,8 @@
<string name="home_title_back">返回</string>
<string name="home_msg_play_audio_init">音频播放初始化</string>
<string name="home_msg_play_video_init">视频播放初始化</string>
<string name="imge_load_error">图片获取失败</string>
<!--登录-->
<string name="main_login_error_classId">课堂Id不能为空</string>
<string name="main_login_error_portal">服务器地址不能为空</string>
... ...
<resources>
<string name="dialog_cancle">cancel</string>
</resources>
... ...
package com.mang.xdy;
package com.mang.xuedianyun;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
... ...
/*
* SmartPlayer.java
* SmartPlayer
*
* Github: https://github.com/daniulive/SmarterStreaming
* WebSite: http://www.daniulive.com
*
* Created by DaniuLive on 2015/09/26.
* Copyright © 2014~2017 DaniuLive. All rights reserved.
*/
package com.daniulive.smartplayer;
import java.nio.ByteBuffer;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.eventhandle.SmartEventCallback;
import com.videoengine.*;
public class SmartPlayer extends Activity {
private SurfaceView sSurfaceView = null;
private long playerHandle = 0;
private static final int PORTRAIT = 1; //竖屏
private static final int LANDSCAPE = 2; //横屏
private static final String TAG = "SmartPlayer";
private SmartPlayerJni libPlayer = null;
private int currentOrigentation = PORTRAIT;
private boolean isPlaybackViewStarted = false;
private String playbackUrl = null;
private boolean isMute = false;
private boolean isHardwareDecoder = false;
Button btnPopInputText;
Button btnPopInputUrl;
Button btnMute;
Button btnStartStopPlayback;
Button btnHardwareDecoder;
TextView txtCopyright;
TextView txtQQQun;
LinearLayout lLayout = null;
FrameLayout fFrameLayout = null;
private Context myContext;
String url="rtmp://player.daniulive.com:1935/hls/stream";
static {
System.loadLibrary("SmartPlayer");
}
@Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
url=getIntent().getStringExtra("url");
Log.i(TAG, "Run into OnCreate++");
Log.e("URl",url+"");
libPlayer = new SmartPlayerJni();
myContext = this.getApplicationContext();
boolean bViewCreated = CreateView();
if(bViewCreated){
inflateLayout(LinearLayout.VERTICAL);
}
}
/* For smartplayer demo app, the url is based on: baseURL + inputID
* For example:
* baseURL: rtmp://player.daniulive.com:1935/hls/stream
* inputID: 123456
* playbackUrl: rtmp://player.daniulive.com:1935/hls/stream123456
* */
private void GenerateURL(String id){
if(id == null)
return;
if(id.equals("hks"))
{
playbackUrl = "rtmp://live.hkstv.hk.lxdns.com/live/hks";
return;
}
btnStartStopPlayback.setEnabled(true);
// String baseURL = "rtmp://player.daniulive.com:1935/hls/stream";
String baseURL = url;
playbackUrl = baseURL + id;
}
private void SaveInputUrl(String url)
{
playbackUrl = "";
if ( url == null )
return;
// rtmp:/
if ( url.length() < 8 )
{
Log.e(TAG, "Input full url error:" + url);
return;
}
if ( !url.startsWith("rtmp://") && !url.startsWith("rtsp://"))
{
Log.e(TAG, "Input full url error:" + url);
return;
}
btnStartStopPlayback.setEnabled(true);
playbackUrl = url;
Log.i(TAG, "Input full url:" + url);
}
/* Popup InputID dialog */
private void PopDialog(){
final EditText inputID = new EditText(this);
inputID.setFocusable(true);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("如 rtmp://player.daniulive.com:1935/hls/stream123456,请输入123456").setView(inputID).setNegativeButton(
"取消", null);
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// String strID = inputID.getText().toString() ;
String strID = url;
GenerateURL(strID);
}
});
builder.show();
}
private void PopFullUrlDialog(){
final EditText inputUrlTxt = new EditText(this);
inputUrlTxt.setFocusable(true);
inputUrlTxt.setText(url+"");
AlertDialog.Builder builderUrl = new AlertDialog.Builder(this);
builderUrl.setTitle(""+url).setView(inputUrlTxt).setNegativeButton(
"取消", null);
builderUrl.setPositiveButton("确认", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//TODO 这个位置是修改的
String fullUrl =url;
// String fullUrl = inputUrlTxt.getText().toString();
SaveInputUrl(fullUrl);
}
});
builderUrl.show();
}
/* Generate basic layout */
private void inflateLayout(int orientation) {
if (null == lLayout)
lLayout = new LinearLayout(this);
addContentView(lLayout, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
lLayout.setOrientation(orientation);
fFrameLayout = new FrameLayout(this);
LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT, 1.0f);
fFrameLayout.setLayoutParams(lp);
Log.i(TAG, "++inflateLayout..");
sSurfaceView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
fFrameLayout.addView(sSurfaceView, 0);
RelativeLayout outLinearLayout = new RelativeLayout(this);
outLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));
LinearLayout lLinearLayout = new LinearLayout(this);
lLinearLayout.setOrientation(LinearLayout.VERTICAL);
lLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
LinearLayout copyRightLinearLayout = new LinearLayout(this);
copyRightLinearLayout.setOrientation(LinearLayout.VERTICAL);
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rl.topMargin = getWindowManager().getDefaultDisplay().getHeight()-270;
copyRightLinearLayout.setLayoutParams(rl);
txtCopyright=new TextView(this);
txtCopyright.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
txtCopyright.setText("Copyright 2014~2016 www.daniulive.com v1.0.16.0326");
copyRightLinearLayout.addView(txtCopyright, 0);
txtQQQun=new TextView(this);
txtQQQun.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
txtQQQun.setText("学点云");
copyRightLinearLayout.addView(txtQQQun, 1);
/* PopInput button */
btnPopInputText = new Button(this);
btnPopInputText.setText("输入urlID");
btnPopInputText.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
lLinearLayout.addView(btnPopInputText, 0);
btnPopInputUrl = new Button(this);
btnPopInputUrl.setText("输入完整url");
btnPopInputUrl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
lLinearLayout.addView(btnPopInputUrl, 1);
/*mute button */
isMute = false;
btnMute = new Button(this);
btnMute.setText("静音 ");
btnMute.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
lLinearLayout.addView(btnMute, 2);
/*hardware decoder button */
isHardwareDecoder = false;
btnHardwareDecoder = new Button(this);
btnHardwareDecoder.setText("当前软解码");
btnHardwareDecoder.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
lLinearLayout.addView(btnHardwareDecoder, 3);
/* Start playback stream button */
btnStartStopPlayback = new Button(this);
btnStartStopPlayback.setText("开始播放 ");
btnStartStopPlayback.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
lLinearLayout.addView(btnStartStopPlayback, 4);
outLinearLayout.addView(lLinearLayout, 0);
outLinearLayout.addView(copyRightLinearLayout, 1);
fFrameLayout.addView(outLinearLayout, 1);
lLayout.addView(fFrameLayout, 0);
if(isPlaybackViewStarted)
{
btnPopInputText.setEnabled(false);
btnPopInputUrl.setEnabled(false);
btnHardwareDecoder.setEnabled(false);
btnStartStopPlayback.setText("停止播放 ");
}
else
{
btnPopInputText.setEnabled(true);
btnPopInputUrl.setEnabled(true);
btnHardwareDecoder.setEnabled(true);
btnStartStopPlayback.setText("开始播放 ");
}
/* PopInput button listener */
btnPopInputText.setOnClickListener(new Button.OnClickListener() {
// @Override
public void onClick(View v) {
Log.i(TAG, "Run into input playback ID++");
PopDialog();
Log.i(TAG, "Run out from input playback ID--");
}
});
btnPopInputUrl.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
PopFullUrlDialog();
}
});
btnMute.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v) {
isMute = !isMute;
if ( isMute )
{
btnMute.setText("取消静音");
}
else
{
btnMute.setText("静音");
}
if ( playerHandle != 0 )
{
libPlayer.SmartPlayerSetMute(playerHandle, isMute?1:0);
}
}
});
btnHardwareDecoder.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v) {
isHardwareDecoder = !isHardwareDecoder;
if ( isHardwareDecoder )
{
btnHardwareDecoder.setText("当前硬解码");
}
else
{
btnHardwareDecoder.setText("当前软解码");
}
}
});
btnStartStopPlayback.setOnClickListener(new Button.OnClickListener() {
// @Override
public void onClick(View v) {
if(isPlaybackViewStarted)
{
Log.i(TAG, "Stop playback stream++");
btnStartStopPlayback.setText("开始播放 ");
btnPopInputText.setEnabled(true);
btnPopInputUrl.setEnabled(true);
btnHardwareDecoder.setEnabled(true);
libPlayer.SmartPlayerClose(playerHandle);
playerHandle = 0;
isPlaybackViewStarted = false;
Log.i(TAG, "Stop playback stream--");
}
else
{
Log.i(TAG, "Start playback stream++");
playerHandle = libPlayer.SmartPlayerInit(myContext);
if(playerHandle == 0)
{
Log.e(TAG, "surfaceHandle with nil..");
return;
}
libPlayer.SetSmartPlayerEventCallback(playerHandle, new EventHande());
libPlayer.SmartPlayerSetSurface(playerHandle, sSurfaceView); //if set the second param with null, it means it will playback audio only..
// libPlayer.SmartPlayerSetSurface(playerHandle, null);
// External Render test
//libPlayer.SmartPlayerSetExternalRender(playerHandle, new RGBAExternalRender());
//libPlayer.SmartPlayerSetExternalRender(playerHandle, new I420ExternalRender());
libPlayer.SmartPlayerSetAudioOutputType(playerHandle, 0);
libPlayer.SmartPlayerSetBuffer(playerHandle, 200);
if ( isMute )
{
libPlayer.SmartPlayerSetMute(playerHandle, isMute?1:0);
}
if( isHardwareDecoder )
{
Log.i(TAG, "check isHardwareDecoder: " + isHardwareDecoder);
int hwChecking = libPlayer.SetSmartPlayerVideoHWDecoder(playerHandle, isHardwareDecoder?1:0);
Log.i(TAG, "[daniulive] hwChecking: " + hwChecking);
}
//It only used when playback RTSP stream..
// libPlayer.SmartPlayerSetRTSPTcpMode(playerHandle, 1);
//playbackUrl = "rtmp://live.hkstv.hk.lxdns.com/live/hks";
//playbackUrl = "rtsp://rtsp-v3-spbtv.msk.spbtv.com/spbtv_v3_1/214_110.sdp";
//playbackUrl = "rtmp://10.2.68.91:1935/hls/stream8";
if(playbackUrl == null){
Log.e(TAG, "playback URL with NULL...");
return;
}
int iPlaybackRet = libPlayer.SmartPlayerStartPlayback(playerHandle, playbackUrl);
if(iPlaybackRet != 0)
{
Log.e(TAG, "StartPlayback strem failed..");
return;
}
btnStartStopPlayback.setText("停止播放 ");
btnPopInputText.setEnabled(false);
btnPopInputUrl.setEnabled(false);
btnHardwareDecoder.setEnabled(false);
isPlaybackViewStarted = true;
Log.i(TAG, "Start playback stream--");
}
}
});
}
public static final String bytesToHexString(byte[] buffer)
{
StringBuffer sb = new StringBuffer(buffer.length);
String temp;
for (int i = 0; i < buffer.length; ++i)
{
temp = Integer.toHexString(0xff&buffer[i]);
if (temp.length() < 2)
sb.append(0);
sb.append(temp);
}
return sb.toString();
}
class RGBAExternalRender implements NTExternalRender
{
//public static final int NT_FRAME_FORMAT_RGBA = 1;
//public static final int NT_FRAME_FORMAT_ABGR = 2;
//public static final int NT_FRAME_FORMAT_I420 = 3;
private int width_ = 0;
private int height_ = 0;
private int row_bytes_ = 0;
private ByteBuffer rgba_buffer_ = null;
@Override
public int getNTFrameFormat()
{
Log.i(TAG, "RGBAExternalRender::getNTFrameFormat return "+ NT_FRAME_FORMAT_RGBA);
return NT_FRAME_FORMAT_RGBA;
}
@Override
public void onNTFrameSizeChanged(int width, int height)
{
width_ = width;
height_ = height;
row_bytes_ = width_ * 4;
Log.i(TAG, "RGBAExternalRender::onNTFrameSizeChanged width_:" + width_ + " height_:" + height_);
rgba_buffer_ = ByteBuffer.allocateDirect(row_bytes_*height_);
}
@Override
public ByteBuffer getNTPlaneByteBuffer(int index)
{
if ( index == 0 )
{
return rgba_buffer_;
}
else
{
Log.e(TAG, "RGBAExternalRender::getNTPlaneByteBuffer index error:" + index);
return null;
}
}
@Override
public int getNTPlanePerRowBytes(int index)
{
if ( index == 0 )
{
return row_bytes_;
}
else
{
Log.e(TAG, "RGBAExternalRender::getNTPlanePerRowBytes index error:" + index);
return 0;
}
}
public void onNTRenderFrame()
{
if( rgba_buffer_ == null )
return;
rgba_buffer_.rewind();
// copy buffer
// test
// byte[] test_buffer = new byte[16];
// rgba_buffer_.get(test_buffer);
//Log.i(TAG, "RGBAExternalRender:onNTRenderFrame rgba:" + bytesToHexString(test_buffer));
}
}
class I420ExternalRender implements NTExternalRender
{
//public static final int NT_FRAME_FORMAT_RGBA = 1;
//public static final int NT_FRAME_FORMAT_ABGR = 2;
//public static final int NT_FRAME_FORMAT_I420 = 3;
private int width_ = 0;
private int height_ = 0;
private int y_row_bytes_ = 0;
private int u_row_bytes_ = 0;
private int v_row_bytes_ = 0;
private ByteBuffer y_buffer_ = null;
private ByteBuffer u_buffer_ = null;
private ByteBuffer v_buffer_ = null;
@Override
public int getNTFrameFormat()
{
Log.i(TAG, "I420ExternalRender::getNTFrameFormat return "+ NT_FRAME_FORMAT_I420);
return NT_FRAME_FORMAT_I420;
}
@Override
public void onNTFrameSizeChanged(int width, int height)
{
width_ = width;
height_ = height;
y_row_bytes_ = (width_ + 15) & (~15);
u_row_bytes_ = ((width_+1)/2 + 15) & (~15);
v_row_bytes_ = ((width_+1)/2 + 15) & (~15);
y_buffer_ = ByteBuffer.allocateDirect(y_row_bytes_*height_);
u_buffer_ = ByteBuffer.allocateDirect(u_row_bytes_*(height_+1)/2);
v_buffer_ = ByteBuffer.allocateDirect(v_row_bytes_*(height_+1)/2);
Log.i(TAG, "I420ExternalRender::onNTFrameSizeChanged width_="
+ width_ + " height_=" + height_
+ " y_row_bytes_=" + y_row_bytes_
+ " u_row_bytes_=" + u_row_bytes_
+ " v_row_bytes_=" + v_row_bytes_);
}
@Override
public ByteBuffer getNTPlaneByteBuffer(int index)
{
if ( index == 0 )
{
return y_buffer_;
}
else if ( index == 1 )
{
return u_buffer_;
}
else if ( index == 2 )
{
return v_buffer_;
}
else
{
Log.e(TAG, "I420ExternalRender::getNTPlaneByteBuffer index error:" + index);
return null;
}
}
@Override
public int getNTPlanePerRowBytes(int index)
{
if ( index == 0 )
{
return y_row_bytes_;
}
else if ( index == 1)
{
return u_row_bytes_;
}
else if (index == 2 )
{
return v_row_bytes_;
}
else
{
Log.e(TAG, "I420ExternalRender::getNTPlanePerRowBytes index error:" + index);
return 0;
}
}
public void onNTRenderFrame()
{
if ( y_buffer_ == null )
return;
if ( u_buffer_ == null )
return;
if ( v_buffer_ == null )
return;
y_buffer_.rewind();
u_buffer_.rewind();
v_buffer_.rewind();
// copy buffer
// test
// byte[] test_buffer = new byte[16];
// y_buffer_.get(test_buffer);
// Log.i(TAG, "I420ExternalRender::onNTRenderFrame y data:" + bytesToHexString(test_buffer));
// u_buffer_.get(test_buffer);
// Log.i(TAG, "I420ExternalRender::onNTRenderFrame u data:" + bytesToHexString(test_buffer));
// v_buffer_.get(test_buffer);
// Log.i(TAG, "I420ExternalRender::onNTRenderFrame v data:" + bytesToHexString(test_buffer));
}
}
class EventHande implements SmartEventCallback
{
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5){
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.i(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.i(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.i(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.i(TAG, "连接成功。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.i(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.i(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.i(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
/* Create rendering */
private boolean CreateView() {
if(sSurfaceView == null)
{
/*
* useOpenGLES2:
* If with true: Check if system supports openGLES, if supported, it will choose openGLES.
* If with false: it will set with default surfaceView;
*/
sSurfaceView = NTRenderer.CreateRenderer(this, true);
}
if(sSurfaceView == null)
{
Log.i(TAG, "Create render failed..");
return false;
}
return true;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG, "Run into onConfigurationChanged++");
if (null != fFrameLayout)
{
fFrameLayout.removeAllViews();
fFrameLayout = null;
}
if (null != lLayout)
{
lLayout.removeAllViews();
lLayout = null;
}
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
Log.i(TAG, "onConfigurationChanged, with LANDSCAPE。。");
inflateLayout(LinearLayout.HORIZONTAL);
currentOrigentation = LANDSCAPE;
}
else
{
Log.i(TAG, "onConfigurationChanged, with PORTRAIT。。");
inflateLayout(LinearLayout.VERTICAL);
currentOrigentation = PORTRAIT;
}
if(!isPlaybackViewStarted)
return;
libPlayer.SmartPlayerSetOrientation(playerHandle, currentOrigentation);
Log.i(TAG, "Run out of onConfigurationChanged--");
}
@Override
protected void onDestroy()
{
Log.i(TAG, "Run into activity destory++");
if(playerHandle!=0)
{
libPlayer.SmartPlayerClose(playerHandle);
playerHandle = 0;
}
super.onDestroy();
finish();
// System.exit(0);
}
}
\ No newline at end of file
... ... @@ -23,6 +23,15 @@ public class VideoPlayBean {
private String rtmpUrl;
private String replay;
private int seek;
private String userRole;
public String getUserRole() {
return userRole;
}
public void setUserRole(String userRole) {
this.userRole = userRole;
}
public int getMediaId() {
return mediaId;
... ... @@ -79,4 +88,18 @@ public class VideoPlayBean {
public void setSeek(int seek) {
this.seek = seek;
}
@Override
public String toString() {
return "VideoPlayBean{" +
"mediaId=" + mediaId +
", fromNodeId=" + fromNodeId +
", userName='" + userName + '\'' +
", m3u8Url='" + m3u8Url + '\'' +
", rtmpUrl='" + rtmpUrl + '\'' +
", replay='" + replay + '\'' +
", seek=" + seek +
", userRole='" + userRole + '\'' +
'}';
}
}
... ...
... ... @@ -182,6 +182,11 @@ public interface Constants {
* 开始录制回放
*/
String START_RECORD_PLAY_BACK="startRecordPlayback";
/**
* 主持人角色
*/
String HOST="host";
String UN_PUBLISH_VIDEO="unPublishVideo";
/*Context为空的时候给出的提示*/
String ERROR_CONTENT_NULL="Xdy,init context is null";
... ...
... ... @@ -7,20 +7,14 @@ package com.mang.xdy.core;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.text.NoCopySpan;
import android.text.TextUtils;
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 com.mang.xdy.common.Constants;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
/**
* 数据的异常检测都放在最外层(便于给用户提示),这层默认数据都是完整
... ... @@ -125,10 +119,10 @@ public class XdyJsCore {
@JavascriptInterface
public void _js2native(String id,String parmp){
/* _native2js("接口名称","参数为JOSN字符串")*/
// XdyLogUtil.e("s3sjs2native","id:"+id+" parmp:"+parmp);
if(mOnXdyAsyncMessageListener !=null){
mOnXdyAsyncMessageListener.getSdyAsyncMessageListener(id,parmp);
}
XdyLogUtil.e("s3sjs2native","id:"+id+" parmp:"+parmp);
// if(mOnXdyAsyncMessageListener !=null){
// mOnXdyAsyncMessageListener.getSdyAsyncMessageListener(id,parmp);
// }
XdySdk.getXdyInstance().notifyObserver(id, parmp);
}
}
... ...
package com.mang.xdy.core;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import com.eventhandle.SmartEventCallback;
import com.google.gson.Gson;
import com.mang.xdy.bean.AudioPlayBean;
import com.mang.xdy.bean.ErrorCodeEntity;
import com.mang.xdy.bean.GetPublishPathReceiveBean;
import com.mang.xdy.bean.PublisherSuccessEntity;
import com.mang.xdy.bean.PublisherVideoReturnBean;
import com.mang.xdy.bean.VideoPlayBean;
import com.mang.xdy.cache.ACache;
import com.mang.xdy.common.Constants;
import com.mang.xdy.listener.ObserverListener;
import com.mang.xdy.listener.SubjectListener;
import com.mang.xdy.message.MsgManage;
import com.mang.xdy.play.XdyPlayer;
import com.mang.xdy.play.XdyPublisher;
import com.mang.xdy.utils.JsonUtil;
import com.mang.xdy.utils.NetWorkUtils;
import com.mang.xdy.utils.PlayerUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import static com.mang.xdy.utils.PlayerUtils.getPublishPathAudio;
import static com.mang.xdy.utils.PlayerUtils.getPublishPathVideo;
/**
* 对外调用的接口
* Created by abao on 2017/3/31.
* 受原先的文档设计的规则,所有方法的都是静态的方法,影响性能
* 考虑跟换文档,提升性能
*/
public class XdySdk implements SubjectListener{
/**
* 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件
*/
private static XdyJsCore mXdyJsCore;
private static XdySdk mXdySdk;
private static Context mContext;
private XdyPlayer mXdyPlayer;
private XdyPublisher mXdyPublisher;
/*消息管理*/
private static MsgManage mMsgManage;
public static String TAG="xdysdk";
/*当前播放视频的id*/
private String currentPlayId="";
/*缓存管理*/
private static ACache aCache;
//TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏)
private SurfaceView mSurfaceView_Publish;
private Activity mActivity;
/*是否正在推流,mcu自动断开,onPause使用的时候使用,推流成功后才表示正在使用*/
private boolean isPublisher =false;
// /*Audio 推送中,resume需要使用*/
private boolean isPublisherAudio=false;
/*推流重连状态,如果是重连状态会有一系列加入课堂的情况*/
private boolean isReconnection=false;
/*是否进行录制回放*/
private boolean isRecordPlayBack=false;
/*观察者集合*/
private List<ObserverListener> observerListenerList=new ArrayList<ObserverListener>();
/*推流地址*/
private String publish_url="";
/*保存nodeid ,自己的唯一标识*/
private int mNodeId =0;
@Override
public void add(ObserverListener observerListener) {
observerListenerList.add(observerListener);
}
@Override
public void notifyObserver(String type, String parameter) {
handleData(type,parameter);
XdyLogUtil.e("notifyObserVer","type:"+type+" parameter:"+parameter);
}
@Override
public void remove(ObserverListener observerListener) {
if(observerListenerList!=null){
if(observerListenerList.contains(observerListener)) {
observerListenerList.remove(observerListener);
}
}
}
private XdySdk(){
}
private static Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.LEAVE_CLASS_CODE){
if(!NetWorkUtils.isNetworkConnected(mContext)) {
if (mXdySdk != null) {
mXdySdk.onPublisherStop();
handler.removeCallbacksAndMessages(null);
}
}
}
}
};
/**
* 初始化
* @param context
*/
public static void init(final Context context){
if(context==null){
throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL);
}
aCache=ACache.get(context);
mContext=context;
mXdyJsCore = XdyJsCore.getInstance(context);
mMsgManage=MsgManage.getErrorMsgInstance();
}
/**
* 接收用户传递进来的参数(两个String 的参数都在这里处理)
* @param type 类型
* @param argument 参数
*/
public void api(final String type, final String argument){
judgeCore();
//再次停止播放器
switch (type){
case "stopPublishAudio":
//停止推送音频
case "stopPublishVideo":
//停止推流video(关闭视频:根据api)
onPublisherStop();
break;
case "stopAudio":
//停止播放audio()
case"stopVideo":
//停止播放video( 停止播放:根据api)
onPlayDestroy();
break;
}
if(!isRecordPlayBack &&!judegeNetOK()){
return;
}
handler.post(new Runnable() {
@Override
public void run() {
mXdyJsCore.native2js(type, argument);
}
});
}
/**
*
* @param type
* @param
* @param surfaceView
* @param activity
* @param
*
*/
public void api(String type,String mediaId, SurfaceView surfaceView, Activity activity) {
judgeString(type);
if(!isRecordPlayBack &&!judegeNetOK()){
return;
}
switch (type) {
case Constants.PLAY_AUDIO:
//判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
String json_audio= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_audio)){
//TODO/给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Audio Can not find this mediaId");
return;
}
currentPlayId=mediaId;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(json_audio,AudioPlayBean.class);
if(audioPlayBean!=null) {
String play_url_audio="";
if(isRecordPlayBack){
//如果是回放给出。m3u8的id用户 用户需要自己获取play_url_audio=audioPlayBean.getReplay();
}else{
play_url_audio=audioPlayBean.getRtmpUrl() ;
if(mXdyPlayer ==null) {
mXdyPlayer = XdyPlayer.getXdyPlayerCore(play_url_audio, activity);
}else{
mXdyPlayer.onStopPlay();
}
mXdyPlayer.playAudio(play_url_audio, new EventHande_Play());
}
}else{
XdyLogUtil.e(TAG,"Can not get play Audio response");
}
break;
case Constants.PLAY_VIDEO:
//播放视频
// 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
String json_video= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_video)){
///给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Video Can not find this mediaId");
return;
}
currentPlayId=mediaId;
VideoPlayBean videoPlayBean=JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class);
if(videoPlayBean!=null){
String play_url_video="";
if(isRecordPlayBack){
// play_url_video=videoPlayBean.getReplay();
}else{
play_url_video=videoPlayBean.getRtmpUrl();
if(mXdyPlayer ==null) {
mXdyPlayer = XdyPlayer.getXdyPlayerCore(play_url_video, activity);
}else{
//重复播放时候
mXdyPlayer.onStopPlay();
}
mXdyPlayer.playVideo(play_url_video, surfaceView,new EventHande_Play());
}
}else{
//统一提示推流错误
XdyLogUtil.e(TAG,"Can not get play Video response");
}
break;
case Constants.PUBLISH_VIDEO:
/**
* 用户发起这个推流的请求的时候,
* 1,去获取推流地址
* 2,判断地址时候有用,有用的话打开播放器,开启推流的过程
* 3,推流成功告知后台,和用户
*/
getPublishPathVideo();
mSurfaceView_Publish=surfaceView;
mActivity=activity;
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
getPublishPathAudio();
mActivity=activity;
break;
}
}
/*判断是否被初始化*/
private void judgeCore(){
if(mXdyJsCore==null){
throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT);
}
}
/*判断type是否为空*/
private void judgeString(String type){
if(TextUtils.isEmpty(type)){
XdyLogUtil.e(TAG,Constants.ERROR_TYPE_NULL);
}
}
/*判断网路是否正常*/
private boolean judegeNetOK(){
if( !NetWorkUtils.isNetworkConnected(mContext)){
String errorJson="{\n" +
" \"code\": 20000,\n" +
" \"reson\": \"无网络连接,请检查网络\"\n" +
"}";
notifyObserver(Constants.ERROR_CODE, errorJson);
return false;
}
return true;
}
public static XdySdk getXdyInstance(){
if(mXdySdk ==null){
synchronized (XdySdk.class){
mXdySdk =new XdySdk();
}
}
return mXdySdk;
}
/**
*core获取到的数据处理
* @param type
* @param response
*/
private void handleData(String type,String response){
//开始处理推流信息,用户只需要传递surfaceview activity, 内部处理url
/*需要处理的信息有playVideo 返回的url地址, 遇到video_play ,和
audio
plublisher Video
publisher Audio
*/
switch (type) {
case Constants.CLASS_JOIN_SUCCESS:
//判断是否是录制回放,调整播流地址
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
isRecordPlayBack = jsonObject.optBoolean("isRecordPlayBack");
mNodeId =jsonObject.optInt("nodeId");
XdyLogUtil.e("获取的id",""+mNodeId);
} catch (JSONException e) {
e.printStackTrace();
}
handleListener(type,response);
break;
case Constants.VIDEO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
// String publishPath=XdyStringUtils.stringToJson(response);
String publishPath=response;
GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean!=null) {
//可以推流了
if (getPublishPathReceiveBean.getCode() == 0) {
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用video_get_publish_path关键字 只支持做只支一路
String video_url = getPublishPathReceiveBean.getPublishUrl();
aCache.put(Constants.VIDEO_GET_PUBLISH_PATH, video_url);
//判断
if (mSurfaceView_Publish == null) {
//todo 输出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_SURFACEVIEW);
}
if (mActivity == null) {
//TODo 给出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_ACTIVITY);
}
if (mXdyPublisher == null) {
mXdyPublisher = new XdyPublisher(1, 1, mActivity);
}else{
//todo 如果不为空的话是已经播放过,得清理上次的
// mXdyPlayer.onPause();
}
publish_url=video_url;
isPublisher =true;
isPublisherAudio=false;
mXdyPublisher.publisher(video_url,mSurfaceView_Publish, new EventHande_Publish());
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
setPublishSendSuccessVideo(video_url);
}else{
mMsgManage.getPublishVideoPathError();
}
}else{
//给出提示
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.AUDIO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
String audio_path=response;
GetPublishPathReceiveBean getPublishPathReceiveBean_Audio=JsonUtil.parseJsonToBean(audio_path,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean_Audio!=null&&getPublishPathReceiveBean_Audio.getCode()==0){
//可以推流了
String audio_url=getPublishPathReceiveBean_Audio.getPublishUrl();
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字
aCache.put(Constants.GET_AUDIO_PUBLISH_PATH,audio_url);
//判断
// if (mSurfaceView==null){
// //todo 输出提示
// XdyLogUtil.e(TAG,"surfaceView is null");
// return;
// }
if(mActivity==null){
//TODo 给出提示
XdyLogUtil.e(TAG,"activity is null");
return;
}
if(mXdyPublisher ==null) {
mXdyPublisher = new XdyPublisher(1, 0, mActivity);
}else {
//todo 如果不为空的话是已经播放过,得清理上次的
// mXdyPlayer.onPause();
}
mXdyPublisher.publisherAudio(audio_url,new EventHande_Publish());
publish_url=audio_url;
isPublisher =true;
isPublisherAudio=true;
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
PlayerUtils.setPublishSendSuccessAudio(audio_url);
}else{
//给出提示
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
//接收后台是否接收到推流URl的地址
String publishReplay_Audio=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay_Audio));
PublisherVideoReturnBean publisherVideoReturnBean_audio=JsonUtil.parseJsonToBean(XdyStringUtils.stringToJson(publishReplay_Audio),PublisherVideoReturnBean.class);
if(publisherVideoReturnBean_audio!=null&&publisherVideoReturnBean_audio.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}
break;
case Constants.VIDEO_PUBLISH_RESULT:
//接收发送推流地址给后台返回的信息
String publishReplay=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay));
PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class);
if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.VIDEO_PLAY:
//获取推流的地址,需要保存起来
//解析数据拿出mediaId 作为主键 将media 释放的给用户可能有多个播放的情况
String video=response;
VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(video,VideoPlayBean.class);
if(videoPlayBean!=null) {
// if(videoPlayBean.getMediaId()!=videoPlayBean.getFromNodeId()) {
if(mNodeId !=videoPlayBean.getFromNodeId()) {
//过滤自己推送的video
aCache.put(videoPlayBean.getMediaId() + "", video);
handleListener(type, videoPlayBean.getMediaId() + "");
}
}else{
XdyLogUtil.e(TAG,"video play json error");
}
break;
case Constants.AUDIO_PLAY:
String audio=response;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(audio,AudioPlayBean.class);
if(audioPlayBean!=null){
// if(audioPlayBean.getMediaId()!=audioPlayBean.getFromNodeId()) {
if(mNodeId !=audioPlayBean.getFromNodeId()) {
aCache.put(audioPlayBean.getMediaId() + "", audio);
handleListener(type, audioPlayBean.getMediaId() + "");
}
}
break;
case Constants.ERROR_CODE:
ErrorCodeEntity errorCodeEntity =JsonUtil.parseJsonToBean(response,ErrorCodeEntity.class);
if(errorCodeEntity!=null){
if(errorCodeEntity.getCode()==Constants.LEAVE_CLASS_CODE){
/**
* 方案 一 1,正在直播的时候mcu无故断开,需要重新连接
* 2,class exit 时候主动课堂停止,停止推流
* 利用mcu的生命周期,加入课堂成功后去请求数据
*/
// 方案 二 mcu 断开,页面也断开,用户需要手动重新调用
if(isPublisher) {
if(!NetWorkUtils.isNetworkConnected(mContext)){
//todo判断是否有网络,没有网络的话就让其退出
// TOdo 延迟5秒,
// onPublisherStop();
handler.sendEmptyMessageDelayed(Constants.LEAVE_CLASS_CODE,Constants.TIME_NET_ERROR_RECONNECTION);
}
isReconnection=true;
}
}
}
handleListener(type,response);
break;
case Constants.CLASS_EXIT:
/**
* 处理正在推流视频,课堂退出的情况,(用户操作退出界面)
* 此时,停止推流,清除surfaceview Activtity 数据,url数据
*/
if(isPublisher){
onPublisherStop();
}
handleListener(type,response);
break;
default:{
handleListener(type,response);
}
}
}
/**
* 处理所有向外发送的接口数据
* @param type
* @param parameter
*/
private void handleListener(String type,String parameter){
XdyLogUtil.e(TAG,"type:"+type+"parameter:"+parameter);
for(ObserverListener o:observerListenerList){
o.observerUpData(type,parameter);
}
}
/**
* 销毁播放音视频
* @param id
* @return
*/
public boolean onPlayStop(String id){
if(currentPlayId.equals(id)) {
if (mXdyPlayer != null) {
mXdyPlayer.onStopPlay();
// mXdyPlayer = null;
}
return true;
}
return false;
}
/**
* 退出时清除信息(重置js监听)
*/
public void removeAll(){
if(mXdyPlayer !=null) {
mXdyPlayer.onPause();
}
if(mXdyJsCore!=null&&!isRecordPlayBack) {
mXdyJsCore.init(mContext);
}
onPublisherStop();
}
/**
* 结束时调用
*/
public void onPlayDestroy(){
if (mXdyPlayer != null) {
mXdyPlayer.onStopPlay();
mXdyPlayer = null;
}
}
/**
* 推送视频音频停止方法(最后调用的方法)
* @deprecated daniu sdk handle best
*/
public void onPublisherStop(){
if(mXdyPublisher !=null){
mXdyPublisher.onStopPublisher();
mXdyPublisher =null;
}
//如果正在推流,msurfaceView ,mActivity不清空
if(!isPublisher) {
if (mSurfaceView_Publish != null) {
mSurfaceView_Publish = null;
}
if (mActivity != null) {
mActivity = null;
}
}
isPublisher =false;
isReconnection=false;
isPublisherAudio=false;
}
/**
* onPause 方法时走的周期
* 推送视频暂停调用,单独提出,不与play合并考虑到有后台继续推送的情况
*/
public void onPublisherPause(){
if(mXdyPublisher !=null){
mXdyPublisher.onPausePublisher();
}
}
/**
*
* TODO 只有一个boolean
* 开始isPublish 为false
* 开始推流初始化后onresume 就是开始
* 大牛 sdk处理的更好
*/
public void onPublisherResume(){
if(!isPublisher){
return;
}
if(mXdyPublisher !=null) {
mXdyPublisher.onResumePublisher();
if (!TextUtils.isEmpty(publish_url)) {
if(!isPublisherAudio){
mXdyPublisher.publisher(publish_url, mSurfaceView_Publish, new EventHande_Publish());
}else{
mXdyPublisher.publisherAudio(publish_url,new EventHande_Publish());
}
}
}
}
class EventHande_Play implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
class EventHande_Publish implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
// notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
// notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
/**
* 向后台发送推流数据(Auido)成功信息
* @param url
*/
protected static void setPublishSendSuccessAudio(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdySdk.getXdyInstance().api(Constants.PUBLISH_AUDIO, pamp);
}
}
/**
* 向后台发送推流(Video)成功的信息
* @param url
*/
protected static void setPublishSendSuccessVideo(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdyLogUtil.e("setPublishSendSuccessVideo:",Thread.currentThread().getId()+"");
XdySdk.getXdyInstance().api(Constants.PUBLISH_VIDEO, pamp);
}
}
}
package com.mang.xdy.core;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import com.eventhandle.SmartEventCallback;
import com.google.gson.Gson;
import com.mang.xdy.bean.GetPublishPathReceiveBean;
import com.mang.xdy.bean.PublisherSuccessEntity;
import com.mang.xdy.bean.VideoPlayBean;
import com.mang.xdy.common.Constants;
import com.mang.xdy.listener.ObserverListener;
import com.mang.xdy.listener.SubjectListener;
import com.mang.xdy.play.XdyPlayer;
import com.mang.xdy.utils.JsonUtil;
import com.mang.xdy.utils.PlayerUtils;
import com.mang.xdy.bean.AudioPlayBean;
import com.mang.xdy.bean.ErrorCodeEntity;
import com.mang.xdy.bean.PublisherVideoReturnBean;
import com.mang.xdy.cache.ACache;
import com.mang.xdy.message.MsgManage;
import com.mang.xdy.play.XdyPublisher;
import com.mang.xdy.utils.NetWorkUtils;
import com.mang.xdy.utils.XdyLogUtil;
import com.mang.xdy.utils.XdyStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
/**
* 对外调用的接
* 受原先的文档设计的规则,所有方法的都是静态的方法,影响性能
* 考虑跟换文档,提升性能
*/
public class XdySdk implements SubjectListener {
/**
* 用户初始化,还是调用各种方法,都需要统一的对外给出监听事件
*/
private static XdyJsCore mXdyJsCore;
private static XdySdk mXdySdk;
private static Context mContext;
private XdyPlayer mXdyPlayer;
private XdyPublisher mXdyPublisher;
/*消息管理*/
private static MsgManage mMsgManage;
public static String TAG="xdysdk";
/*当前播放视频的id*/
private String currentPlayId="";
/*缓存管理*/
private static ACache aCache;
//TODO 拿不到同步的数据先保留信息(必须释放,否者内存泄漏)
private SurfaceView mSurfaceView_Publish;
private Activity mActivity;
/*是否正在推流,mcu自动断开,onPause使用的时候使用,推流成功后才表示正在使用*/
private boolean isPublisher =false;
// /*Audio 推送中,resume需要使用*/
private boolean isPublisherAudio=false;
/*推流重连状态,如果是重连状态会有一系列加入课堂的情况*/
private boolean isReconnection=false;
/*是否进行录制回放*/
private boolean isRecordPlayBack=false;
/*观察者集合*/
private List<ObserverListener> observerListenerList=new ArrayList<ObserverListener>();
/*推流地址*/
private String publish_url="";
/*保存nodeid ,自己的唯一标识*/
private int mNodeId =0;
/*z正在播放视频 onStop 重置状态,是否是Host 在播放视频,这个优先级最高,1v1 产物*/
private boolean isCurrentVideoHost=false;
private boolean isCurrentAudioHost=false;
@Override
public void add(ObserverListener observerListener) {
observerListenerList.add(observerListener);
}
@Override
public void notifyObserver(String type, String parameter) {
handleData(type,parameter);
XdyLogUtil.e("notifyObserVer","type:"+type+" parameter:"+parameter);
}
@Override
public void remove(ObserverListener observerListener) {
if(observerListenerList!=null){
if(observerListenerList.contains(observerListener)) {
observerListenerList.remove(observerListener);
}
}
}
private XdySdk(){
}
private static Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what== Constants.LEAVE_CLASS_CODE){
if(!NetWorkUtils.isNetworkConnected(mContext)) {
if (mXdySdk != null) {
mXdySdk.onPublisherStop();
handler.removeCallbacksAndMessages(null);
}
}
}
}
};
/**
* 初始化
* @param context
*/
public static void init(final Context context){
if(context==null){
throw new IllegalArgumentException(Constants.ERROR_CONTENT_NULL);
}
aCache=ACache.get(context);
mContext=context;
mXdyJsCore = XdyJsCore.getInstance(context);
mMsgManage=MsgManage.getErrorMsgInstance();
}
/**
* 接收用户传递进来的参数(两个String 的参数都在这里处理)
* @param type 类型
* @param argument 参数
*/
public void api(final String type, final String argument){
judgeCore();
//再次停止播放器
switch (type){
case "stopPublishAudio":
//停止推送音频
case "stopPublishVideo":
//停止推流video(关闭视频:根据api)
onPublisherStop();
break;
case "stopAudio":
//停止播放audio()
isCurrentAudioHost=false;
onPlayDestroy();
break;
case"stopVideo":
//停止播放video( 停止播放:根据api)
isCurrentVideoHost=false;
onPlayDestroy();
break;
}
if(!isRecordPlayBack &&!judegeNetOK()){
return;
}
handler.post(new Runnable() {
@Override
public void run() {
mXdyJsCore.native2js(type, argument);
}
});
}
/**
*
* @param type
* @param
* @param surfaceView
* @param activity
* @param
*
*/
public void api(String type,String mediaId, SurfaceView surfaceView, Activity activity) {
judgeString(type);
if(!isRecordPlayBack &&!judegeNetOK()){
return;
}
switch (type) {
case Constants.PLAY_AUDIO:
//判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
String json_audio= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_audio)){
//TODO/给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Audio Can not find this mediaId");
return;
}
AudioPlayBean audioPlayBean= JsonUtil.parseJsonToBean(json_audio,AudioPlayBean.class);
if(audioPlayBean!=null) {
String play_url_audio="";
if(isRecordPlayBack){
//如果是回放给出。m3u8的id用户 用户需要自己获取play_url_audio=audioPlayBean.getReplay();
}else{
//如果是host权限的在播放,下次在播放必须是host
if(isCurrentAudioHost){
if(!Constants.HOST.equals(audioPlayBean.getUserRole())){
return;
}
}
if(Constants.HOST.equals(audioPlayBean.getUserRole())){
isCurrentAudioHost=true;
}
play_url_audio=audioPlayBean.getRtmpUrl() ;
if(mXdyPlayer ==null) {
mXdyPlayer = XdyPlayer.getXdyPlayerCore(play_url_audio, activity);
}else{
mXdyPlayer.onStopPlay();
}
mXdyPlayer.playAudio(play_url_audio, new EventHande_Play());
currentPlayId=mediaId;
}
}else{
XdyLogUtil.e(TAG,"Can not get play Audio response");
}
break;
case Constants.PLAY_VIDEO:
//播放视频
// 判断mediaId (仅播放需要)通过取得value 如果为空的话表示输入的数据有误
String json_video= aCache.getAsString(mediaId);
if(TextUtils.isEmpty(json_video)){
///给出相应的提示表示没有 这个id
XdyLogUtil.e(TAG,"Play Video Can not find this mediaId");
return;
}
VideoPlayBean videoPlayBean=JsonUtil.parseJsonToBean(json_video,VideoPlayBean.class);
if(videoPlayBean!=null){
String play_url_video="";
if(isRecordPlayBack){
// play_url_video=videoPlayBean.getReplay();
}else{
//如果是host权限的在播放,下次在播放必须是host
if(isCurrentVideoHost){
if(!Constants.HOST.equals(videoPlayBean.getUserRole())){
return;
}
}
if(Constants.HOST.equals(videoPlayBean.getUserRole())){
isCurrentVideoHost=true;
}
play_url_video=videoPlayBean.getRtmpUrl();
if(mXdyPlayer ==null) {
mXdyPlayer = XdyPlayer.getXdyPlayerCore(play_url_video, activity);
}else{
//重复播放时候
mXdyPlayer.onStopPlay();
}
mXdyPlayer.playVideo(play_url_video, surfaceView,new EventHande_Play());
currentPlayId=mediaId;
}
}else{
//统一提示推流错误
XdyLogUtil.e(TAG,"Can not get play Video response");
}
break;
case Constants.PUBLISH_VIDEO:
/**
* 用户发起这个推流的请求的时候,
* 1,去获取推流地址
* 2,判断地址时候有用,有用的话打开播放器,开启推流的过程
* 3,推流成功告知后台,和用户
*/
PlayerUtils.getPublishPathVideo();
mSurfaceView_Publish=surfaceView;
mActivity=activity;
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
PlayerUtils.getPublishPathAudio();
mActivity=activity;
break;
}
}
/*判断是否被初始化*/
private void judgeCore(){
if(mXdyJsCore==null){
throw new IllegalArgumentException(Constants.ERROR_XDYCORE_INIT);
}
}
/*判断type是否为空*/
private void judgeString(String type){
if(TextUtils.isEmpty(type)){
XdyLogUtil.e(TAG,Constants.ERROR_TYPE_NULL);
}
}
/*判断网路是否正常*/
private boolean judegeNetOK(){
if( !NetWorkUtils.isNetworkConnected(mContext)){
String errorJson="{\n" +
" \"code\": 20000,\n" +
" \"reson\": \"无网络连接,请检查网络\"\n" +
"}";
notifyObserver(Constants.ERROR_CODE, errorJson);
return false;
}
return true;
}
public static XdySdk getXdyInstance(){
if(mXdySdk ==null){
synchronized (XdySdk.class){
mXdySdk =new XdySdk();
}
}
return mXdySdk;
}
/**
*core获取到的数据处理
* @param type
* @param response
*/
private void handleData(String type,String response){
//开始处理推流信息,用户只需要传递surfaceview activity, 内部处理url
/*需要处理的信息有playVideo 返回的url地址, 遇到video_play ,和
audio
plublisher Video
publisher Audio
*/
switch (type) {
case Constants.CLASS_JOIN_SUCCESS:
//判断是否是录制回放,调整播流地址
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
isRecordPlayBack = jsonObject.optBoolean("isRecordPlayBack");
mNodeId =jsonObject.optInt("nodeId");
XdyLogUtil.e("获取的id",""+mNodeId);
} catch (JSONException e) {
e.printStackTrace();
}
handleListener(type,response);
break;
case Constants.VIDEO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
// String publishPath=XdyStringUtils.stringToJson(response);
String publishPath=response;
GetPublishPathReceiveBean getPublishPathReceiveBean=JsonUtil.parseJsonToBean(publishPath,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean!=null) {
//可以推流了
if (getPublishPathReceiveBean.getCode() == 0) {
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用video_get_publish_path关键字 只支持做只支一路
String video_url = getPublishPathReceiveBean.getPublishUrl();
aCache.put(Constants.VIDEO_GET_PUBLISH_PATH, video_url);
//判断
if (mSurfaceView_Publish == null) {
//todo 输出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_SURFACEVIEW);
}
if (mActivity == null) {
//TODo 给出提示
throw new IllegalArgumentException(Constants.ERROR_TYPE_ACTIVITY);
}
if (mXdyPublisher == null) {
mXdyPublisher = new XdyPublisher(1, 1, mActivity);
}else{
//todo 如果不为空的话是已经播放过,得清理上次的
// mXdyPlayer.onPause();
}
publish_url=video_url;
isPublisher =true;
isPublisherAudio=false;
mXdyPublisher.publisher(video_url,mSurfaceView_Publish, new EventHande_Publish());
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
setPublishSendSuccessVideo(video_url);
}else{
mMsgManage.getPublishVideoPathError();
}
}else{
//给出提示
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.AUDIO_GET_PUBLISH_PATH:
//推流地址的返回值拿到正确的推流地址直接开始推流
//打开推流视频
String audio_path=response;
GetPublishPathReceiveBean getPublishPathReceiveBean_Audio=JsonUtil.parseJsonToBean(audio_path,GetPublishPathReceiveBean.class);
if(getPublishPathReceiveBean_Audio!=null&&getPublishPathReceiveBean_Audio.getCode()==0){
//可以推流了
String audio_url=getPublishPathReceiveBean_Audio.getPublishUrl();
//TODO 成功存储数据 文档上有mediaId ,实际获取没有,下个版本会加上,现在暂时用getvideopublishpath 做关键字
aCache.put(Constants.GET_AUDIO_PUBLISH_PATH,audio_url);
//判断
// if (mSurfaceView==null){
// //todo 输出提示
// XdyLogUtil.e(TAG,"surfaceView is null");
// return;
// }
if(mActivity==null){
//TODo 给出提示
XdyLogUtil.e(TAG,"activity is null");
return;
}
if(mXdyPublisher ==null) {
mXdyPublisher = new XdyPublisher(1, 0, mActivity);
}else {
//todo 如果不为空的话是已经播放过,得清理上次的
// mXdyPlayer.onPause();
}
mXdyPublisher.publisherAudio(audio_url,new EventHande_Publish());
publish_url=audio_url;
isPublisher =true;
isPublisherAudio=true;
//// TODO: 2017/4/13 大牛连接成功回调没有监听到 暂时在这告知后台,(后续加上网路判断,摄像头判断)
PlayerUtils.setPublishSendSuccessAudio(audio_url);
}else{
//给出提示
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.PUBLISH_AUDIO:
//只推送音频
//接收后台是否接收到推流URl的地址
String publishReplay_Audio=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay_Audio));
PublisherVideoReturnBean publisherVideoReturnBean_audio=JsonUtil.parseJsonToBean(XdyStringUtils.stringToJson(publishReplay_Audio),PublisherVideoReturnBean.class);
if(publisherVideoReturnBean_audio!=null&&publisherVideoReturnBean_audio.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}
break;
case Constants.VIDEO_PUBLISH_RESULT:
//接收发送推流地址给后台返回的信息
String publishReplay=response;
XdyLogUtil.e(TAG,"后台成功接收到,返回值"+XdyStringUtils.stringToJson(publishReplay));
PublisherVideoReturnBean publisherVideoReturnBean=JsonUtil.parseJsonToBean(publishReplay,PublisherVideoReturnBean.class);
if(publisherVideoReturnBean!=null&&publisherVideoReturnBean.getCode()==0){
XdyLogUtil.e(TAG,"后台成功接收到,推流的地址");
//TODO
handleListener(Constants.PUBLISH_RERUEN_SUCCESS,"");
}else{
//TODO
handleListener(Constants.ERROR_CODE,"{\n" +
" \"code\": 804,\n" +
" \"reson\": \"推流失败\"\n" +
"}");
}
break;
case Constants.VIDEO_PLAY:
//获取推流的地址,需要保存起来
//解析数据拿出mediaId 作为主键 将media 释放的给用户可能有多个播放的情况
String video=response;
VideoPlayBean videoPlayBean= JsonUtil.parseJsonToBean(video,VideoPlayBean.class);
if(videoPlayBean!=null) {
// if(videoPlayBean.getMediaId()!=videoPlayBean.getFromNodeId()) {
if(mNodeId !=videoPlayBean.getFromNodeId()) {
//过滤自己推送的video
aCache.put(videoPlayBean.getMediaId() + "", video);
handleListener(type, videoPlayBean.getMediaId() + "");
}
}else{
XdyLogUtil.e(TAG,"video play json error");
}
break;
case Constants.AUDIO_PLAY:
String audio=response;
AudioPlayBean audioPlayBean=JsonUtil.parseJsonToBean(audio,AudioPlayBean.class);
if(audioPlayBean!=null){
// if(audioPlayBean.getMediaId()!=audioPlayBean.getFromNodeId()) {
if(mNodeId !=audioPlayBean.getFromNodeId()) {
aCache.put(audioPlayBean.getMediaId() + "", audio);
handleListener(type, audioPlayBean.getMediaId() + "");
}
}
break;
case Constants.ERROR_CODE:
ErrorCodeEntity errorCodeEntity =JsonUtil.parseJsonToBean(response,ErrorCodeEntity.class);
if(errorCodeEntity!=null){
if(errorCodeEntity.getCode()==Constants.LEAVE_CLASS_CODE){
/**
* 方案 一 1,正在直播的时候mcu无故断开,需要重新连接
* 2,class exit 时候主动课堂停止,停止推流
* 利用mcu的生命周期,加入课堂成功后去请求数据
*/
// 方案 二 mcu 断开,页面也断开,用户需要手动重新调用
if(isPublisher) {
if(!NetWorkUtils.isNetworkConnected(mContext)){
//todo判断是否有网络,没有网络的话就让其退出
// TOdo 延迟5秒,
// onPublisherStop();
handler.sendEmptyMessageDelayed(Constants.LEAVE_CLASS_CODE,Constants.TIME_NET_ERROR_RECONNECTION);
}
isReconnection=true;
}
}
}
handleListener(type,response);
break;
case Constants.CLASS_EXIT:
/**
* 处理正在推流视频,课堂退出的情况,(用户操作退出界面)
* 此时,停止推流,清除surfaceview Activtity 数据,url数据
*/
if(isPublisher){
onPublisherStop();
}
handleListener(type,response);
break;
default:{
handleListener(type,response);
}
}
}
/**
* 处理所有向外发送的接口数据
* @param type
* @param parameter
*/
private void handleListener(String type,String parameter){
XdyLogUtil.e(TAG,"type:"+type+"parameter:"+parameter);
for(ObserverListener o:observerListenerList){
o.observerUpData(type,parameter);
}
}
/**
* 销毁播放音视频
* @param id
* @return
*/
public boolean onPlayStop(String id){
if(currentPlayId.equals(id)) {
if (mXdyPlayer != null) {
mXdyPlayer.onStopPlay();
// mXdyPlayer = null;
isCurrentAudioHost=false;
isCurrentVideoHost=false;
}
return true;
}
return false;
}
/**
* 退出时清除信息(重置js监听)
*/
public void removeAll(){
if(mXdyPlayer !=null) {
mXdyPlayer.onPause();
}
if(mXdyJsCore!=null&&!isRecordPlayBack) {
mXdyJsCore.init(mContext);
}
isCurrentVideoHost=false;
isCurrentAudioHost=false;
onPublisherStop();
}
/**
* 结束时调用
*/
public void onPlayDestroy(){
if (mXdyPlayer != null) {
mXdyPlayer.onStopPlay();
mXdyPlayer = null;
}
}
/**
* 推送视频音频停止方法(最后调用的方法)
* @deprecated daniu sdk handle best
*/
public void onPublisherStop(){
if(mXdyPublisher !=null){
mXdyPublisher.onStopPublisher();
mXdyPublisher =null;
}
//如果正在推流,msurfaceView ,mActivity不清空
if(!isPublisher) {
if (mSurfaceView_Publish != null) {
mSurfaceView_Publish = null;
}
if (mActivity != null) {
mActivity = null;
}
}
isPublisher =false;
isReconnection=false;
isPublisherAudio=false;
}
/**
* onPause 方法时走的周期
* 推送视频暂停调用,单独提出,不与play合并考虑到有后台继续推送的情况
*/
public void onPublisherPause(){
if(mXdyPublisher !=null){
mXdyPublisher.onPausePublisher();
}
}
/**
*
* TODO 只有一个boolean
* 开始isPublish 为false
* 开始推流初始化后onresume 就是开始
* 大牛 sdk处理的更好
*/
public void onPublisherResume(){
if(!isPublisher){
return;
}
if(mXdyPublisher !=null) {
mXdyPublisher.onResumePublisher();
if (!TextUtils.isEmpty(publish_url)) {
if(!isPublisherAudio){
mXdyPublisher.publisher(publish_url, mSurfaceView_Publish, new EventHande_Publish());
}else{
mXdyPublisher.publisherAudio(publish_url,new EventHande_Publish());
}
}
}
}
class EventHande_Play implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
class EventHande_Publish implements SmartEventCallback {
@Override
public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {
switch (code) {
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
Log.e(TAG, "开始。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
Log.e(TAG, "连接中。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
Log.e(TAG, "连接失败。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
Log.e(TAG, "连接成功。。");
//TODO //如果连接成功发送连接成功信息,判断的方式有待考虑
// PlayerUtils.setPublishSendSuccessVideo(aCache.getAsString(Constants.GET_VIDEO_PUBLISH_PATH));
// XdySdk.getXdyInstance().notifyObserver("video_success","");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
Log.e(TAG, "连接断开。。");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
Log.i(TAG, "关闭。。");
// notifyObserver("play_stop",currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
Log.e(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);
//在这里最接近得到播放的成功的准确回调
// notifyObserver(Constants.PLAY_SUCCESS,currentPlayId+"");
break;
case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
Log.e(TAG, "收不到媒体数据,可能是url错误。。");
}
}
}
/**
* 向后台发送推流数据(Auido)成功信息
* @param url
*/
protected static void setPublishSendSuccessAudio(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdySdk.getXdyInstance().api(Constants.PUBLISH_AUDIO, pamp);
}
}
/**
* 向后台发送推流(Video)成功的信息
* @param url
*/
protected static void setPublishSendSuccessVideo(String url) {
PublisherSuccessEntity publisherEntity = new PublisherSuccessEntity();
if (!TextUtils.isEmpty(url)) {
publisherEntity.setPublishUrl(url);
final String pamp = new Gson().toJson(publisherEntity);
XdyLogUtil.e("setPublishSendSuccessVideo:",Thread.currentThread().getId()+"");
XdySdk.getXdyInstance().api(Constants.PUBLISH_VIDEO, pamp);
}
}
}
... ...
package com.mang.xdy.utils;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装的是使用Gson解析json的方法
*
* @author abao
*/
public class JsonUtil {
private static final String TAG = JsonUtil.class.getSimpleName();
/**
* 把一个map变成json字符串
*
* @param map
* @return
*/
public static String parseMapToJson(Map<?, ?> map) {
try {
Gson gson = new Gson();
return gson.toJson(map);
} catch (Exception e) {
}
return null;
}
public static String parseListToJson(List<?> list) {
try {
Gson gson = new Gson();
return gson.toJson(list);
} catch (Exception e) {
}
return null;
}
/**
* 把一个json字符串变成对象
*
* @param json
* @param cls
* @return
*/
public static <T> T parseJsonToBean(String json, Class<T> cls) {
Gson gson = new Gson();
T t = null;
try {
t = gson.fromJson(json, cls);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
return t;
}
/**
* 把json字符串变成map
*
* @param json
* @return
*/
public static HashMap<String, Object> parseJsonToMap(String json) {
Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
HashMap<String, Object> map = null;
try {
map = gson.fromJson(json, type);
} catch (Exception e) {
}
return map;
}
/**
* 把json字符串变成集合
* params: new TypeToken<List<yourbean>>(){}.getType(),
*
* @param json
* @param type new TypeToken<List<yourbean>>(){}.getType()
* @return
*/
public static List<?> parseJsonToList(String json, Type type) {
Gson gson = new Gson();
List<?> list = gson.fromJson(json, type);
return list;
}
/**
* 获取json串中某个字段的值,注意,只能获取同一层级的value
*
* @param json
* @param key
* @return
*/
public static String getFieldValue(String json, String key) {
if (TextUtils.isEmpty(json))
return null;
if (!json.contains(key))
return "";
JSONObject jsonObject = null;
String value = null;
try {
jsonObject = new JSONObject(json);
value = jsonObject.getString(key);
} catch (JSONException e) {
e.printStackTrace();
}
return value;
}
}
package com.mang.xdy.utils;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装的是使用Gson解析json的方法
*
* @author abao
*/
public class JsonUtil {
private static final String TAG = JsonUtil.class.getSimpleName();
/**
* 把一个map变成json字符串
*
* @param map
* @return
*/
public static String parseMapToJson(Map<?, ?> map) {
try {
Gson gson = new Gson();
return gson.toJson(map);
} catch (Exception e) {
}
return null;
}
public static String parseListToJson(List<?> list) {
try {
Gson gson = new Gson();
return gson.toJson(list);
} catch (Exception e) {
}
return null;
}
/**
* 把一个json字符串变成对象
*
* @param json
* @param cls
* @return
*/
public static <T> T parseJsonToBean(String json, Class<T> cls) {
Gson gson = new Gson();
T t = null;
try {
t = gson.fromJson(json, cls);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
e.printStackTrace();
}
return t;
}
/**
* 把json字符串变成map
*
* @param json
* @return
*/
public static HashMap<String, Object> parseJsonToMap(String json) {
Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
HashMap<String, Object> map = null;
try {
map = gson.fromJson(json, type);
} catch (Exception e) {
}
return map;
}
/**
* 把json字符串变成集合
* params: new TypeToken<List<yourbean>>(){}.getType(),
*
* @param json
* @param type new TypeToken<List<yourbean>>(){}.getType()
* @return
*/
public static List<?> parseJsonToList(String json, Type type) {
Gson gson = new Gson();
List<?> list = gson.fromJson(json, type);
return list;
}
/**
* 获取json串中某个字段的值,注意,只能获取同一层级的value
*
* @param json
* @param key
* @return
*/
public static String getFieldValue(String json, String key) {
if (TextUtils.isEmpty(json))
return null;
if (!json.contains(key))
return "";
JSONObject jsonObject = null;
String value = null;
try {
jsonObject = new JSONObject(json);
value = jsonObject.getString(key);
} catch (JSONException e) {
e.printStackTrace();
}
return value;
}
}
... ...
package com.mang.xdy.utils;
import android.content.Context;
import android.content.SharedPreferences;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class SPUtil {
private static SharedPreferences mSp;
private static SharedPreferences getSharedPreferences(Context context) {
if (mSp == null) {
mSp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
}
return mSp;
}
public static void putBoolean(Context context, String key, boolean value) {
// SharedPreferences sp = mContext.getSharedPreferences("config",
// Context.MODE_PRIVATE);
getSharedPreferences(context).edit().putBoolean(key, value).commit();
}
public static boolean getBoolean(Context context, String key, boolean defValue) {
// SharedPreferences sp = mContext.getSharedPreferences("config",
// Context.MODE_PRIVATE);
return getSharedPreferences(context).getBoolean(key, defValue);
}
public static void putString(Context context, String key, String value) {
getSharedPreferences(context).edit().putString(key, value).commit();
}
public static String getString(Context context, String key, String defValue) {
return getSharedPreferences(context).getString(key, defValue);
}
public static void putInt(Context context, String key, int value) {
getSharedPreferences(context).edit().putInt(key, value).commit();
}
public static int getInt(Context context, String key, int defValue) {
return getSharedPreferences(context).getInt(key, defValue);
}
/**
* 移除一个字符串值
*
* @param context
* @param key
*/
public static void removeString(Context context, String key) {
getSharedPreferences(context).edit().remove(key).commit();
}
/**
* 把流里的内容解析成字符串
*
* @param is
* @return
* @throws IOException
*/
public static String streamToString(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
String string = baos.toString();
baos.close();
is.close();
return string;
}
public static long getLong(String key,long defValue) {
return mSp.getLong(key, defValue);
}
public static void setLong(Context context, String key, Long value) {
getSharedPreferences(context).edit().putLong(key, value).commit();
}
}
... ...
package com.mang.xdy.utils;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;
/**
* Created by abao on 2017/3/30.
*/
public class XdyStringUtils {
private static String TAG="xdysdk";
public static String stringToJson(String s,boolean isJSjson){
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++){
char c =s.charAt(i);
switch(c){
case'\'': if(isJSjson) {sb.append("\\\'");}else{sb.append("\'");} break;
case'\"': if(!isJSjson) {sb.append("\\\"");}else{sb.append("\"");} break;
case'\\':sb.append("\\\\"); break; //如果不处理单引号,可以释放此段代码,若结合StringDanYinToJSON()处理单引号就必须注释掉该段代码
case'/': sb.append("\\/");break;
case'\b':sb.append("\\b");break;//退格
case'\f':sb.append("\\f");break;//走纸换页
case'\n':sb.append("\\n");break;//换行
case'\r':sb.append("\\r");break;//回车
case'\t':sb.append("\\t");break;//横向跳格
default: sb.append(c);
}}
return sb.toString();
}
public static String stringToJson(String s){
String resString="";
if(!TextUtils.isEmpty(s)&&s.length()>2) {
String temp = s.replace("\\", "");
resString = temp.substring(1, temp.length() - 1);
}
return resString;
}
/*判断url*/
public static void judgeUrl(String url){
if (url == null)
return;
// rtmp://
if (url.length() < 8) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
if (!url.startsWith("rtmp://")) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
}
/**
* 时间
* @param currentTime
* @return
*/
private String generateTime(long currentTime) {
int totalSeconds = (int) (currentTime);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
seconds).toString();
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds)
.toString();
}
}
public static int dp2px(Context context, float dp) {
return (int) Math.ceil(context.getResources().getDisplayMetrics().density * dp);
}
}
package com.mang.xdy.utils;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;
/**
* Created by abao on 2017/3/30.
*/
public class XdyStringUtils {
private static String TAG="xdysdk";
public static String stringToJson(String s,boolean isJSjson){
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++){
char c =s.charAt(i);
switch(c){
case'\'': if(isJSjson) {sb.append("\\\'");}else{sb.append("\'");} break;
case'\"': if(!isJSjson) {sb.append("\\\"");}else{sb.append("\"");} break;
case'\\':sb.append("\\\\"); break; //如果不处理单引号,可以释放此段代码,若结合StringDanYinToJSON()处理单引号就必须注释掉该段代码
case'/': sb.append("\\/");break;
case'\b':sb.append("\\b");break;//退格
case'\f':sb.append("\\f");break;//走纸换页
case'\n':sb.append("\\n");break;//换行
case'\r':sb.append("\\r");break;//回车
case'\t':sb.append("\\t");break;//横向跳格
default: sb.append(c);
}}
return sb.toString();
}
public static String stringToJson(String s){
String resString="";
if(!TextUtils.isEmpty(s)&&s.length()>2) {
String temp = s.replace("\\", "");
resString = temp.substring(1, temp.length() - 1);
}
return resString;
}
/*判断url*/
public static void judgeUrl(String url){
if (url == null)
return;
// rtmp://
if (url.length() < 8) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
if (!url.startsWith("rtmp://")) {
Log.e(TAG, "Input publish url error:" + url);
return;
}
}
/**
* 时间
* @param currentTime
* @return
*/
private String generateTime(long currentTime) {
int totalSeconds = (int) (currentTime);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
seconds).toString();
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds)
.toString();
}
}
public static int dp2px(Context context, float dp) {
return (int) Math.ceil(context.getResources().getDisplayMetrics().density * dp);
}
}
... ...