Commit 96f7daac by mReturn

Merge remote-tracking branch 'remotes/origin/dev'

parents 35dcd8a2 1fb016c3
Showing with 1322 additions and 27 deletions
......@@ -23,7 +23,7 @@ android {
}
}
ndk {
abiFilters 'x86', 'armeabi-v7a','armeabi'
abiFilters 'armeabi-v7a','armeabi'
}
}
......
......@@ -53,15 +53,15 @@
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"
tools:replace="android:label,icon,theme,allowBackup">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.dayu.bigfish.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<!--<provider-->
<!--android:name="android.support.v4.content.FileProvider"-->
<!--android:authorities="com.dayu.bigfish.fileProvider"-->
<!--android:exported="false"-->
<!--android:grantUriPermissions="true">-->
<!--<meta-data-->
<!--android:name="android.support.FILE_PROVIDER_PATHS"-->
<!--android:resource="@xml/file_paths" />-->
<!--</provider>-->
<!-- <provider -->
<!-- android:name="android.support.v4.content.FileProvider" -->
......
......@@ -16,13 +16,13 @@ import com.dayu.bigfish.ui.service.LocationService;
import com.dayu.bigfish.utils.HxManager;
import com.dayu.common.BaseApplication;
import com.dayu.common.Constants;
import com.dayu.livemodule.LiveUtils;
import com.dayu.location.base.LocationUtils;
import com.dayu.order.greendao.GreenDaoManager;
import com.dayu.order.ui.activity.OrderDetailsActivity;
import com.dayu.utils.LogUtils;
import com.dayu.utils.NetworkConnectChangedReceiver;
import com.dayu.utils.SPUtils;
import com.dayu.utils.ToastUtils;
import com.dayu.utils.UserManager;
import com.scwang.smartrefresh.header.MaterialHeader;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
......@@ -91,6 +91,9 @@ public class MyApplication extends BaseApplication {
//初始化环信
HxManager.getInstance().init(mContext);
//直播
LiveUtils.initLive(this);
}
//初始化刷新框架 static 代码段可以防止内存泄露
......
......@@ -14,15 +14,11 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.dayu.event.LearnTabNumEvent;
import com.dayu.event.SaleTabNumEvent;
import com.bigfish.salecenter.ui.fragment.HomeSaleFragment;
import com.dayu.base.api.Api;
import com.dayu.base.api.DownloadService;
......@@ -42,8 +38,12 @@ import com.dayu.bigfish.utils.HxManager;
import com.dayu.common.BaseApplication;
import com.dayu.common.Constants;
import com.dayu.event.DownloadBean;
import com.dayu.event.LearnTabNumEvent;
import com.dayu.event.SaleTabNumEvent;
import com.dayu.event.UserInfo;
import com.dayu.learncenter.ui.fragment.HomeLearnFragment;
import com.dayu.livemodule.LiveUtils;
import com.dayu.livemodule.event.UserKickOutEvent;
import com.dayu.location.base.LocationUtils;
import com.dayu.order.common.TabNumEvent;
import com.dayu.order.ui.activity.OrderDetailsActivity;
......@@ -104,6 +104,7 @@ public class MainActivity extends BaseActivity<MainPresenter, ActivityMainBindin
@Override
public void initView() {
LiveUtils.initEnv(Constants.ENVIROMENT);
if (getIntent().hasExtra(Constants.ORDER_ID)) {
Bundle bundle = new Bundle();
bundle.putInt(Constants.ORDER_ID, Integer.parseInt(getIntent().getStringExtra(Constants.ORDER_ID)));
......@@ -113,6 +114,7 @@ public class MainActivity extends BaseActivity<MainPresenter, ActivityMainBindin
MobclickAgent.onEvent(BaseApplication.getContext(), "push_offline_check_order_detail");
}
initUser();
LiveUtils.initUser(mUserId,mUserInfo.getAccountName(),mUserInfo.getHeaderImg());
MobclickAgent.onEvent(this, "go_home");
saleFragment = HomeSaleFragment.newInstance();
secondFragment = HomeOrderFragment.newInstance();
......@@ -470,6 +472,11 @@ public class MainActivity extends BaseActivity<MainPresenter, ActivityMainBindin
}
}
@Subscribe
public void kickOutUser(UserKickOutEvent event) {
showLoginDialog();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
......
......@@ -49,6 +49,17 @@ public interface APIService {
@POST(Constants.UP_PHOTO)
Observable<BaseResponse<List<String>>> uploadPhoto(
@Part MultipartBody.Part part);
/**
* 上传图片单张.
*
* @param part
* @param style nowatermark 无水印
* @return
*/
@Multipart
@POST(Constants.UP_PHOTO)
Observable<BaseResponse<List<String>>> uploadPhoto(
@Part MultipartBody.Part part, @Query("style") String style);
/**
* 上传单个视频.
......
......@@ -23,6 +23,9 @@ public class BaseApiFactory {
public static Observable<List<String>> uploadPhoto(MultipartBody.Part part) {
return Api.getService(APIService.class).uploadPhoto(part).compose(Api.applySchedulers());
}
public static Observable<List<String>> uploadPhoto(MultipartBody.Part part, String style) {
return Api.getService(APIService.class).uploadPhoto(part,style).compose(Api.applySchedulers());
}
public static Observable<String> uploadVideo(MultipartBody.Part part) {
return Api.getService(APIService.class).uploadVideo(part).compose(Api.applySchedulers());
......
......@@ -32,6 +32,8 @@ public class Constants {
public static final String PROGRAM_PATH = "pages/mallDetail/main?goodsId=gid&userId=uid&type=1"; //小程序路径
public static final String INVITE_NEW_SHARE_URL = "http://app.dl.kf.ai/ext/#/shareMaster?code="; //邀请新人分享链接
public static final String INVITE_NEW_SHARE_URL_BUSINESS = "http://app.dl.kf.ai/ext/#/merchants?code="; //邀请商家分享链接
public static String VIDEO_SHARE_URL = "http://app.dl.kf.ai/ext/#/shareVideo?type=_type&id="; //学习视频分享链接 type(课程: course 直播: live)
// public static String VIDEO_SHARE_URL = "http://uat.kf.ai:9099/#/shareVideo?type=_type&id="; //uat 学习视频分享链接 type(课程: course 直播: live)
/**
......@@ -67,6 +69,7 @@ public class Constants {
// public static final boolean IS_DEBUG = true;
// public static final boolean CAN_CHANGE_ENV = false; //是否显示切换开发环境菜单
/**
* 正式环境.
*/
......
......@@ -37,6 +37,16 @@ public class UserInfo {
private List<Integer> roles;
private String mobile;
private int liveStatus; //1.开启主播权限
public int getLiveStatus() {
return liveStatus;
}
public void setLiveStatus(int liveStatus) {
this.liveStatus = liveStatus;
}
//不为空时弹出邀请码弹框
private String newAccount;
......
......@@ -5,10 +5,8 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.telephony.TelephonyManager;
import com.alibaba.android.arouter.launcher.ARouter;
import com.dayu.baselibrary.R;
import com.dayu.common.BaseApplication;
import com.dayu.common.BaseConstant;
import com.dayu.common.Constants;
import com.hyphenate.chat.EMClient;
......
......@@ -5,14 +5,11 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.dayu.baselibrary.R;
import com.dayu.common.BaseApplication;
......@@ -24,6 +21,7 @@ import com.umeng.socialize.UMShareListener;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.media.UMImage;
import com.umeng.socialize.media.UMMin;
import com.umeng.socialize.media.UMVideo;
import com.umeng.socialize.media.UMWeb;
import java.text.ParseException;
......@@ -285,11 +283,10 @@ public class CommonUtils {
UMWeb web = new UMWeb(url);
web.setTitle(title);
if (TextUtils.isEmpty(imgUrl)) {
web.setThumb(new UMImage(activity, R.drawable.icon_app_logo));
web.setThumb(new UMImage(activity, Constants.AppLogoUrl));
} else {
web.setThumb(new UMImage(activity, imgUrl));
}
web.setThumb(new UMImage(activity, imgUrl));
web.setDescription(description);
new ShareAction(activity).withMedia(web)
.setDisplayList(SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE)
......@@ -297,6 +294,20 @@ public class CommonUtils {
// .setPlatform(SHARE_MEDIA.WEIXIN_CIRCLE)
// .setCallback(callBack).share();
}
/**
* 微信(朋友圈)分享链接(包含标题内容)
*/
public static void shareWxVideo(Activity activity, String videoUrl, String imgUrl, String title,
String description, UMShareListener callBack) {
UMVideo video = new UMVideo(videoUrl);
video.setTitle(title);//视频的标题
video.setDescription(description);//视频的描述
new ShareAction(activity).withMedia(video)
.setDisplayList(SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE)
.setCallback(callBack).open();
// .setPlatform(SHARE_MEDIA.WEIXIN_CIRCLE)
// .setCallback(callBack).share();
}
......
......@@ -19,7 +19,6 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
......@@ -50,8 +49,8 @@ public class GlideImageLoader {
public static void load(Context context,ImageView view, String imageRes, int defaultRes) {
RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(defaultRes)
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(context)
.load(imageRes)
......@@ -69,6 +68,15 @@ public class GlideImageLoader {
.apply(options)
.into(view);
}
public static void loadNoDeal(Context context, ImageView view, String imageRes, int defaultRes) {
RequestOptions options = new RequestOptions()
.placeholder(defaultRes)
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(context)
.load(imageRes)
.apply(options)
.into(view);
}
public static void loadDrawable(Context context, String imageRes, ImageView view) {
RequestOptions options = new RequestOptions()
.centerCrop()
......
......@@ -19,6 +19,13 @@ public class MediaChooseUtils {
public static void chooseSigleImg(Activity activity) {
chooseMedia(activity,PictureMimeType.ofImage(),1,0);
}
public static void chooseLiveImg(Activity activity) {
PictureSelectionModel selector = getPictureSelectionModel(activity, PictureMimeType.ofImage(), 1, 0);
selector.enableCrop(true)//是否裁剪
.withAspectRatio(3, 2)
.freeStyleCropEnabled(true);
selector.forResult(PictureConfig.CHOOSE_REQUEST);
}
/**
* 选择头像图片并裁剪
......
......@@ -2,7 +2,6 @@ package com.dayu.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import com.dayu.baselibrary.R;
import com.dayu.utils.ToastUtils;
......@@ -13,6 +12,7 @@ public class MyJzvdStd extends JzvdStd {
public int curProgress;
public long curPosition;
private PlayCallBack callBack;
private startPlayCallBack startPlayCallBack;
public MyJzvdStd(Context context) {
super(context);
......@@ -34,6 +34,8 @@ public class MyJzvdStd extends JzvdStd {
curPosition = 0;
if (callBack != null)
callBack.onstart();
if (startPlayCallBack != null)
startPlayCallBack.onstart();
}
//onState 代表了播放器引擎的回调,播放视频各个过程的状态的回调
......@@ -111,6 +113,9 @@ public class MyJzvdStd extends JzvdStd {
public void setPlayCallBack(PlayCallBack callBack) {
this.callBack = callBack;
}
public void setStartCallBack(startPlayCallBack callBack) {
this.startPlayCallBack = callBack;
}
public interface PlayCallBack {
void onstart();
......@@ -121,4 +126,7 @@ public class MyJzvdStd extends JzvdStd {
void onComplete();
}
public interface startPlayCallBack {
void onstart();
}
}
......@@ -72,11 +72,16 @@ public class TextDialog {
}
public void showCenterDialog(final Activity activity, List<String> strs,onItemClickListener listener) {
showCenterDialog(activity,R.layout.dialog_text,R.layout.item_dialog_text,strs,listener);
}
public void showCenterDialog(final Activity activity, int viewId,int itemId,List<String> strs,onItemClickListener listener) {
View mView = View.inflate(activity, R.layout.dialog_text , null);
View mView = View.inflate(activity, viewId , null);
RecyclerView recyclerView = mView.findViewById(R.id.rv_text);
BaseQuickAdapter<String,BaseViewHolder> mAdapter = new BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_dialog_text,strs) {
BaseQuickAdapter<String,BaseViewHolder> mAdapter = new BaseQuickAdapter<String, BaseViewHolder>(itemId,strs) {
@Override
protected void convert(BaseViewHolder helper, String item) {
helper.setText(R.id.tv_text,item);
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="15dp"/>
<solid android:color="@color/cl_tab_gray"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="15dp"/>
<solid android:color="@color/dark_red"/>
</shape>
\ No newline at end of file
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='请选择视频片段'
android:layout_margin="15dp"
android:textColor="@color/common_text_color"
android:textSize="16sp" />
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#999"
/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_text"
android:layout_margin="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text='aaa'
android:textColor="@color/text_common_blue"
android:textSize="@dimen/sp_14" />
\ No newline at end of file
......@@ -995,6 +995,7 @@ C) 在甲方使用大鱼平台服务过程中产生的业务数据,客户数
<string name="find_course">查找课程</string>
<array name="learn_top_tab_item">
<item>公开课</item>
<item>直播</item>
<item>已学习</item>
<item>已发布</item>
</array>
......
apply plugin: 'com.android.library'
android {
compileSdkVersion compile_sdk_version
buildToolsVersion build_tools_version
defaultConfig {
minSdkVersion min_sdk_version
targetSdkVersion target_sdk_version
versionCode version_code
versionName verson_name
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "com.android.support:appcompat-v7:27.1.1"
implementation "com.android.support:recyclerview-v7:27.1.1"
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tencent.liteav.demo.beauty">
</manifest>
\ No newline at end of file
package com.tencent.liteav.demo.beauty;
public class BeautyData {
public int icon;
public String text;
public BeautyData(int icon, String text) {
this.icon = icon;
this.text = text;
}
}
package com.tencent.liteav.demo.beauty;
import android.graphics.Bitmap;
/**
* 美颜参数
*/
public class BeautyParams {
// 美颜类型
public int mBeautyStyle = 0;
// 美颜
public int mBeautyLevel = 4;
// 美白
public int mWhiteLevel = 1;
// 红润
public int mRuddyLevel = 0;
// 滤镜LUT图
public Bitmap mFilterBmp;
// 滑动滤镜索引
public int mFilterIndex;
// 滤镜程度
public int mFilterStrength = 0;
// 大眼
public int mBigEyeLevel;
// 瘦脸
public int mFaceSlimLevel;
// 瘦鼻
public int mNoseSlimLevel;
// 缩下巴
public int mChinSlimLevel;
// V脸
public int mFaceVLevel;
// 短脸
public int mFaceShortLevel;
// 亮眼
public int mEyeLightenLevel = 0;
// 白牙
public int mToothWhitenLevel = 0;
// 祛皱
public int mWrinkleRemoveLevel = 0;
// 祛眼袋
public int mPounchRemoveLevel = 0;
// 祛法令纹
public int mSmileLinesRemoveLevel = 0;
// 发际线
public int mForeheadLevel = 0;
// 眼距
public int mEyeDistanceLevel = 0;
// 眼角
public int mEyeAngleLevel = 0;
// 嘴型
public int mMouthShapeLevel = 0;
// 鼻翼
public int mNoseWingLevel = 0;
// 鼻子位置
public int mNosePositionLevel = 0;
// 嘴唇厚度
public int mLipsThicknessLevel = 0;
// 脸型
public int mFaceBeautyLevel = 0;
// 长腿
public int mLongLegLevel = 0;
// 瘦腰
public int mThinWaistLevel = 0;
// 瘦体
public int mThinBodyLevel = 0;
// 瘦肩
public int mThinShoulderLevel = 0;
// 动效文件路径
public String mMotionTmplPath;
// 绿幕
public String mGreenFile;
}
package com.tencent.liteav.demo.beauty;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CustomProgressDialog {
private Dialog mDialog;
private TextView tvMsg;
public void createLoadingDialog(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.layout_loading_progress, null);
LinearLayout layout = (LinearLayout) v.findViewById(R.id.layout_progress);
ImageView spaceshipImage = (ImageView) v.findViewById(R.id.progress_img);
tvMsg = (TextView) v.findViewById(R.id.msg_tv);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(context, R.anim.load_progress_animation);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
mDialog = new Dialog(context, R.style.loading_dialog);
mDialog.setCancelable(false);
mDialog.setContentView(layout, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT));// 设置布局
}
public void setCancelable(boolean cancelable) {
if (mDialog != null) {
mDialog.setCancelable(cancelable);
}
}
public void setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
if (mDialog != null) {
mDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
}
}
public void show() {
if (mDialog != null) {
mDialog.show();
}
}
public void dismiss() {
if (mDialog != null) {
mDialog.dismiss();
}
}
public void setMsg(String msg) {
if (tvMsg == null) {
return;
}
if (tvMsg.getVisibility() == View.GONE) {
tvMsg.setVisibility(View.VISIBLE);
}
tvMsg.setText(msg);
}
}
package com.tencent.liteav.demo.beauty;
public interface Downloadlistener {
void onDownloadFail(String errorMsg);
void onDownloadProgress(final int progress);
void onDownloadSuccess(String filePath);
}
package com.tencent.liteav.demo.beauty;
import java.io.File;
public interface HttpFileListener {
void onProgressUpdate(int progress);
void onSaveSuccess(File file);
void onSaveFailed(File file, Exception e);
void onProcessEnd();
}
package com.tencent.liteav.demo.beauty;
import android.content.Context;
import android.text.TextUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpFileUtil implements Runnable {
public static final int BUFFERED_READER_SIZE = 8192;
public static final int TIMEOUT = 30000;
private Context mContext;
private String mUrl;
private String mFolder;
private String mFilename;
private HttpFileListener mListener;
private long mContentLength;
private long mDownloadingSize;
private boolean mNeedProgress;
public HttpFileUtil(Context context, String url, String folder, String filename, HttpFileListener listener, boolean needProgress) {
mContext = context;
mUrl = url;
mFolder = folder;
mFilename = filename;
mListener = listener;
mNeedProgress = needProgress;
}
@Override
public void run() {
if (!VideoDeviceUtil.isNetworkAvailable(mContext) ||
TextUtils.isEmpty(mUrl) || TextUtils.isEmpty(mFolder) || TextUtils.isEmpty(mFilename) || !mUrl.startsWith("http")) {
fail(null);
return;
}
File dstFolder = new File(mFolder);
if (!dstFolder.exists()) {
dstFolder.mkdirs();
} else {
if (dstFolder.isFile()) {
if (mListener != null) {
mListener.onSaveFailed(dstFolder, null);
return;
}
}
}
File dstFile = new File(mFolder + File.separator + mFilename);
HttpURLConnection client = null;
InputStream responseIs = null;
FileOutputStream fos = null;
int statusCode = -1;
boolean success = false;
Exception failException = null;
try {
if (dstFile.exists()) {
dstFile.delete();
}
dstFile.createNewFile();
client = (HttpURLConnection) new URL(mUrl).openConnection();
// 设置网络超时参数
client.setConnectTimeout(TIMEOUT);
client.setReadTimeout(TIMEOUT);
client.setDoInput(true);
client.setRequestMethod("GET");
statusCode = client.getResponseCode();
success = client.getResponseCode() == HttpURLConnection.HTTP_OK;
if (success) {
if (mNeedProgress) {
mContentLength = client.getContentLength();
}
responseIs = client.getInputStream();
int length = -1;
byte[] buffer = new byte[BUFFERED_READER_SIZE];
fos = new FileOutputStream(dstFile);
mDownloadingSize = 0;
mListener.onProgressUpdate(0);
while ((length = responseIs.read(buffer)) != -1) {
fos.write(buffer, 0, length);
if (mNeedProgress) {
int pre = (int) (mDownloadingSize * 100 / mContentLength);
mDownloadingSize += length;
int now = (int) (mDownloadingSize * 100 / mContentLength);
if (pre != now && mListener != null) {
mListener.onProgressUpdate(now);
}
}
}
fos.flush();
if (mListener != null) {
mListener.onProgressUpdate(100);
mListener.onSaveSuccess(dstFile);
}
} else {
failException = new HttpStatusException("http status got exception. code = " + statusCode);
}
} catch (Exception e) {
failException = e;
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
if (responseIs != null) {
responseIs.close();
}
if (client != null) {
client.disconnect();
}
mListener.onProcessEnd();
} catch (IOException e) {
e.printStackTrace();
}
}
if (!success || null != failException) {
mListener.onSaveFailed(dstFile, failException);
}
}
private void fail(Exception e) {
if (mListener != null) {
mListener.onSaveFailed(null, e);
}
mListener = null;
}
}
package com.tencent.liteav.demo.beauty;
/**
* Http状态异常[自定义抛出的异常]
*/
public class HttpStatusException extends Exception {
public HttpStatusException(String detailMessage) {
super(detailMessage);
}
}
package com.tencent.liteav.demo.beauty;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
public interface IBeautyKit {
/**
* 设置指定素材滤镜特效
*
* @param filterImage : 指定素材,即颜色查找表图片。注意:一定要用png格式!!!
* demo用到的滤镜查找表图片位于RTMPAndroidDemo/app/src/main/res/drawable-xxhdpi/目录下。
*/
void setFilter(Bitmap filterImage, int index);
/**
* 设置滤镜效果程度
*
* @param strength : 从0到1,越大滤镜效果越明显,默认取值0.5
*/
void setFilterStrength(float strength);
/**
* 设置绿幕文件(企业版有效,其它版本设置此参数无效)[API >= 18]
* <p>
* 此处的绿幕功能并非智能抠背,它需要被拍摄者的背后有一块绿色的幕布来辅助产生特效。
*
* @param path 视频文件路径。支持 MP4;null 表示关闭特效。
*/
@TargetApi(18)
void setGreenScreenFile(String path);
/**
* 设置美颜类型
*
* @param beautyStyle 美颜风格.三种美颜风格:0 :光滑 1:自然 2:朦胧
*/
void setBeautyStyle(int beautyStyle);
/**
* 设置美颜级别
*
* @param beautyLevel 美颜级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setBeautyLevel(int beautyLevel);
/**
* 设置美白级别
*
* @param whitenessLevel 美白级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setWhitenessLevel(int whitenessLevel);
/**
* 设置红润级别
*
* @param ruddyLevel 红润级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setRuddyLevel(int ruddyLevel);
/**
* 设置大眼级别(企业版有效,其它版本设置此参数无效)
*
* @param eyeScaleLevel 大眼级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setEyeScaleLevel(int eyeScaleLevel);
/**
* 设置瘦脸级别(企业版有效,其它版本设置此参数无效)
*
* @param faceSlimLevel 瘦脸级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setFaceSlimLevel(int faceSlimLevel);
/**
* 设置V脸级别(企业版有效,其它版本设置此参数无效)
*
* @param faceVLevel V脸级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setFaceVLevel(int faceVLevel);
/**
* 设置下巴拉伸或收缩(企业版有效,其它版本设置此参数无效)
*
* @param chinLevel 下巴拉伸或收缩级别,取值范围 -9 - 9;0 表示关闭,小于0表示收缩,大于0表示拉伸。
*/
void setChinLevel(int chinLevel);
/**
* 设置短脸级别(企业版有效,其它版本设置此参数无效)
*
* @param faceShortLevel 短脸级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setFaceShortLevel(int faceShortLevel);
/**
* 设置瘦鼻级别(企业版有效,其它版本设置此参数无效)
*
* @param noseSlimLevel 瘦鼻级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setNoseSlimLevel(int noseSlimLevel);
/**
* 设置亮眼 (企业版有效,其它版本设置此参数无效)
*
* @param eyeLightenLevel 亮眼级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setEyeLightenLevel(int eyeLightenLevel);
/**
* 设置白牙 (企业版有效,其它版本设置此参数无效)
*
* @param toothWhitenLevel 白牙级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setToothWhitenLevel(int toothWhitenLevel);
/**
* 设置祛皱 (企业版有效,其它版本设置此参数无效)
*
* @param wrinkleRemoveLevel 祛皱级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setWrinkleRemoveLevel(int wrinkleRemoveLevel);
/**
* 设置祛眼袋 (企业版有效,其它版本设置此参数无效)
*
* @param pounchRemoveLevel 祛眼袋级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setPounchRemoveLevel(int pounchRemoveLevel);
/**
* 设置祛法令纹 (企业版有效,其它版本设置此参数无效)
*
* @param smileLinesRemoveLevel 祛法令纹级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setSmileLinesRemoveLevel(int smileLinesRemoveLevel);
/**
* 设置发际线 (企业版有效,其它版本设置此参数无效)
*
* @param foreheadLevel 发际线级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setForeheadLevel(int foreheadLevel);
/**
* 设置眼距 (企业版有效,其它版本设置此参数无效)
*
* @param eyeDistanceLevel 眼距级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setEyeDistanceLevel(int eyeDistanceLevel);
/**
* 设置眼角 (企业版有效,其它版本设置此参数无效)
*
* @param eyeAngleLevel 眼角级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setEyeAngleLevel(int eyeAngleLevel);
/**
* 设置嘴型 (企业版有效,其它版本设置此参数无效)
*
* @param mouthShapeLevel 嘴型级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setMouthShapeLevel(int mouthShapeLevel);
/**
* 设置鼻翼 (企业版有效,其它版本设置此参数无效)
*
* @param noseWingLevel 鼻翼级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setNoseWingLevel(int noseWingLevel);
/**
* 设置鼻子位置 (企业版有效,其它版本设置此参数无效)
*
* @param nosePositionLevel 鼻子位置级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setNosePositionLevel(int nosePositionLevel);
/**
* 设置嘴唇厚度 (企业版有效,其它版本设置此参数无效)
*
* @param lipsThicknessLevel 嘴唇厚度级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setLipsThicknessLevel(int lipsThicknessLevel);
/**
* 设置脸型 (企业版有效,其它版本设置此参数无效)
*
* @param faceBeautyLevel 脸型级别,取值范围0 - 9; 0表示关闭,1 - 9值越大,效果越明显。
*/
void setFaceBeautyLevel(int faceBeautyLevel);
/**
* 选择使用哪一款 AI 动效挂件(企业版有效,其它版本设置此参数无效)
*/
void setMotionTmpl(String tmplPath);
/**
* 设置动效静音(企业版有效,其它版本设置此参数无效)
* <p>
* 有些挂件本身会有声音特效,通过此 API 可以关闭这些特效播放时所带的声音效果。
*
* @param motionMute YES:静音;NO:不静音。
*/
void setMotionMute(boolean motionMute);
}
package com.tencent.liteav.demo.beauty;
import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class IconTextAdapter extends BaseAdapter {
private static final String TAG = "IconTextAdapter";
private final Context mContext;
private int mTextColorPrimary;
private ArrayList<BeautyData> data = new ArrayList<BeautyData>();
private BeautyPanel.OnItemClickListener mItemClickListener;
// 当前选中
private int mSelectPos;
public IconTextAdapter(Context context) {
mContext = context;
}
public void addAll(ArrayList<BeautyData> beautyDataList) {
data.clear();
data.addAll(beautyDataList);
notifyDataSetChanged();
}
public void clearAllData() {
data.clear();
notifyDataSetChanged();
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_beauty, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final BeautyData beautyData = data.get(position);
holder.icon.setImageResource(beautyData.icon);
holder.title.setText(beautyData.text);
if (mSelectPos == position) {
holder.title.setTextColor(mTextColorPrimary);
} else {
holder.title.setTextColor(Color.WHITE);
}
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(beautyData, position);
}
if (mSelectPos != position) {
mSelectPos = position;
notifyDataSetChanged();
}
}
});
return convertView;
}
public void setOnItemClickListener(BeautyPanel.OnItemClickListener itemClickListener) {
mItemClickListener = itemClickListener;
}
public void setTextColor(int colorPrimary) {
mTextColorPrimary = colorPrimary;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView icon;
private TextView title;
public ViewHolder(View itemView) {
super(itemView);
icon = (ImageView) itemView.findViewById(R.id.icon);
title = (TextView) itemView.findViewById(R.id.title);
}
}
}
package com.tencent.liteav.demo.beauty;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 美颜模块素材下载
*/
public class MaterialDownloader {
private Context mContext;
public static final String DOWNLOAD_FILE_POSTFIX = ".zip";
public static final String ONLINE_MATERIAL_FOLDER = "cameraVideoAnimal";
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private boolean mProcessing;
private String mUrl;
private Downloadlistener mListener;
private DownloadThreadPool mDownloadThreadPool;
private String mMaterialId;
public MaterialDownloader(Context context, String materialId, String url) {
mContext = context;
mMaterialId = materialId;
mUrl = url;
mProcessing = false;
}
public void start(@Nullable Downloadlistener listener) {
if (listener == null || TextUtils.isEmpty(mUrl) || mProcessing) {
return;
}
mProcessing = true;
mListener = listener;
mListener.onDownloadProgress(0);
HttpFileListener fileListener = new HttpFileListener() {
@Override
public void onSaveSuccess(@NonNull File file) {
//删除该素材目录下的旧文件
File path = new File(file.toString().substring(0, file.toString().indexOf(DOWNLOAD_FILE_POSTFIX)));
if (path.exists() && path.isDirectory()) {
File[] oldFiles = path.listFiles();
if (oldFiles != null) {
for (File f : oldFiles) {
f.delete();
}
}
}
String dataDir = VideoUtil.unZip(file.getPath(), file.getParentFile().getPath());
if (TextUtils.isEmpty(dataDir)) {
mListener.onDownloadFail(mContext.getString(R.string.video_material_download_progress_material_unzip_failed));
stop();
return;
}
file.delete();
mListener.onDownloadSuccess(dataDir);
stop();
}
@Override
public void onSaveFailed(File file, Exception e) {
mListener.onDownloadFail(mContext.getString(R.string.video_material_download_progress_download_failed));
stop();
}
@Override
public void onProgressUpdate(int progress) {
mListener.onDownloadProgress(progress);
}
@Override
public void onProcessEnd() {
mProcessing = false;
}
};
File onlineMaterialDir = VideoDeviceUtil.getExternalFilesDir(mContext, ONLINE_MATERIAL_FOLDER);
if (onlineMaterialDir == null || onlineMaterialDir.getName().startsWith("null")) {
mListener.onDownloadFail(mContext.getString(R.string.video_material_download_progress_no_enough_storage_space));
stop();
return;
}
if (!onlineMaterialDir.exists()) {
onlineMaterialDir.mkdirs();
}
ThreadPoolExecutor threadPool = getThreadExecutor();
threadPool.execute(new HttpFileUtil(mContext, mUrl, onlineMaterialDir.getPath(), mMaterialId + DOWNLOAD_FILE_POSTFIX, fileListener, true));
}
public void stop() {
mListener = null;
}
public synchronized ThreadPoolExecutor getThreadExecutor() {
if (mDownloadThreadPool == null || mDownloadThreadPool.isShutdown()) {
mDownloadThreadPool = new DownloadThreadPool(CORE_POOL_SIZE);
}
return mDownloadThreadPool;
}
public static class DownloadThreadPool extends ThreadPoolExecutor {
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public DownloadThreadPool(int poolSize) {
super(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>(),
Executors.defaultThreadFactory(), new DiscardOldestPolicy());
}
}
}
package com.tencent.liteav.demo.beauty;
public class MotionData {
public String mMotionId;
public String mMotionName;
public String mMotionUrl;
public String mMotionPath;
public MotionData(String motionId, String motionName, String motionUrl, String motionPath) {
mMotionId = motionId;
mMotionName = motionName;
mMotionUrl = motionUrl;
mMotionPath = motionPath;
}
}
package com.tencent.liteav.demo.beauty;
import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
public class TCHorizontalScrollView extends android.widget.HorizontalScrollView {
private DataSetObserver mObserver;
private Adapter mAdapter;
public TCHorizontalScrollView(Context context) {
super(context);
initialize();
}
public TCHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public TCHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize();
}
public void setAdapter(Adapter adapter) {
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mObserver);
}
mAdapter = adapter;
mAdapter.registerDataSetObserver(mObserver);
updateAdapter();
}
private void updateAdapter() {
ViewGroup group = (ViewGroup) getChildAt(0);
group.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
View view = mAdapter.getView(i, null, group);
group.addView(view);
}
}
void initialize() {
mObserver = new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
updateAdapter();
}
@Override
public void onInvalidated() {
super.onInvalidated();
((ViewGroup) getChildAt(0)).removeAllViews();
}
};
}
public void setClicked(int position) {
((ViewGroup) getChildAt(0)).getChildAt(position).performClick();
}
}
\ No newline at end of file
package com.tencent.liteav.demo.beauty;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
/**
* 属性管理
*/
public class UIAttributeUtil {
/**
* 获取主题设置的图片资源的drawable
*
* @param context context
* @param attrId style-attr对应的id
* @param defaultResourceId 默认的图片id
* @return Drawable
*/
public static Drawable getDrawableResources(Context context, int attrId, int defaultResourceId) {
TypedArray a = context.obtainStyledAttributes(new int[]{attrId});
int resourceId = a.getResourceId(0, defaultResourceId);
Drawable drawable = context.getResources().getDrawable(resourceId);
a.recycle();
return drawable;
}
public static int getColorRes(Context context, int attrId, int defaultColorId) {
TypedArray a = context.obtainStyledAttributes(new int[]{attrId});
int color = a.getColor(0, context.getResources().getColor(defaultColorId));
a.recycle();
return color;
}
public static int getTextSizeResources(Context context, int attrId, int defaultTextSize) {
TypedArray a = context.obtainStyledAttributes(new int[]{attrId});
int textSize = a.getDimensionPixelOffset(0, defaultTextSize);
a.recycle();
return textSize;
}
public static int getResResources(Context context, int attrId, int defaultResourceId) {
TypedArray a = context.obtainStyledAttributes(new int[]{attrId});
int resourceId = a.getResourceId(0, defaultResourceId);
a.recycle();
return resourceId;
}
public static int[] getResResourcsArray(Context context, int[] attrId, int[] defaultResourceId) {
int[] resourceIdArray = new int[attrId.length];
TypedArray a = context.obtainStyledAttributes(attrId);
for (int i = 0; i < attrId.length; i++) {
resourceIdArray[i] = a.getResourceId(i, defaultResourceId[i]);
}
a.recycle();
return resourceIdArray;
}
}
package com.tencent.liteav.demo.beauty;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.File;
public class VideoDeviceUtil {
private static final String TAG = "VideoDeviceUtil";
public VideoDeviceUtil() {
}
public static boolean isNetworkAvailable(@NonNull Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
return false;
} else {
NetworkInfo networkInfo = connectivity.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnectedOrConnecting();
}
}
@Nullable
public static File getExternalFilesDir(@NonNull Context context, String folder) {
if (context == null) {
Log.e(TAG, "getExternalFilesDir context is null");
return null;
}
File sdcardDir = context.getApplicationContext().getExternalFilesDir(null);
if (sdcardDir == null) {
Log.e(TAG, "sdcardDir is null");
return null;
}
String path = sdcardDir.getPath();
File file = new File(path + File.separator + folder);
try {
if (file.exists() && file.isFile()) {
file.delete();
}
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception var5) {
var5.printStackTrace();
}
return file;
}
}
package com.tencent.liteav.demo.beauty;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class VideoUtil {
private static final String TAG = "VideoUtil";
public VideoUtil() {
}
public static boolean isEmpty(@Nullable Collection object) {
return null == object || object.isEmpty();
}
public static synchronized String unZip(@NonNull String zipFile, @NonNull String targetDir) {
if (TextUtils.isEmpty(zipFile)) {
return null;
} else {
File file = new File(zipFile);
if (!file.exists()) {
return null;
} else {
File targetFolder = new File(targetDir);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
String dataDir = null;
short BUFFER = 4096;
FileInputStream fis = null;
ZipInputStream zis = null;
FileOutputStream fos = null;
BufferedOutputStream dest = null;
try {
fis = new FileInputStream(file);
zis = new ZipInputStream(new BufferedInputStream(fis));
while (true) {
while (true) {
String strEntry;
ZipEntry entry;
do {
if ((entry = zis.getNextEntry()) == null) {
return dataDir;
}
strEntry = entry.getName();
} while (strEntry.contains("../"));
if (entry.isDirectory()) {
String count1 = targetDir + File.separator + strEntry;
File data1 = new File(count1);
if (!data1.exists()) {
data1.mkdirs();
}
if (TextUtils.isEmpty(dataDir)) {
dataDir = data1.getPath();
}
} else {
byte[] data = new byte[BUFFER];
String targetFileDir = targetDir + File.separator + strEntry;
File targetFile = new File(targetFileDir);
try {
fos = new FileOutputStream(targetFile);
dest = new BufferedOutputStream(fos, BUFFER);
int count;
while ((count = zis.read(data)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
} catch (IOException var41) {
var41.printStackTrace();
} finally {
try {
if (dest != null) {
dest.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException var40) {
var40.printStackTrace();
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (zis != null) {
zis.close();
}
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return dataDir;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="1500"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="restart"
android:startOffset="-1"
android:toDegrees="+360" />
</set>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment