1.2.0 增加bugly

This commit is contained in:
2026-03-30 10:32:54 +08:00
parent 73892596b1
commit b53e07195f
24 changed files with 493 additions and 257 deletions

View File

@@ -20,6 +20,8 @@ android {
targetSdkVersion 29
versionCode 20
versionName "1.1.9"
// versionCode 21
// versionName "1.2.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -188,6 +190,8 @@ dependencies {
annotationProcessor 'com.arialyy.aria:compiler:3.8.15'
//MMKV
implementation 'com.tencent:mmkv-static:1.2.13'
implementation 'com.tencent.bugly:crashreport:4.1.9.2'
implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.0.0'
//工具类
implementation 'com.blankj:utilcodex:1.31.0'
//沉浸状态栏

View File

@@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".base.BaseApplication"

View File

@@ -25,7 +25,7 @@ import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class CategoryListViewModel extends BaseViewModel<ActivityCategoryListBinding, ActivityEvent> {
private static final String TAG = "CategoryViewModel";
private static final String TAG = "CategoryListViewModel";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
@@ -130,6 +130,7 @@ public class CategoryListViewModel extends BaseViewModel<ActivityCategoryListBin
List<CategoryUpdateInfo> categoryUpdateInfos = listBaseResponse.data;
mCategoryUpdateInfoListData.setValue(categoryUpdateInfos);
}
mMMKV.encode(CommonConfig.CHECK_CATEGORY_UPDATE_NUMBER_TIME, currentTime);
}
@Override

View File

@@ -13,7 +13,6 @@ import com.hainaos.vc.config.CommonConfig;
import com.hainaos.vc.databinding.ActivityCategoryLocalBinding;
import com.hainaos.vc.network.NetInterfaceManager;
import com.hainaos.vc.utils.FileUtils;
import com.hainaos.vc.utils.TimeUtils;
import com.hainaos.vc.utils.VideoUtils;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
@@ -174,37 +173,37 @@ public class LocalCategoryViewModel extends BaseViewModel<ActivityCategoryLocalB
public MutableLiveData<VideoUpdate> mVideoUpdateMutableLiveData = new MutableLiveData<>();
public void getVideoUpdate(String uuid) {
String currentTime = TimeUtils.transferMillisecondToDate(System.currentTimeMillis());
String time = mMMKV.decodeString(uuid, currentTime);
Log.e(TAG, "getVideoUpdate: " + time);
NetInterfaceManager.getInstance().getVideoUpdateObservable(time)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse<VideoUpdate>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getVideoUpdate", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<VideoUpdate> baseResponse) {
Log.e("getVideoUpdate", "onNext: " + baseResponse);
mMMKV.encode(uuid, currentTime);
if (baseResponse.code == 200) {
VideoUpdate videoUpdate = baseResponse.data;
mVideoUpdateMutableLiveData.setValue(videoUpdate);
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("getVideoUpdate", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("getVideoUpdate", "onComplete: ");
}
});
}
// public void getVideoUpdate(String uuid) {
// String currentTime = TimeUtils.transferMillisecondToDate(System.currentTimeMillis());
// String time = mMMKV.decodeString(uuid, currentTime);
// Log.e(TAG, "getVideoUpdate: " + time);
// NetInterfaceManager.getInstance().getVideoUpdateObservable(time)
// .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
// .subscribe(new Observer<BaseResponse<VideoUpdate>>() {
// @Override
// public void onSubscribe(@NonNull Disposable d) {
// Log.e("getVideoUpdate", "onSubscribe: ");
// }
//
// @Override
// public void onNext(@NonNull BaseResponse<VideoUpdate> baseResponse) {
// Log.e("getVideoUpdate", "onNext: " + baseResponse);
// mMMKV.encode(uuid, currentTime);
// if (baseResponse.code == 200) {
// VideoUpdate videoUpdate = baseResponse.data;
// mVideoUpdateMutableLiveData.setValue(videoUpdate);
// }
// }
//
// @Override
// public void onError(@NonNull Throwable e) {
// Log.e("getVideoUpdate", "onError: " + e.getMessage());
// }
//
// @Override
// public void onComplete() {
// Log.e("getVideoUpdate", "onComplete: ");
// }
// });
// }
}

View File

