This commit is contained in:
2025-11-18 15:12:24 +08:00
parent c173c425ce
commit a7d2035e70
1361 changed files with 367452 additions and 0 deletions
@@ -0,0 +1,315 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import androidx.annotation.NonNull;
import com.easefun.polyvsdk.PolyvDownloaderErrorReason;
import com.easefun.polyvsdk.video.PolyvPlayErrorReason;
/**
* 错误类型转成错误信息工具类
* @author Lion 2017-8-3
*/
public class PolyvErrorMessageUtils {
/**
* 获取下载错误信息
* @param type 下载错误类型
* @return 错误信息字符串
*/
@NonNull
public static String getDownloaderErrorMessage(PolyvDownloaderErrorReason.ErrorType type) {
switch (type) {
case VID_IS_NULL:
return "视频id不正确,请设置正确的视频id进行下载";
case NOT_PERMISSION:
return "非法下载,请向管理员反馈";
case RUNTIME_EXCEPTION:
return "当前视频无法下载,请向管理员反馈";
case VIDEO_STATUS_ERROR:
return "视频状态异常,无法下载";
case M3U8_NOT_DATA:
return "视频数据加载失败,请重新下载";
case QUESTION_NOT_DATA:
return "视频问答数据加载失败,请重新下载";
case MULTIMEDIA_LIST_EMPTY:
return "当前视频无法下载,请向管理员反馈";
case CAN_NOT_MKDIR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case DOWNLOAD_TS_ERROR:
return "视频文件下载失败,请重新下载";
case MULTIMEDIA_EMPTY:
return "当前视频无法下载,请向管理员反馈";
case NOT_CREATE_DIR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case VIDEO_LOAD_FAILURE:
return "当前视频无法下载,请向管理员反馈";
case VIDEO_NULL:
return "视频信息加载失败,请重新下载";
case DIR_SPACE_LACK:
return "检测到移动设备存储空间不足,请清除存储空间再重新下载";
case DOWNLOAD_DIR_IS_NUll:
return "检测到存储目录未设置,请先设置存储目录再重新下载";
case HLS_15X_URL_ERROR:
return "当前视频无法下载,请向管理员反馈";
case HLS_SPEED_TYPE_IS_NULL:
return "视频速度类型错误,请设置了速度类型后重新下载";
case HLS_15X_ERROR:
return "当前视频无法下载,请向管理员反馈";
case GET_VIDEO_INFO_ERROR:
return "视频信息加载失败,请重新下载";
case WRITE_EXTERNAL_STORAGE_DENIED:
return "检测到拒绝写入存储设备,请先为应用程序分配权限,再重新下载";
case VID_ERROR:
return "视频id不正确,请设置正确的视频id进行下载";
case EXTRA_DIR_IS_NUll:
return "检测到资源目录未设置,请先设置存储目录再重新下载";
case NOT_CREATE_EXTRA_DIR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case CREATE_NOMEDIA_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case URL_IS_EMPTY:
return "当前视频无法下载,请向管理员反馈";
case CREATE_M3U8_FILE_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case WRITE_M3U8_FILE_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case CREATE_VIDEO_JSON_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case WRITE_VIDEO_JSON_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case QUESTION_FORMAT_JSON_ERROR:
return "当前视频无法下载,请重新下载或者切换网络重新下载或者向管理员反馈";
case DELETE_ZIP_FILE_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case CREATE_VIDEO_TMP_FILE_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case DOWNLOAD_VIDEO_FILE_LENGTH_ERROR:
return "当前视频无法下载,请重新下载或者切换网络重新下载或者向管理员反馈";
case VIDEO_HTTP_CODE_ERROR:
return "当前视频无法下载,请重新下载或者切换网络重新下载或者向管理员反馈";
case VIDEO_DOWNLOAD_ERROR:
return "当前视频下载出错,请点击停止/继续下载或删除重新下载";// 当前视频无法下载,请删除后重新下载或者切换网络重新下载或者向管理员反馈
case VIDEO_RENAME_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case UNZIP_FILE_ERROR:
return "当前视频解压失败,请尝试删除视频再次下载或者切换网络再次下载或者向管理员反馈";
case CREATE_ZIP_TMP_FILE_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case CREATE_UNZIP_DIR_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case DOWNLOAD_ZIP_FILE_LENGTH_ERROR:
return "当前视频无法下载,请重新下载或者切换网络重新下载或者向管理员反馈";
case ZIP_HTTP_CODE_ERROR:
return "当前视频无法下载,请重新下载或者切换网络重新下载或者向管理员反馈";
case ZIP_DOWNLOAD_ERROR:
return "当前视频下载出错,请删除后重新下载或者切换网络重新下载或者向管理员反馈";
case ZIP_RENAME_ERROR:
return "当前视频无法下载,请重启手机再次下载或者向管理员反馈";
case NETWORK_DENIED:
return "无法连接网络,请连接网络后下载";
case MEDIA_UNKNOWN:
return "SD卡不可用,请重启手机或者更换SD卡或者向管理员反馈";
case MEDIA_REMOVED:
return "SD卡被移除,请重启手机或者向管理员反馈";
case MEDIA_UNMOUNTED:
return "SD卡存在但未安装,请重新安装SD卡或者向管理员反馈";
case MEDIA_CHECKING:
return "SD卡正在进行磁盘检查中,请稍后下载或者重启手机或者向管理员反馈";
case MEDIA_NOFS:
return "SD卡空白或正在使用不受支持的文件系统,请重启手机或者更换SD卡或者向管理员反馈";
case MEDIA_MOUNTED_READ_ONLY:
return "SD卡不能写入,请重启手机或者向管理员反馈";
case MEDIA_SHARED:
return "SD卡不可用,请重启手机或者更换SD卡或者向管理员反馈";
case MEDIA_BAD_REMOVAL:
return "SD卡不可用,请重启手机或者更换SD卡或者向管理员反馈";
case MEDIA_UNMOUNTABLE:
return "SD卡不可用,请重启手机或者更换SD卡或者向管理员反馈";
case MEDIA_EJECTING:
return "SD卡不可用,请重启手机或者更换SD卡或者向管理员反馈";
case VIDEO_BITRATE_NOT_EXIST:
return "当前视频下载出错,请尝试切换码率进行下载或者向管理员反馈";
default:
return "当前视频无法下载,请向管理员反馈";
}
}
/**
* 获取播放错误信息
* @param playErrorReason 播放错误类型
* @return 错误信息字符串
*/
public static String getPlayErrorMessage(@PolyvPlayErrorReason.PlayErrorReason int playErrorReason) {
switch (playErrorReason) {
case PolyvPlayErrorReason.VIDEO_ERROR:
return "当前视频无法播放,请尝试切换网络重新播放或者向管理员反馈";
case PolyvPlayErrorReason.NETWORK_DENIED:
return "无法连接网络,请连接网络后播放";
case PolyvPlayErrorReason.OUT_FLOW:
return "流量超标,请向管理员反馈";
case PolyvPlayErrorReason.TIMEOUT_FLOW:
return "账号过期,请向管理员反馈";
case PolyvPlayErrorReason.LOCAL_AUDIO_ERROR:
return "本地视频文件损坏,请重新下载";
case PolyvPlayErrorReason.START_ERROR:
return "播放异常,请重新播放";
case PolyvPlayErrorReason.NOT_PERMISSION:
return "非法播放,请向管理员反馈";
case PolyvPlayErrorReason.USER_TOKEN_ERROR:
return "请先设置播放凭证,再进行播放";
case PolyvPlayErrorReason.VIDEO_STATUS_ERROR:
return "视频状态异常,无法播放,请向管理员反馈";
case PolyvPlayErrorReason.VID_ERROR:
return "视频id不正确,请设置正确的视频id进行播放";
case PolyvPlayErrorReason.BITRATE_ERROR:
return "清晰度不正确,请设置正确的清晰度进行播放";
case PolyvPlayErrorReason.VIDEO_NULL:
return "视频信息加载失败,请尝试切换网络重新播放";
case PolyvPlayErrorReason.MP4_LINK_NUM_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.M3U8_LINK_NUM_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.HLS_SPEED_TYPE_NULL:
return "播放速度不正确,请设置正确的播放速度进行播放";
case PolyvPlayErrorReason.NOT_LOCAL_VIDEO:
return "找不到缓存的视频文件,请连网后重新下载";
case PolyvPlayErrorReason.HLS_15X_INDEX_EMPTY:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.HLS_15X_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.HLS_15X_URL_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.M3U8_15X_LINK_NUM_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.CHANGE_EQUAL_HLS_SPEED:
return "切换播放速度相同,请选择其它播放速度";
case PolyvPlayErrorReason.CAN_NOT_CHANGE_BITRATE:
return "未开始播放视频不能切换清晰度,请先播放视频";
case PolyvPlayErrorReason.CAN_NOT_CHANGE_HLS_SPEED:
return "未开始播放视频不能切换播放速度,请先播放视频";
case PolyvPlayErrorReason.QUESTION_ERROR:
return "视频问答数据加载失败,请重新播放或者切换网络重新播放";
case PolyvPlayErrorReason.CHANGE_BITRATE_NOT_EXIST:
return "视频没有这个清晰度,请切换其它清晰度";
case PolyvPlayErrorReason.HLS_URL_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.LOADING_VIDEO_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.HLS2_URL_ERROR:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.TOKEN_NULL:
return "播放授权获取失败,请重新播放或者切换网络重新播放或者向管理员反馈";
case PolyvPlayErrorReason.WRITE_EXTERNAL_STORAGE_DENIED:
return "检测到拒绝读取存储设备,请先为应用程序分配权限,再重新播放";
case PolyvPlayErrorReason.SOURCE_URL_EMPTY:
return "当前视频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.AUDIO_URL_EMPTY:
return "当前音频无法播放,请向管理员反馈";
case PolyvPlayErrorReason.NOT_LOCAL_AUDIO:
return "找不到缓存的音频文件,请连网后重新下载";
case PolyvPlayErrorReason.CAN_NOT_CHANGE_AUDIO:
return "未开始播放不能切换到音频,请先开始播放";
case PolyvPlayErrorReason.CAN_NOT_CHANGE_VIDEO:
return "未开始播放不能切换到视频,请先开始播放";
case PolyvPlayErrorReason.LOCAL_VIDEO_ERROR:
return "本地音频文件损坏,请重新下载";
case PolyvPlayErrorReason.LOAD_TIMEOUT:
return "加载超时,请重新播放";
default:
return "当前视频无法播放,请向管理员反馈";
}
}
}
@@ -0,0 +1,150 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
/**
* 图片二次加载框架
*/
public class PolyvImageLoader {
// <editor-fold defaultstate="collapsed" desc="单例">
private static PolyvImageLoader INSTANCE;
private PolyvImageLoader() {/**/}
public static PolyvImageLoader getInstance() {
if (INSTANCE == null) {
synchronized (PolyvImageLoader.class) {
if (INSTANCE == null) {
INSTANCE = new PolyvImageLoader();
}
}
}
return INSTANCE;
}
// </editor-fold>
/**
* 加载图片
*/
public void loadImage(Context context, String url, ImageView imageView) {
Glide.with(context)
.load(url)
.into(imageView);
}
/**
* 加载图片
*/
public void loadImage(Context context, @DrawableRes Integer resourceId, ImageView imageView) {
Glide.with(context)
.load(resourceId)
.into(imageView);
}
/**
* 预加载
* @param context
* @param url
*/
public void preloadImage(Context context, String url){
RequestOptions imgOptions = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(Target.SIZE_ORIGINAL);
Glide.with(context).load(url).apply(imgOptions).preload();
}
/**
* 原始尺寸加载图片
* @param context
* @param url
* @param imageView
*/
public void loadImageOrigin(Context context, String url, ImageView imageView, @DrawableRes int placeHolderId) {
RequestOptions options = new RequestOptions().override(Target.SIZE_ORIGINAL)
.placeholder(placeHolderId)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE);
loadImageWithOptions(context, url, imageView, options);
}
/**
* 原始尺寸加载图片
* @param context
* @param url
* @param imageView
*/
public void loadImageOrigin(Context context, String url, ImageView imageView, Drawable drawable) {
RequestOptions options = new RequestOptions().override(Target.SIZE_ORIGINAL)
.placeholder(drawable)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE);
loadImageWithOptions(context, url, imageView, options);
}
public void loadImageOriginCircle(Context context, String url, ImageView imageView, @DrawableRes int placeHolderId){
RequestOptions options = new RequestOptions()
.placeholder(placeHolderId)
.bitmapTransform(new CircleCrop())
.override(Target.SIZE_ORIGINAL).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.RESOURCE);
loadImageWithOptions(context, url, imageView, options);
}
/**
* 加载图片,开启自动缓存策略
* @param context
* @param url
* @param imageView
*/
public void loadImageWithCache(Context context, String url, ImageView imageView, @DrawableRes int placeHolderId) {
RequestOptions options = new RequestOptions().dontAnimate()
.placeholder(placeHolderId)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC);
loadImageWithOptions(context, url, imageView, options);
}
/**
* 加载图片,关闭缓存策略
* @param context
* @param url
* @param imageView
*/
public void loadImageNoCache(Context context, String url, ImageView imageView, @DrawableRes int placeHolderId) {
RequestOptions options = new RequestOptions().dontAnimate()
.placeholder(placeHolderId)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE);
loadImageWithOptions(context, url, imageView, options);
}
/**
* 加载图片,自定义配置
* @param context
* @param url
* @param imageView
* @param options 自定义配置
*/
public void loadImageWithOptions(Context context, String url, ImageView imageView, RequestOptions options){
Glide.with(context)
.load(url)
.apply(options)
.into(imageView);
}
}
@@ -0,0 +1,32 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import android.content.Context;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
/**
* 软键盘工具类
*/
public class PolyvKeyBoardUtils
{
public static void openKeybord(EditText mEditText, Context mContext)
{
InputMethodManager imm = (InputMethodManager) mContext
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY);
}
public static void closeKeybord(EditText mEditText, Context mContext)
{
InputMethodManager imm = (InputMethodManager) mContext
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
}
@@ -0,0 +1,230 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
public class PolyvNetworkUtils {
private PolyvNetworkUtils() {
}
public static final int NETWORK_WIFI = 1; // wifi network
public static final int NETWORK_4G = 4; // "4G" networks
public static final int NETWORK_3G = 3; // "3G" networks
public static final int NETWORK_2G = 2; // "2G" networks
public static final int NETWORK_UNKNOWN = 5; // unknown network
public static final int NETWORK_NO = -1; // no network
private static final int NETWORK_TYPE_GSM = 16;
private static final int NETWORK_TYPE_TD_SCDMA = 17;
private static final int NETWORK_TYPE_IWLAN = 18;
/**
* 打开网络设置界面
* <p>3.0以下打开设置界面</p>
*
* @param context 上下文
*/
public static void openWirelessSettings(Context context) {
if (android.os.Build.VERSION.SDK_INT > 10) {
context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
} else {
context.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
}
}
/**
* 获取活动网路信息
*
* @param context 上下文
* @return NetworkInfo
*/
private static NetworkInfo getActiveNetworkInfo(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
/**
* 判断网络是否可用
* <p>需添加权限 android.permission.ACCESS_NETWORK_STATE</p>
*/
public static boolean isAvailable(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isAvailable();
}
/**
* 判断网络是否连接
* <p>需添加权限 android.permission.ACCESS_NETWORK_STATE</p>
*
* @param context 上下文
* @return true: 是<br>false: 否
*/
public static boolean isConnected(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isConnected();
}
/**
* 判断网络是否是4G
* <p>需添加权限 android.permission.ACCESS_NETWORK_STATE</p>
*
* @param context 上下文
* @return true: 是<br>false: 不是
*/
public static boolean is4G(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isAvailable() && info.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE;
}
/**
* 判断wifi是否连接状态
* <p>需添加权限 android.permission.ACCESS_NETWORK_STATE</p>
*
* @param context 上下文
* @return true: 连接<br>false: 未连接
*/
public static boolean isWifiConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm != null && cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
}
/**
* 获取移动网络运营商名称
* <p>如中国联通、中国移动、中国电信</p>
*
* @param context 上下文
* @return 移动网络运营商名称
*/
public static String getNetworkOperatorName(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getNetworkOperatorName() : null;
}
/**
* 获取移动终端类型
*
* @param context 上下文
* @return 手机制式
* <ul>
* <li>PHONE_TYPE_NONE : 0 手机制式未知</li>
* <li>PHONE_TYPE_GSM : 1 手机制式为GSM,移动和联通</li>
* <li>PHONE_TYPE_CDMA : 2 手机制式为CDMA,电信</li>
* <li>PHONE_TYPE_SIP : 3</li>
* </ul>
*/
public static int getPhoneType(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getPhoneType() : -1;
}
/**
* 获取当前的网络类型(WIFI,2G,3G,4G)
* <p>需添加权限 android.permission.ACCESS_NETWORK_STATE</p>
*
* @param context 上下文
* @return 网络类型
* <ul>
* <li>NETWORK_WIFI = 1;</li>
* <li>NETWORK_4G = 4;</li>
* <li>NETWORK_3G = 3;</li>
* <li>NETWORK_2G = 2;</li>
* <li>NETWORK_UNKNOWN = 5;</li>
* <li>NETWORK_NO = -1;</li>
* </ul>
*/
public static int getNetWorkType(Context context) {
int netType = NETWORK_NO;
NetworkInfo info = getActiveNetworkInfo(context);
if (info != null && info.isAvailable()) {
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
netType = NETWORK_WIFI;
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
switch (info.getSubtype()) {
case NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
netType = NETWORK_2G;
break;
case NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
netType = NETWORK_3G;
break;
case NETWORK_TYPE_IWLAN:
case TelephonyManager.NETWORK_TYPE_LTE:
netType = NETWORK_4G;
break;
default:
String subtypeName = info.getSubtypeName();
if (subtypeName.equalsIgnoreCase("TD-SCDMA")
|| subtypeName.equalsIgnoreCase("WCDMA")
|| subtypeName.equalsIgnoreCase("CDMA2000")) {
netType = NETWORK_3G;
} else {
netType = NETWORK_UNKNOWN;
}
break;
}
} else {
netType = NETWORK_UNKNOWN;
}
}
return netType;
}
/**
* 获取当前的网络类型(WIFI,2G,3G,4G)
* <p>依赖上面的方法</p>
*
* @param context 上下文
* @return 网络类型名称
* <ul>
* <li>NETWORK_WIFI </li>
* <li>NETWORK_4G </li>
* <li>NETWORK_3G </li>
* <li>NETWORK_2G </li>
* <li>NETWORK_UNKNOWN</li>
* <li>NETWORK_NO </li>
* </ul>
*/
public static String getNetWorkTypeName(Context context) {
switch (getNetWorkType(context)) {
case NETWORK_WIFI:
return "NETWORK_WIFI";
case NETWORK_4G:
return "NETWORK_4G";
case NETWORK_3G:
return "NETWORK_3G";
case NETWORK_2G:
return "NETWORK_2G";
case NETWORK_NO:
return "NETWORK_NO";
default:
return "NETWORK_UNKNOWN";
}
}
}
@@ -0,0 +1,138 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import java.util.List;
/**
* 与屏幕相关的工具类
*/
public class PolyvScreenUtils {
private static int height16_9;
// 生成竖屏下w:h=16:9的高
public static int generateHeight16_9(Activity activity) {
return height16_9 != 0 ? height16_9 : (height16_9 = getNormalWH(activity)[isPortrait(activity) ? 0 : 1] * 9 / 16);
}
// 获取竖屏下w:h=16:9的高
public static int getHeight16_9() {
return height16_9;
}
// 是否竖屏
public static boolean isPortrait(Context context) {
return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
}
// 是否横屏
public static boolean isLandscape(Context context) {
return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
// 设置竖屏
public static void setPortrait(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
// 设置横屏
public static void setLandscape(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
/**
* 获取包含状态栏的屏幕宽度和高度
*
* @param activity
* @return {宽,高}
*/
public static int[] getNormalWH(Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return new int[] { dm.widthPixels, dm.heightPixels };
} else {
Point point = new Point();
WindowManager wm = activity.getWindowManager();
wm.getDefaultDisplay().getSize(point);
return new int[] { point.x, point.y };
}
}
// 重置状态栏
public static void reSetStatusBar(Activity activity) {
if (isLandscape(activity)) {
hideStatusBar(activity);
} else {
setDecorVisible(activity);
}
}
// 隐藏状态栏
public static void hideStatusBar(Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = activity.getWindow().getDecorView();
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
}
}
// 恢复为不全屏状态
public static void setDecorVisible(Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = activity.getWindow().getDecorView();
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
int uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
decorView.setSystemUiVisibility(uiOptions);
}
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
public static int px2dip(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue / scale + 0.5f);
}
//由于画中画的activity为singleInstance模式,如果需要在画中画的activity退出时退出singleInstance模式,那么可以调用该方法
public static void removePIPSingleInstanceTask(Context context, String pipActivityName, boolean isInPictureInPictureMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
if (activityManager == null)
return;
List<ActivityManager.AppTask> tasks = activityManager.getAppTasks();
if (tasks == null)
return;
for (ActivityManager.AppTask task : tasks) {
ActivityManager.RecentTaskInfo info = task.getTaskInfo();
if (info != null && info.baseIntent != null && info.baseIntent.getComponent() != null) {
if (pipActivityName.equals(info.baseIntent.getComponent().getClassName())) {
if (isInPictureInPictureMode || info.numActivities == 0) {
task.finishAndRemoveTask();
}
}
}
}
}
}
}
@@ -0,0 +1,57 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import android.app.Activity;
import android.view.OrientationEventListener;
import java.lang.ref.WeakReference;
public class PolyvSensorHelper {
private OrientationEventListener eventListener;
private boolean switchFlag;
private boolean isLandscape;
public PolyvSensorHelper(final Activity activity) {
final WeakReference<Activity> wr_activity = new WeakReference<Activity>(activity);
eventListener = new OrientationEventListener(activity.getApplicationContext()) {
@Override
public void onOrientationChanged(int orientation) {
Activity activity1 = wr_activity.get();
if (activity1 != null) {
boolean isPortrait = PolyvScreenUtils.isPortrait(activity1);
if ((orientation > -1 && orientation <= 10) || orientation >= 350 || (orientation <= 190 && orientation >= 170)) {
if (!isPortrait && switchFlag && !isLandscape)
PolyvScreenUtils.setPortrait(activity1);
if (isPortrait && !isLandscape)
isLandscape = !isLandscape;
} else if ((orientation <= 100 && orientation >= 80) || (orientation <= 280 && orientation >= 260)) {
if (isPortrait && switchFlag && isLandscape)
PolyvScreenUtils.setLandscape(activity1);
if (!isPortrait && isLandscape)
isLandscape = !isLandscape;
}
}
}
};
}
// 开启监听
public void enable() {
eventListener.enable();
}
// 关闭监听
public void disable() {
eventListener.disable();
}
/**
* 屏幕方向切换之后,是否开启随手势自动切换屏幕方向
*
* @param switchFlag 是否开启自动切换
* @param isLandscape 屏幕切换之后的方向(非自动切换,屏幕方向需要和手动切换之后的方向一致之后,自动切换才会再次生效)
*/
public void toggle(boolean switchFlag, boolean isLandscape) {
this.switchFlag = switchFlag;
this.isLandscape = isLandscape;
}
}
@@ -0,0 +1,57 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
/**
* 存储工具类
* @author Lionel 2018-6-12
*/
public class PolyvStorageUtils {
private final static String MOUNTED = "mounted";
/**
* 获取可使用的外部存储目录<br/>
* 列表中的第一个条目被视为外部主存储,当Android API 大于等于19时,列表中包含了可移除的存储介质(例如 SD 卡)的路径。
* 当用户卸载您的应用时,此目录列表中的目录及其内容将被删除。
* 详细请看:https://developer.android.com/guide/topics/data/data-storage?hl=zh-cn#filesExternal
* @param context
* @return 外部存储目录列表
*/
@NonNull
public static ArrayList<File> getExternalFilesDirs(@NonNull Context context) {
File[] files;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//列表中包含了可移除的存储介质(例如 SD 卡)的路径。
files = context.getExternalFilesDirs(null);
} else {
files = ContextCompat.getExternalFilesDirs(context, null);
}
ArrayList<File> storageList = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//判断存储设备可用性
for (File file : files) {
if (file != null) {
String state = Environment.getExternalStorageState(file);
if (MOUNTED.equals(state)) {
storageList.add(file);
}
}
}
} else {
storageList.addAll(Arrays.asList(files));
}
return storageList;
}
}
@@ -0,0 +1,108 @@
package cn.shangyu.gdxzExpert.polyvplayer.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* 常用时间工具类
*/
public class PolyvTimeUtils {
private static SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
private static SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
/**
* 解析日期
*/
private static Date parseDateTime(String datetime) {
Date mDate = null;
try {
mDate = formatDateTime.parse(datetime);
} catch (ParseException e) {
e.printStackTrace();
}
return mDate;
}
/**
* 以友好的方式显示时间
*/
public static String friendlyTime(String sdate) {
Date time = parseDateTime(sdate);
if (time == null) {
return "Unknown";
}
String ftime = "";
Calendar cal = Calendar.getInstance();
// 判断是否是同一天
String curDate = formatDate.format(cal.getTime());
String paramDate = formatDate.format(time);
if (curDate.equals(paramDate)) {
int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
if (hour == 0) {
ftime = Math.max(
(cal.getTimeInMillis() - time.getTime()) / 60000, 1)
+ "分钟前";
} else {
ftime = hour + "小时前";
}
return ftime;
}
long lt = time.getTime() / 86400000;
long ct = cal.getTimeInMillis() / 86400000;
int days = (int) (ct - lt);
if (days == 0) {
int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
if (hour == 0) {
ftime = Math.max(
(cal.getTimeInMillis() - time.getTime()) / 60000, 1)
+ "分钟前";
} else {
ftime = hour + "小时前";
}
} else if (days == 1) {
ftime = "昨天";
} else if (days == 2) {
ftime = "前天";
} else if (days > 2 && days <= 5) {
ftime = days + "天前";
} else if (days > 5) {
ftime = formatDate.format(time);
}
return ftime;
}
/**
* 以友好的方式显示视频时间
*/
public static String generateTime(long millisecond) {
return generateTime(millisecond, false);
}
/**
* 以友好的方式显示视频时间
*
* @param millisecond 毫秒
* @param fit 小时是否适配"00"
* @return
*/
public static String generateTime(long millisecond, boolean fit) {
int totalSeconds = (int) (millisecond / 1000);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
if (fit || hours > 0)
return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
else
return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
}
}