diff --git a/app/build.gradle b/app/build.gradle index f618eea..b638c9b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' //沉浸状态栏 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a94044a..9e5c1d1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + { - 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 categoryUpdateInfos = listBaseResponse.data; mCategoryUpdateInfoListData.setValue(categoryUpdateInfos); } + mMMKV.encode(CommonConfig.CHECK_CATEGORY_UPDATE_NUMBER_TIME, currentTime); } @Override diff --git a/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java b/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java index bf9b055..a4b74ad 100644 --- a/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java +++ b/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java @@ -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 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>() { - @Override - public void onSubscribe(@NonNull Disposable d) { - Log.e("getVideoUpdate", "onSubscribe: "); - } - - @Override - public void onNext(@NonNull BaseResponse 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>() { +// @Override +// public void onSubscribe(@NonNull Disposable d) { +// Log.e("getVideoUpdate", "onSubscribe: "); +// } +// +// @Override +// public void onNext(@NonNull BaseResponse 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: "); +// } +// }); +// } } diff --git a/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoActivity.java b/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoActivity.java index fe88a39..35ade1c 100644 --- a/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoActivity.java +++ b/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoActivity.java @@ -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 { private static final String TAG = "CategoryActivity"; @@ -81,7 +74,7 @@ public class CategoryVideoActivity extends BaseMvvmActivity>() { + mViewModel.mCategoryVideoInfoListData.observe(this, new Observer>() { @Override - public void onChanged(BaseResponse baseResponse) { - if (baseResponse.code == 200) { - VideoListData videoListData = baseResponse.data; - List categoryVideoInfos = videoListData.getData(); - - 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 paths = new ArrayList<>(Arrays.asList(strings)); - ArrayList localVideoInfos = paths.stream() - .filter(new Predicate() { - @Override - public boolean test(String s) { - return FileUtils.isVideoFile(s); - } - }) - .map(new Function() { - @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); + public void onChanged(List categoryVideoInfos) { - if (categoryVideoInfos == null || categoryVideoInfos.isEmpty()) { - mViewDataBinding.clNodata.setVisibility(View.VISIBLE); - mViewDataBinding.rvVideo.setVisibility(View.GONE); - } else { - mViewDataBinding.clNodata.setVisibility(View.GONE); - mViewDataBinding.rvVideo.setVisibility(View.VISIBLE); - mViewDataBinding.tvTotal.setText(String.format(getString(R.string.video_total), categoryVideoInfos.size())); - } + mCategoryVideoAdapter.setData(categoryVideoInfos); + + + if (categoryVideoInfos == null || categoryVideoInfos.isEmpty()) { + mViewDataBinding.clNodata.setVisibility(View.VISIBLE); + mViewDataBinding.rvVideo.setVisibility(View.GONE); } else { - Toaster.show(baseResponse.msg); + mViewDataBinding.clNodata.setVisibility(View.GONE); + mViewDataBinding.rvVideo.setVisibility(View.VISIBLE); + mViewDataBinding.tvTotal.setText(String.format(getString(R.string.video_total), categoryVideoInfos.size())); + } + } + }); + + mViewModel.mPasswdCorrect.observe(this, new Observer() { + @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 { @@ -74,23 +82,96 @@ public class CategoryVideoViewModel extends BaseViewModel> mCategoryVideoInfoListData = new MutableLiveData<>(); + private Observable> getLocalCategoryVideoInfo(String dirName) { + return Observable.fromCallable(new Callable>() { + @Override + public List call() throws Exception { + ArrayList 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 paths = new ArrayList<>(Arrays.asList(strings)); + localVideoInfos = paths.stream() + .filter(new Predicate() { + @Override + public boolean test(String s) { + return FileUtils.isVideoFile(s); + } + }) + .map(new Function() { + @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> mCategoryVideoInfoListData = new MutableLiveData<>(); + public MutableLiveData mPasswdCorrect = new MutableLiveData<>(); + + public void getVideoList(String dir, String uuid, String password) { + Observable.zip(getLocalCategoryVideoInfo(dir), NetInterfaceManager.getInstance().getVideoListObservable(uuid, password), + new BiFunction, BaseResponse, List>() { + @Override + public List apply(List localCategoryVideoInfos, BaseResponse baseResponse) throws Throwable { + List allCategoryVideoInfos = new ArrayList<>(); + + PasswdInfo passwdInfo = new PasswdInfo(); + if (baseResponse.code == 200) { + VideoListData videoListData = baseResponse.data; + passwdInfo.setCorrect(true); + List onlineCategoryVideoInfos = videoListData.getData(); + allCategoryVideoInfos.addAll(onlineCategoryVideoInfos); + + // 1. 提取线上所有元素的name,存入Set(去重+O(1)查找,效率最高) + Set 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>() { + .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e("getVideoList", "onSubscribe: "); } @Override - public void onNext(@NonNull BaseResponse listBaseResponse) { - Log.e("getVideoList", "onNext: "); - mCategoryVideoInfoListData.setValue(listBaseResponse); - + public void onNext(@NonNull List categoryVideoInfos) { + Log.e("getVideoList", "onNext: " + categoryVideoInfos.size()); + mCategoryVideoInfoListData.setValue(categoryVideoInfos); } @Override @@ -103,41 +184,76 @@ public class CategoryVideoViewModel extends BaseViewModel>() { +// @Override +// public void onSubscribe(@NonNull Disposable d) { +// Log.e("getVideoList", "onSubscribe: "); +// } +// +// @Override +// public void onNext(@NonNull BaseResponse baseResponse) { +// Log.e("getVideoList", "onNext: "); +// PasswdInfo passwdInfo = new PasswdInfo(); +// if (baseResponse.code == 200) { +// VideoListData videoListData = baseResponse.data; +// List 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 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>() { - @Override - public void onSubscribe(@NonNull Disposable d) { - Log.e("getVideoUpdate", "onSubscribe: "); - } - - @Override - public void onNext(@NonNull BaseResponse 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>() { +// @Override +// public void onSubscribe(@NonNull Disposable d) { +// Log.e("getVideoUpdate", "onSubscribe: "); +// } +// +// @Override +// public void onNext(@NonNull BaseResponse 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: "); +// } +// }); +// } } diff --git a/app/src/main/java/com/hainaos/vc/activity/user/UserActivity.java b/app/src/main/java/com/hainaos/vc/activity/user/UserActivity.java index a3ee6c8..023b763 100644 --- a/app/src/main/java/com/hainaos/vc/activity/user/UserActivity.java +++ b/app/src/main/java/com/hainaos/vc/activity/user/UserActivity.java @@ -100,7 +100,7 @@ public class UserActivity extends BaseMvvmActivity mLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { diff --git a/app/src/main/java/com/hainaos/vc/adapter/CategoryVideoAdapter.java b/app/src/main/java/com/hainaos/vc/adapter/CategoryVideoAdapter.java index e0e114a..8439b7e 100644 --- a/app/src/main/java/com/hainaos/vc/adapter/CategoryVideoAdapter.java +++ b/app/src/main/java/com/hainaos/vc/adapter/CategoryVideoAdapter.java @@ -127,18 +127,23 @@ public class CategoryVideoAdapter extends RecyclerView.Adapter 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, "")); diff --git a/app/src/main/java/com/hainaos/vc/service/DownloadService.java b/app/src/main/java/com/hainaos/vc/service/DownloadService.java index 481ba91..8e735cb 100644 --- a/app/src/main/java/com/hainaos/vc/service/DownloadService.java +++ b/app/src/main/java/com/hainaos/vc/service/DownloadService.java @@ -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() { + Type type = new TypeToken() { }.getType(); - AriaDownloadInfo ariaDownloadInfo = null; + CategoryVideoInfo ariaDownloadInfo = null; try { ariaDownloadInfo = gson.fromJson(jsonString, type); } catch (Exception e) { diff --git a/app/src/main/java/com/hainaos/vc/utils/FileUtils.java b/app/src/main/java/com/hainaos/vc/utils/FileUtils.java index ab4c136..f6b9714 100644 --- a/app/src/main/java/com/hainaos/vc/utils/FileUtils.java +++ b/app/src/main/java/com/hainaos/vc/utils/FileUtils.java @@ -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); -// } + } diff --git a/app/src/main/java/com/hainaos/vc/utils/Utils.java b/app/src/main/java/com/hainaos/vc/utils/Utils.java index c3e955a..837e1e9 100644 --- a/app/src/main/java/com/hainaos/vc/utils/Utils.java +++ b/app/src/main/java/com/hainaos/vc/utils/Utils.java @@ -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()); // } - 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; - } +// return serial; +// } public static String getDataTotalSize(Context context) { StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); diff --git a/app/src/main/res/drawable-hdpi/icon_category.png b/app/src/main/res/drawable-hdpi/icon_category.png index 00860ca..07c0451 100644 Binary files a/app/src/main/res/drawable-hdpi/icon_category.png and b/app/src/main/res/drawable-hdpi/icon_category.png differ diff --git a/app/src/main/res/layout/activity_user.xml b/app/src/main/res/layout/activity_user.xml index caeab94..b6cc896 100644 --- a/app/src/main/res/layout/activity_user.xml +++ b/app/src/main/res/layout/activity_user.xml @@ -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" /> - - + + + + + \ No newline at end of file diff --git a/ui/video-encryptor/native_build.bat b/ui/video-encryptor/native_build.bat index eaec3fc..7d8e48f 100644 --- a/ui/video-encryptor/native_build.bat +++ b/ui/video-encryptor/native_build.bat @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/ui/video-encryptor/native_build_all.bat b/ui/video-encryptor/native_build_all.bat index 58a7b3e..e19ec21 100644 --- a/ui/video-encryptor/native_build_all.bat +++ b/ui/video-encryptor/native_build_all.bat @@ -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 diff --git a/ui/video-encryptor/pom.xml b/ui/video-encryptor/pom.xml index 9c661df..f9b5b7f 100644 --- a/ui/video-encryptor/pom.xml +++ b/ui/video-encryptor/pom.xml @@ -6,7 +6,7 @@ com.hainaos video-encryptor - 1.0 + 1.0.1 17 diff --git a/ui/video-encryptor/src/main/java/com/hnos/video/VideoEncryptorGUI.java b/ui/video-encryptor/src/main/java/com/hnos/video/VideoEncryptorGUI.java index 59cb99b..a356655 100644 --- a/ui/video-encryptor/src/main/java/com/hnos/video/VideoEncryptorGUI.java +++ b/ui/video-encryptor/src/main/java/com/hnos/video/VideoEncryptorGUI.java @@ -21,8 +21,7 @@ public class VideoEncryptorGUI extends JFrame { // 加密算法常量(保持和VideoEncryptor一致) private static final String ALGORITHM = "AES/CTR/NoPadding"; // 视频文件扩展名列表(可根据需要扩展) - private static final List VIDEO_EXTENSIONS = Arrays.asList("mp4", "avi", "mov", "mkv", "flv", "wmv", - "rmvb"); + private static final List VIDEO_EXTENSIONS = List.of("mp4"); // 测试用AES密钥(16字节,AES-128),实际使用请替换为安全生成的密钥 private static final byte[] TEST_KEY = "1234567890123456".getBytes(); // 测试用IV向量(16字节,CTR模式要求IV长度等于块大小),实际使用请随机生成 diff --git a/ui/video-encryptor/video-encryptor-1.0.zip b/ui/video-encryptor/video-encryptor-1.0.zip new file mode 100644 index 0000000..25513db Binary files /dev/null and b/ui/video-encryptor/video-encryptor-1.0.zip differ