@@ -1,7 +1,6 @@
package com.hainaos.vc.activity.category.online;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
@@ -14,10 +13,9 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.hainaos.vc.R;
import com.hainaos.vc.adapter.CategoryVideoAdapter;
import com.hainaos.vc.base.mvvm.BaseMvvmActivity;
import com.hainaos.vc.bean.BaseResponse;
import com.hainaos.vc.bean.CategoryInfo;
import com.hainaos.vc.bean.CategoryVideoInfo;
import com.hainaos.vc.bean.VideoListData;
import com.hainaos.vc.bean.PasswdInfo;
import com.hainaos.vc.bean.VideoUpdate;
import com.hainaos.vc.config.CommonConfig;
import com.hainaos.vc.databinding.ActivityCategoryVideoBinding;
@@ -30,12 +28,7 @@ import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CategoryVideoActivity extends BaseMvvmActivity<CategoryVideoViewModel, ActivityCategoryVideoBinding> {
private static final String TAG = "CategoryActivity";
@@ -81,7 +74,7 @@ public class CategoryVideoActivity extends BaseMvvmActivity<CategoryVideoViewMod
@Override
public void onRefresh() {
mViewDataBinding.swipeRefreshLayout.setRefreshing(true);
mViewModel.getVideoList(mCategoryInfo.getUuid(), mPasswd);
mViewModel.getVideoList(mCategoryInfo.getFolder(), mCategoryInfo.getUuid(), mPasswd);
}
});
mViewDataBinding.rvVideo.addOnScrollListener(new RecyclerView.OnScrollListener() {
@@ -118,39 +111,10 @@ public class CategoryVideoActivity extends BaseMvvmActivity<CategoryVideoViewMod
// });
// mViewModel.getViedoList(mCategoryInfo.getUuid());
mViewModel.mCategoryVideoInfoListData.observe(this, new Observer<BaseResponse<VideoListData>>() {
mViewModel.mCategoryVideoInfoListData.observe(this, new Observer<List<CategoryVideoInfo>>() {
@Override
public void onChanged(BaseResponse<VideoListData> baseResponse) {
if (baseResponse.code == 200) {
VideoListData videoListData = baseResponse.data;
List<CategoryVideoInfo> categoryVideoInfos = videoListData.getData();
public void onChanged(List<CategoryVideoInfo> categoryVideoInfos) {
File file = new File(FileUtils.getHainaVideoPath(CategoryVideoActivity.this) + mCategoryInfo.getFolder());
if (file.exists()) {
String[] strings = file.list();
Log.e(TAG, "getViedoList: " + Arrays.toString(strings));
if (strings != null) {
List<String> paths = new ArrayList<>(Arrays.asList(strings));
ArrayList<CategoryVideoInfo> localVideoInfos = paths.stream()
.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return FileUtils.isVideoFile(s);
}
})
.map(new Function<String, CategoryVideoInfo>() {
@Override
public CategoryVideoInfo apply(String s) {
CategoryVideoInfo categoryVideoInfo = new CategoryVideoInfo();
categoryVideoInfo.setName(FileUtils.getFileNameWithoutExtension(s));
categoryVideoInfo.setFile_url(new File(file.getAbsolutePath() + File.separator + s).getAbsolutePath());
return categoryVideoInfo;
}
}).collect(Collectors.toCollection(ArrayList::new));
categoryVideoInfos.addAll(localVideoInfos);
}
}
mCategoryVideoAdapter.setData(categoryVideoInfos);
@@ -163,21 +127,25 @@ public class CategoryVideoActivity extends BaseMvvmActivity<CategoryVideoViewMod
mViewDataBinding.rvVideo.setVisibility(View.VISIBLE);
mViewDataBinding.tvTotal.setText(String.format(getString(R.string.video_total), categoryVideoInfos.size()));
}
} else {
Toaster.show(baseResponse.msg);
}
});
mViewModel.mPasswdCorrect.observe(this, new Observer<PasswdInfo>() {
@Override
public void onChanged(PasswdInfo passwdInfo) {
mViewDataBinding.swipeRefreshLayout.setRefreshing(false);
if (!passwdInfo.isCorrect()) {
Toaster.show(passwdInfo.getMsg());
PasswdDialogFragment passwdDialogFragment = new PasswdDialogFragment(mCategoryInfo);
passwdDialogFragment.setConfimCallback(new PasswdDialogFragment.ConfimCallback() {
@Override
public void onConfig(String passwd) {
mPasswd = passwd;
mViewModel.getVideoList(mCategoryInfo.getUuid(), mPasswd);
mViewModel.getVideoList(mCategoryInfo.getFolder(), mCategoryInfo.getUuid(), mPasswd);
}
});
passwdDialogFragment.show(getSupportFragmentManager(), "PasswdDialogFragment");
}
mViewDataBinding.swipeRefreshLayout.setRefreshing(false);
}
});
@@ -192,7 +160,7 @@ public class CategoryVideoActivity extends BaseMvvmActivity<CategoryVideoViewMod
}
});
mViewModel.getVideoList(mCategoryInfo.getUuid(), mPasswd);
mViewModel.getVideoList(mCategoryInfo.getFolder(), mCategoryInfo.getUuid(), mPasswd);
}

View File

@@ -7,13 +7,13 @@ import androidx.lifecycle.MutableLiveData;
import com.hainaos.vc.base.mvvm.BaseViewModel;
import com.hainaos.vc.bean.BaseResponse;
import com.hainaos.vc.bean.CategoryVideoInfo;
import com.hainaos.vc.bean.PasswdInfo;
import com.hainaos.vc.bean.VideoListData;
import com.hainaos.vc.bean.VideoUpdate;
import com.hainaos.vc.config.CommonConfig;
import com.hainaos.vc.databinding.ActivityCategoryVideoBinding;
import com.hainaos.vc.network.NetInterfaceManager;
import com.hainaos.vc.utils.FileUtils;
import com.hainaos.vc.utils.TimeUtils;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
@@ -21,13 +21,21 @@ import com.trello.rxlifecycle4.android.ActivityEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.BiFunction;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class CategoryVideoViewModel extends BaseViewModel<ActivityCategoryVideoBinding, ActivityEvent> {
@@ -74,23 +82,96 @@ public class CategoryVideoViewModel extends BaseViewModel<ActivityCategoryVideoB
}
}
public MutableLiveData<BaseResponse<VideoListData>> mCategoryVideoInfoListData = new MutableLiveData<>();
private Observable<List<CategoryVideoInfo>> getLocalCategoryVideoInfo(String dirName) {
return Observable.fromCallable(new Callable<List<CategoryVideoInfo>>() {
@Override
public List<CategoryVideoInfo> call() throws Exception {
ArrayList<CategoryVideoInfo> localVideoInfos = new ArrayList<>();
File file = new File(FileUtils.getHainaVideoPath(getCtx()) + dirName);
if (file.exists()) {
String[] strings = file.list();
Log.e(TAG, "getViedoList: " + Arrays.toString(strings));
if (strings != null) {
List<String> paths = new ArrayList<>(Arrays.asList(strings));
localVideoInfos = paths.stream()
.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return FileUtils.isVideoFile(s);
}
})
.map(new Function<String, CategoryVideoInfo>() {
@Override
public CategoryVideoInfo apply(String s) {
CategoryVideoInfo categoryVideoInfo = new CategoryVideoInfo();
categoryVideoInfo.setName(FileUtils.getFileNameWithoutExtension(s));
categoryVideoInfo.setFile_url(new File(file.getAbsolutePath() + File.separator + s).getAbsolutePath());
return categoryVideoInfo;
}
}).collect(Collectors.toCollection(ArrayList::new));
}
}
return localVideoInfos;
}
});
}
public void getVideoList(String uuid, String password) {
// getVideoUpdate(uuid);
NetInterfaceManager.getInstance().getVideoListObservable(uuid, password)
public MutableLiveData<List<CategoryVideoInfo>> mCategoryVideoInfoListData = new MutableLiveData<>();
public MutableLiveData<PasswdInfo> mPasswdCorrect = new MutableLiveData<>();
public void getVideoList(String dir, String uuid, String password) {
Observable.zip(getLocalCategoryVideoInfo(dir), NetInterfaceManager.getInstance().getVideoListObservable(uuid, password),
new BiFunction<List<CategoryVideoInfo>, BaseResponse<VideoListData>, List<CategoryVideoInfo>>() {
@Override
public List<CategoryVideoInfo> apply(List<CategoryVideoInfo> localCategoryVideoInfos, BaseResponse<VideoListData> baseResponse) throws Throwable {
List<CategoryVideoInfo> allCategoryVideoInfos = new ArrayList<>();
PasswdInfo passwdInfo = new PasswdInfo();
if (baseResponse.code == 200) {
VideoListData videoListData = baseResponse.data;
passwdInfo.setCorrect(true);
List<CategoryVideoInfo> onlineCategoryVideoInfos = videoListData.getData();
allCategoryVideoInfos.addAll(onlineCategoryVideoInfos);
// 1. 提取线上所有元素的name存入Set去重+O(1)查找,效率最高)
Set<String> onlineNames = new HashSet<>();
for (CategoryVideoInfo onlineInfo : onlineCategoryVideoInfos) {
if (onlineInfo != null && onlineInfo.getName() != null) {
onlineNames.add(onlineInfo.getName());
}
if (onlineInfo != null && onlineInfo.getFile_url() != null) {
onlineNames.add(FileUtils.getFileNameWithoutExtension(onlineInfo.getFile_url()));
}
}
// 2. 遍历本地列表删除name存在于线上Set中的元素
// 注意使用迭代器删除避免普通for循环删除报ConcurrentModificationException
localCategoryVideoInfos.removeIf(info ->
info != null && info.getName() != null && onlineNames.contains(info.getName())
);
allCategoryVideoInfos.addAll(localCategoryVideoInfos);
} else {
passwdInfo.setCorrect(false);
passwdInfo.setMsg(baseResponse.msg);
}
mPasswdCorrect.setValue(passwdInfo);
return allCategoryVideoInfos;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse<VideoListData>>() {
.subscribe(new Observer<List<CategoryVideoInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getVideoList", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<VideoListData> listBaseResponse) {
Log.e("getVideoList", "onNext: ");
mCategoryVideoInfoListData.setValue(listBaseResponse);
public void onNext(@NonNull List<CategoryVideoInfo> categoryVideoInfos) {
Log.e("getVideoList", "onNext: " + categoryVideoInfos.size());
mCategoryVideoInfoListData.setValue(categoryVideoInfos);
}
@Override
@@ -103,41 +184,76 @@ public class CategoryVideoViewModel extends BaseViewModel<ActivityCategoryVideoB
Log.e("getVideoList", "onComplete: ");
}
});
// NetInterfaceManager.getInstance().getVideoListObservable(uuid, password)
// .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
// .subscribe(new Observer<BaseResponse<VideoListData>>() {
// @Override
// public void onSubscribe(@NonNull Disposable d) {
// Log.e("getVideoList", "onSubscribe: ");
// }
//
// @Override
// public void onNext(@NonNull BaseResponse<VideoListData> baseResponse) {
// Log.e("getVideoList", "onNext: ");
// PasswdInfo passwdInfo = new PasswdInfo();
// if (baseResponse.code == 200) {
// VideoListData videoListData = baseResponse.data;
// List<CategoryVideoInfo> categoryVideoInfos = videoListData.getData();
// mCategoryVideoInfoListData.setValue(categoryVideoInfos);
// passwdInfo.setCorrect(true);
// } else {
// passwdInfo.setCorrect(false);
// passwdInfo.setMsg(baseResponse.msg);
// }
// mPasswdCorrect.setValue(passwdInfo);
// }
//
// @Override
// public void onError(@NonNull Throwable e) {
// Log.e("getVideoList", "onError: " + e.getMessage());
// }
//
// @Override
// public void onComplete() {
// Log.e("getVideoList", "onComplete: ");
// }
// });
}
public MutableLiveData<VideoUpdate> mVideoUpdateMutableLiveData = new MutableLiveData<>();
public void getVideoUpdate(String uuid) {
String currentTime = TimeUtils.transferMillisecondToDate(System.currentTimeMillis());
String time = mMMKV.decodeString(uuid, currentTime);
Log.e(TAG, "getVideoUpdate: " + time);
NetInterfaceManager.getInstance().getVideoUpdateObservable(time)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse<VideoUpdate>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getVideoUpdate", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<VideoUpdate> baseResponse) {
Log.e("getVideoUpdate", "onNext: " + baseResponse);
mMMKV.encode(uuid, currentTime);
if (baseResponse.code == 200) {
VideoUpdate videoUpdate = baseResponse.data;
mVideoUpdateMutableLiveData.setValue(videoUpdate);
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("getVideoUpdate", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("getVideoUpdate", "onComplete: ");
}
});
}
// public void getVideoUpdate(String uuid) {
// String currentTime = TimeUtils.transferMillisecondToDate(System.currentTimeMillis());
// String time = mMMKV.decodeString(uuid, currentTime);
// Log.e(TAG, "getVideoUpdate: " + time);
// NetInterfaceManager.getInstance().getVideoUpdateObservable(time)
// .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
// .subscribe(new Observer<BaseResponse<VideoUpdate>>() {
// @Override
// public void onSubscribe(@NonNull Disposable d) {
// Log.e("getVideoUpdate", "onSubscribe: ");
// }
//
// @Override
// public void onNext(@NonNull BaseResponse<VideoUpdate> baseResponse) {
// Log.e("getVideoUpdate", "onNext: " + baseResponse);
// mMMKV.encode(uuid, currentTime);
// if (baseResponse.code == 200) {
// VideoUpdate videoUpdate = baseResponse.data;
// mVideoUpdateMutableLiveData.setValue(videoUpdate);
// }
// }
//
// @Override
// public void onError(@NonNull Throwable e) {
// Log.e("getVideoUpdate", "onError: " + e.getMessage());
// }
//
// @Override
// public void onComplete() {
// Log.e("getVideoUpdate", "onComplete: ");
// }
// });
// }
}

View File

@@ -100,7 +100,7 @@ public class UserActivity extends BaseMvvmActivity<UserViewModel, ActivityUserBi
protected void onResume() {
super.onResume();
mViewDataBinding.tvSn.setText(LenovoCsdkUtil.getInstance().getSerial());
mViewDataBinding.tvStorge.setText("" + Utils.getRemnantSize(this) + "/" + Utils.getDataTotalSize(this));
mViewDataBinding.tvStorge.setText("" + Utils.getRemnantSize(this) + "/" + Utils.getDataTotalSize(this));
}
private ActivityResultLauncher<Intent> mLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {

View File

@@ -127,18 +127,23 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
}
holder.tv_size.setText("视频大小: " + fileSize);
holder.tv_download.setText("删除");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_delete_button));
holder.tv_download.setOnClickListener(new View.OnClickListener() {
holder.tv_download.setVisibility(View.GONE);
holder.tv_delete.setVisibility(View.VISIBLE);
holder.tv_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// if (file.exists()) {
showDeleteLocalDialog(file.getAbsolutePath(), position);
// }
}
});
// holder.tv_download.setText("已下载");
// holder.tv_download.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
//// if (file.exists()) {
// showDeleteLocalDialog(file.getAbsolutePath(), position);
//// }
// }
// });
}
} else {
String cover = categoryVideoInfo.getCover();
@@ -148,36 +153,46 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
holder.tv_size.setText("视频大小: " + fileSize);
String fileName = FileUtils.getFileNamefromURL(url);
String fileExName = FileUtils.getFileType(url);
File file = new File(FileUtils.getHainaVideoPath(mContext) + mDirName + File.separator + fileName);
File downloadFile = new File(FileUtils.getHainaVideoPath(mContext) + mDirName + File.separator + fileName);
File localVideoFile = new File(FileUtils.getHainaVideoPath(mContext) + mDirName + File.separator + name + fileExName);
File file;
if (localVideoFile.exists()) {
file = localVideoFile;
} else {
file = downloadFile;
}
DownloadEntity entity = Aria.download(mContext).getFirstDownloadEntity(url);
if (entity == null) {
if (file.exists()) {
holder.tv_download.setText("删除");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_delete_button));
holder.tv_delete.setVisibility(View.VISIBLE);
holder.tv_download.setText("已下载");
} else {
holder.tv_delete.setVisibility(View.GONE);
holder.tv_download.setText("下载");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_download_button));
}
} else {
int state = entity.getState();
switch (state) {
case 1:
if (file.exists()) {
holder.tv_download.setText("删除");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_delete_button));
holder.tv_delete.setVisibility(View.VISIBLE);
holder.tv_download.setText("已下载");
} else {
holder.tv_delete.setVisibility(View.GONE);
holder.tv_download.setText("下载");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_download_button));
}
break;
case 2:
holder.tv_delete.setVisibility(View.GONE);
holder.tv_download.setText("停止");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_download_button));
break;
case 3:
holder.tv_delete.setVisibility(View.GONE);
holder.tv_download.setText("等待");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_download_button));
break;
@@ -186,10 +201,12 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
case 5:
case 6:
case 7:
holder.tv_delete.setVisibility(View.GONE);
holder.tv_download.setText("下载");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_download_button));
break;
case 4:
holder.tv_delete.setVisibility(View.GONE);
int percent = entity.getPercent();
holder.tv_download.setText(percent + "%");
holder.tv_download.setBackground(mContext.getDrawable(R.drawable.bg_download_button));
@@ -200,7 +217,16 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
GlideLoadUtils.getInstance().glideLoad(mContext, cover, holder.video_image);
holder.tv_duration.setText("视频时长: " + TimeUtils.TimeFormat(categoryVideoInfo.getDuration() * 1000));
holder.tv_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (localVideoFile.exists()) {
showDialog(localVideoFile.getAbsolutePath(), position);
} else if (downloadFile.exists()) {
showDialog(downloadFile.getAbsolutePath(), position);
}
}
});
holder.tv_download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -209,7 +235,7 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
showDialog(file.getAbsolutePath(), position);
} else {
if (XXPermissions.isGranted(mContext, Permissions.STORAGE_PERMISSIONS)) {
FileUtils.ariaDownload(mContext, mDirName, url, md5);
FileUtils.ariaDownload(mContext, mDirName, categoryVideoInfo);
FileUtils.ariaDownload(mContext, mDirName, cover);
// FileUtils.ariaDownloadCover(mContext, mDirName, cover, md5);
} else {
@@ -224,7 +250,7 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
showDialog(file.getAbsolutePath(), position);
} else {
if (XXPermissions.isGranted(mContext, Permissions.STORAGE_PERMISSIONS)) {
FileUtils.ariaDownload(mContext, mDirName, url, md5);
FileUtils.ariaDownload(mContext, mDirName, categoryVideoInfo);
FileUtils.ariaDownload(mContext, mDirName, cover);
// FileUtils.ariaDownloadCover(mContext, mDirName, cover, md5);
} else {
@@ -396,7 +422,7 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
static class VideoHolder extends RecyclerView.ViewHolder {
NiceImageView video_image;
TextView tv_title, tv_duration, tv_download, tv_size;
TextView tv_title, tv_duration, tv_delete, tv_download, tv_size;
ConstraintLayout root;
public VideoHolder(@NonNull View itemView) {
@@ -405,6 +431,7 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter<CategoryVideoAdap
video_image = itemView.findViewById(R.id.video_image);
tv_title = itemView.findViewById(R.id.tv_title);
tv_duration = itemView.findViewById(R.id.tv_duration);
tv_delete = itemView.findViewById(R.id.tv_delete);
tv_download = itemView.findViewById(R.id.tv_download);
tv_size = itemView.findViewById(R.id.tv_size);
}

View File

@@ -14,6 +14,7 @@ import com.hainaos.vc.utils.LenovoCsdkUtil;
import com.hainaos.vc.utils.LoginUtils;
import com.hainaos.vc.utils.ToastUtil;
import com.hjq.toast.Toaster;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.mmkv.MMKV;
public class BaseApplication extends Application {
@@ -31,7 +32,13 @@ public class BaseApplication extends Application {
String rootDir = MMKV.initialize(this);
Log.i(TAG, "mmkv root: " + rootDir);
LenovoCsdkUtil.init(this);
CrashReport.initCrashReport(getApplicationContext(), "3398d86ad9", false);
CrashReport.setDeviceId(this, LenovoCsdkUtil.getInstance().getSerial());
xcrash.XCrash.init(this);
JgyUtils.init(this);
Aria.init(this);
ConnectManager.init(this);

View File

@@ -12,7 +12,7 @@ public class CategoryVideoInfo implements Serializable {
String name;
String cover;
long duration;
long file_size;
int file_size;
String md5;
int status;
int download;
@@ -75,11 +75,11 @@ public class CategoryVideoInfo implements Serializable {
this.duration = duration;
}
public long getFile_size() {
public int getFile_size() {
return file_size;
}
public void setFile_size(long file_size) {
public void setFile_size(int file_size) {
this.file_size = file_size;
}

View File

@@ -0,0 +1,26 @@
package com.hainaos.vc.bean;
import java.io.Serializable;
public class PasswdInfo implements Serializable {
private static final long serialVersionUID = -2630428449697230101L;
boolean correct;
String msg;
public boolean isCorrect() {
return correct;
}
public void setCorrect(boolean correct) {
this.correct = correct;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@@ -43,16 +43,16 @@ public class CategoryViewModel extends BaseViewModel<FragmentCategoryBinding, Fr
@Deprecated
public void getDirList() {
List<CategoryInfo> homeAppInfos = new ArrayList<>();
homeAppInfos.add(new CategoryInfo("分类1", "", 1, "a1"));
homeAppInfos.add(new CategoryInfo("分类2", "", 1, "a2"));
homeAppInfos.add(new CategoryInfo("分类3", "", 1, "a3"));
homeAppInfos.add(new CategoryInfo("分类4", "", 1, "a4"));
homeAppInfos.add(new CategoryInfo("分类5", "", 1, "a5"));
homeAppInfos.add(new CategoryInfo("分类6", "", 1, "a6"));
homeAppInfos.add(new CategoryInfo("分类7", "", 1, "a7"));
homeAppInfos.add(new CategoryInfo("分类8", "", 1, "a8"));
homeAppInfos.add(new CategoryInfo("分类9", "", 1, "a9"));
homeAppInfos.add(new CategoryInfo("分类10", "", 1, "a10"));
homeAppInfos.add(new CategoryInfo("美容师招聘系统", "", 1, "a1"));
homeAppInfos.add(new CategoryInfo("美容师培育系统", "", 1, "a2"));
homeAppInfos.add(new CategoryInfo("薪酬设计系统", "", 1, "a3"));
homeAppInfos.add(new CategoryInfo("拓客系统", "", 1, "a4"));
homeAppInfos.add(new CategoryInfo("锁客系统", "", 1, "a5"));
homeAppInfos.add(new CategoryInfo("培育系统", "", 1, "a6"));
homeAppInfos.add(new CategoryInfo("晋级系统", "", 1, "a7"));
homeAppInfos.add(new CategoryInfo("万元达标系统", "", 1, "a8"));
homeAppInfos.add(new CategoryInfo("海纳五大指标", "", 1, "a9"));
homeAppInfos.add(new CategoryInfo("设计课程", "", 1, "a10"));
// homeAppInfos.add(new CategoryInfo("下载视频", HomeAppAdapter.DOWNLOAD_CENTER, 1, ""));
// homeAppInfos.add(new CategoryInfo("用户中心", HomeAppAdapter.USER_CENTER, 1, ""));

View File

@@ -22,8 +22,7 @@ import com.arialyy.aria.core.task.DownloadTask;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hainaos.vc.R;
import com.hainaos.vc.bean.uiuios.AriaDownloadInfo;
import com.hainaos.vc.utils.LenovoCsdkUtil;
import com.hainaos.vc.bean.CategoryVideoInfo;
import com.hjq.toast.Toaster;
import java.io.File;
@@ -46,9 +45,9 @@ public class DownloadService extends Service {
Aria.download(this).register();
// mNotificationManagerCompat = NotificationManagerCompat.from(this);
mNotificationManagerCompat = NotificationManagerCompat.from(this);
// createNotificationChannel();
// createDownloadNotificationChannel();
createDownloadNotificationChannel();
// sendSimpleNotification();
}
@@ -119,11 +118,11 @@ public class DownloadService extends Service {
}
}
private void sendDownloadRunning(AriaDownloadInfo ariaDownloadInfo, int progress) {
private void sendDownloadRunning(CategoryVideoInfo ariaDownloadInfo, int progress) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_DOWNLOAD_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(ariaDownloadInfo.getAppName())
.setContentTitle(ariaDownloadInfo.getName())
.setContentText("下载中:" + progress + "%")
.setAutoCancel(true)
.setShowWhen(true)
@@ -132,24 +131,26 @@ public class DownloadService extends Service {
.setProgress(100, progress, false)
.setPriority(NotificationCompat.PRIORITY_HIGH);
// notificationId is a unique int for each notification that you must define
mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build());
// startForeground(ariaDownloadInfo.getAppId(), builder.build());
// mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build());
startForeground(ariaDownloadInfo.getFile_size(), builder.build());
}
private void sendDownloadComplete(AriaDownloadInfo ariaDownloadInfo, String path) {
private void sendDownloadComplete(CategoryVideoInfo ariaDownloadInfo, String path) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_DOWNLOAD_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(ariaDownloadInfo.getAppName())
.setContentTitle(ariaDownloadInfo.getName())
.setContentText("下载完成")
.setAutoCancel(true)
.setShowWhen(true)
.setOngoing(false)
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(createIntent(path));
// .setContentIntent(createIntent(path))
;
// notificationId is a unique int for each notification that you must define
mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build());
// mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build());
startForeground(ariaDownloadInfo.getFile_size(), builder.build());
}
/**
@@ -175,11 +176,11 @@ public class DownloadService extends Service {
return pendingIntent;
}
private void sendDownloadFail(AriaDownloadInfo ariaDownloadInfo) {
private void sendDownloadFail(CategoryVideoInfo ariaDownloadInfo) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_DOWNLOAD_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(ariaDownloadInfo.getAppName())
.setContentTitle(ariaDownloadInfo.getName())
.setContentText("下载失败")
.setAutoCancel(true)
.setShowWhen(true)
@@ -187,17 +188,18 @@ public class DownloadService extends Service {
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_HIGH);
// notificationId is a unique int for each notification that you must define
mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build());
// mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build());
startForeground(ariaDownloadInfo.getFile_size(), builder.build());
}
@Download.onTaskRunning
void running(DownloadTask task) {
String jsonString = task.getExtendField();
Log.e(TAG, "running: " + "正在下载:" + task.getPercent() + "% " + jsonString);
AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString);
CategoryVideoInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString);
if (ariaDownloadInfo != null) {
Toaster.show("正在下载: " + ariaDownloadInfo.getAppName() + "\t" + task.getPercent() + "%");
// sendDownloadRunning(ariaDownloadInfo, task.getPercent());
Toaster.show("正在下载: " + ariaDownloadInfo.getName() + "\t" + task.getPercent() + "%");
sendDownloadRunning(ariaDownloadInfo, task.getPercent());
}
}
@@ -205,14 +207,14 @@ public class DownloadService extends Service {
void taskComplete(DownloadTask task) {
String path = task.getFilePath();
Log.e(TAG, "taskComplete: " + path);
if (path.endsWith(".apk")) {
LenovoCsdkUtil.getInstance().installPackage(task.getFilePath());
if (path.endsWith(".hnv")) {
// LenovoCsdkUtil.getInstance().installPackage(task.getFilePath());
String jsonString = task.getExtendField();
Log.e(TAG, "taskComplete: " + "下载完成:" + jsonString);
AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString);
CategoryVideoInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString);
if (ariaDownloadInfo != null) {
Toaster.show("下载完成: " + "\t" + ariaDownloadInfo.getAppName());
// sendDownloadComplete(ariaDownloadInfo, task.getFilePath());
Toaster.show("下载完成: " + "\t" + ariaDownloadInfo.getName());
sendDownloadComplete(ariaDownloadInfo, task.getFilePath());
}
}
}
@@ -222,19 +224,19 @@ public class DownloadService extends Service {
Log.e(TAG, "taskFail: ");
String jsonString = task.getExtendField();
Log.e(TAG, "taskFail: " + "下载失败:" + jsonString);
AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString);
CategoryVideoInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString);
if (ariaDownloadInfo != null) {
Toaster.show("下载失败: " + "\t" + ariaDownloadInfo.getAppName());
// sendDownloadFail(ariaDownloadInfo);
Toaster.show("下载失败: " + "\t" + ariaDownloadInfo.getName());
sendDownloadFail(ariaDownloadInfo);
}
}
private AriaDownloadInfo getAriaDownloadInfo(String jsonString) {
private CategoryVideoInfo getAriaDownloadInfo(String jsonString) {
if (!TextUtils.isEmpty(jsonString)) {
Gson gson = new Gson();
Type type = new TypeToken<AriaDownloadInfo>() {
Type type = new TypeToken<CategoryVideoInfo>() {
}.getType();
AriaDownloadInfo ariaDownloadInfo = null;
CategoryVideoInfo ariaDownloadInfo = null;
try {
ariaDownloadInfo = gson.fromJson(jsonString, type);
} catch (Exception e) {

View File

@@ -3,6 +3,7 @@ package com.hainaos.vc.utils;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
@@ -11,6 +12,7 @@ import androidx.core.content.ContextCompat;
import com.arialyy.aria.core.Aria;
import com.hainaos.vc.bean.AppInfo;
import com.hainaos.vc.bean.CategoryVideoInfo;
import com.hainaos.vc.bean.uiuios.AppUpdateInfo;
import com.hainaos.vc.bean.uiuios.AriaDownloadInfo;
import com.hainaos.vc.gson.GsonUtils;
@@ -198,6 +200,7 @@ public class FileUtils {
}
}
@Deprecated
public static void ariaDownload(Context context, String dirName, String url, String md5) {
String downLoadPath = getHainaVideoPath(context) + dirName + File.separator;
File dirFile = new File(downLoadPath);
@@ -218,6 +221,12 @@ public class FileUtils {
// .ignoreFilePathOccupy()
.setExtendField(url)
.create(); //启动下载}
Intent intent = new Intent(context, DownloadService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
} else {
Log.e("ariaDownload", "fileName = " + fileName + " exists");
}
@@ -231,7 +240,66 @@ public class FileUtils {
// .ignoreFilePathOccupy()
.setExtendField(url)
.create(); //启动下载}
Intent intent = new Intent(context, DownloadService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
}
public static void ariaDownload(Context context, String dirName, CategoryVideoInfo categoryVideoInfo) {
String url = categoryVideoInfo.getFile_url();
String md5 = categoryVideoInfo.getMd5();
String downLoadPath = getHainaVideoPath(context) + dirName + File.separator;
File dirFile = new File(downLoadPath);
if (!dirFile.exists()) {
Log.e(TAG, "ariaDownload: mkdirs = " + dirFile.mkdirs());
}
String fileName = getFileNamefromURL(url);
File file = new File(downLoadPath + fileName);
if (file.exists() && !file.isDirectory()) {
String fileMD5 = com.blankj.utilcode.util.FileUtils.getFileMD5ToString(file);
Log.e("ariaDownload", "fileOnlineMD5=" + md5);
Log.e("ariaDownload", "fileMD5=" + fileMD5);
if (!TextUtils.isEmpty(md5)) {
if (!md5.equals(fileMD5)) {
Aria.download(context)
.load(url) //读取下载地址
.setFilePath(file.getAbsolutePath())
// .ignoreFilePathOccupy()
.setExtendField(GsonUtils.toJSONString(categoryVideoInfo))
.create(); //启动下载}
Intent intent = new Intent(context, DownloadService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
} else {
Log.e("ariaDownload", "fileName = " + fileName + " exists");
}
} else {
Log.e("ariaDownload", url + " no md5 params , skip");
}
} else {
Aria.download(context)
.load(url) //读取下载地址
.setFilePath(file.getAbsolutePath())
// .ignoreFilePathOccupy()
.setExtendField(GsonUtils.toJSONString(categoryVideoInfo))
.create(); //启动下载}
Intent intent = new Intent(context, DownloadService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
}
public static void ariaDownload(Context context, String dirName, String url) {
@@ -317,12 +385,7 @@ public class FileUtils {
.setExtendField(GsonUtils.toJSONString(ariaDownloadInfo))
.create(); //启动下载}
}
Intent intent = new Intent(context, DownloadService.class);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// context.startForegroundService(intent);
// } else {
context.startService(intent);
// }
}

View File

@@ -1,38 +1,33 @@
package com.hainaos.vc.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.StatFs;
import android.text.format.Formatter;
import android.util.Log;
import java.lang.reflect.Method;
public class Utils {
@SuppressLint({"MissingPermission", "HardwareIds"})
public static String getSerial() {
// if (BuildConfig.DEBUG) {
// return "T98005H1024GB32GB";
// @SuppressLint({"MissingPermission", "HardwareIds"})
// public static String getSerial() {
//// if (BuildConfig.DEBUG) {
//// return "T98005H1024GB32GB";
//// }
// String serial = "unknow";
// try {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
// serial = Build.getSerial();
// } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
// serial = Build.SERIAL;
// } else {//8.0-
// Class<?> c = Class.forName("android.os.SystemProperties");
// Method get = c.getMethod("get", String.class);
// serial = (String) get.invoke(c, "ro.serialno");
// }
// } catch (Exception e) {
// e.printStackTrace();
// Log.e("getSerial", "读取设备序列号异常:" + e.toString());
// }
// return serial;
// }
String serial = "unknow";
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
serial = Build.getSerial();
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
serial = Build.SERIAL;
} else {//8.0-
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("getSerial", "读取设备序列号异常:" + e.toString());
}
return serial;
}
public static String getDataTotalSize(Context context) {
StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath());

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -373,7 +373,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_more6"
app:layout_constraintTop_toTopOf="parent"
tools:text="用28GB/128GB" />
tools:text="用28GB/128GB" />
<ImageView
android:id="@+id/iv_more6"

View File

@@ -79,9 +79,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="4dp"
android:layout_marginStart="2dp"
android:gravity="center_horizontal"
android:maxLines="2"
android:minLines="2"
android:textColor="@color/white"
android:textSize="8sp"
app:layout_constraintBottom_toBottomOf="parent"

View File

@@ -28,19 +28,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_download_button"
android:text="下载"
android:textColor="@color/white"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
@@ -51,7 +38,7 @@
android:textColor="@color/white"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_download"
app:layout_constraintEnd_toStartOf="@+id/tv_delete"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/video_image"
app:layout_constraintTop_toTopOf="parent"
@@ -60,7 +47,9 @@
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="3"
android:gravity="center_vertical"
android:maxLines="3"
android:textColor="@color/black"
android:textSize="13sp"
@@ -70,8 +59,9 @@
<TextView
android:id="@+id/tv_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center_vertical"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/text_content"
@@ -81,8 +71,9 @@
<TextView
android:id="@+id/tv_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center_vertical"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/text_content"
@@ -91,6 +82,39 @@
</LinearLayout>
<TextView
android:id="@+id/tv_delete"
android:layout_width="56dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:gravity="center"
android:background="@drawable/bg_delete_button"
android:text="删除"
android:textColor="@color/white"
android:maxLines="1"
android:singleLine="true"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_download"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_download"
android:layout_width="56dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:maxLines="1"
android:singleLine="true"
android:background="@drawable/bg_download_button"
android:text="已下载"
android:textColor="@color/white"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,2 +1,3 @@
SET class_path=target/video-encryptor-1.0-SNAPSHOT.jar;
native-image --no-fallback -H:ConfigurationFileDirectories=META-INF/native-image --allow-incomplete-classpath -classpath %class_path% com.penngo.gralvm.MainSwing
SET class_path=target\video-encryptor-1.0.1.jar;
native-image --no-fallback -H:ConfigurationFileDirectories=src\main\resources\META-INF\native-image --allow-incomplete-classpath -classpath %class_path% com.hnos.video.VideoEncryptorGUI

View File

@@ -1,7 +1,9 @@
@REM 使用idea 的mvn clean package
java -agentlib:native-image-agent=config-output-dir=./META-INF/native-image -jar video-encryptor-1.0.jar
cd target
native-image -jar target\video-encryptor-1.0.jar --no-fallback -H:ConfigurationFileDirectories=.\src\main\resources\META-INF\native-image
java -agentlib:native-image-agent=config-output-dir=src\main\resources\META-INF\native-image -jar video-encryptor-1.0.1.jar
native-image -jar target\video-encryptor-1.0.1.jar --no-fallback -H:ConfigurationFileDirectories=src\main\resources\META-INF\native-image
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\editbin.exe" /SUBSYSTEM:WINDOWS video-encryptor-1.0.exe

View File

@@ -6,7 +6,7 @@
<groupId>com.hainaos</groupId>
<artifactId>video-encryptor</artifactId>
<version>1.0</version>
<version>1.0.1</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>

View File

@@ -21,8 +21,7 @@ public class VideoEncryptorGUI extends JFrame {
// 加密算法常量保持和VideoEncryptor一致
private static final String ALGORITHM = "AES/CTR/NoPadding";
// 视频文件扩展名列表(可根据需要扩展)
private static final List<String> VIDEO_EXTENSIONS = Arrays.asList("mp4", "avi", "mov", "mkv", "flv", "wmv",
"rmvb");
private static final List<String> VIDEO_EXTENSIONS = List.of("mp4");
// 测试用AES密钥16字节AES-128实际使用请替换为安全生成的密钥
private static final byte[] TEST_KEY = "1234567890123456".getBytes();
// 测试用IV向量16字节CTR模式要求IV长度等于块大小实际使用请随机生成

Binary file not shown.