|
|
@@ -18,21 +18,27 @@ import com.datarecovery.master.sdk.bugly.BuglyHelper;
|
|
|
import com.datarecovery.master.utils.BoxingUtil;
|
|
|
import com.datarecovery.master.utils.FileUtil;
|
|
|
import com.datarecovery.master.utils.FilesSearch;
|
|
|
+import com.datarecovery.master.utils.ImageDeepDetector;
|
|
|
import com.datarecovery.master.utils.Maps;
|
|
|
import com.datarecovery.master.utils.MediaStoreHelper;
|
|
|
import com.datarecovery.master.utils.ReportUtil;
|
|
|
+import com.datarecovery.master.utils.ReverseArrayList;
|
|
|
import com.datarecovery.master.utils.ToastUtil;
|
|
|
|
|
|
import org.reactivestreams.Subscriber;
|
|
|
import org.reactivestreams.Subscription;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Iterator;
|
|
|
import java.util.List;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
|
import atmob.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
|
|
+import atmob.reactivex.rxjava3.annotations.NonNull;
|
|
|
+import atmob.reactivex.rxjava3.core.Single;
|
|
|
+import atmob.reactivex.rxjava3.core.SingleObserver;
|
|
|
import atmob.reactivex.rxjava3.disposables.Disposable;
|
|
|
import atmob.rxjava.utils.RxJavaUtil;
|
|
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
|
|
@@ -48,11 +54,18 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
private final int[] tabTitle = {R.string.word, R.string.excel, R.string.ppt, R.string.pdf};
|
|
|
|
|
|
private final List<MutableLiveData<Boolean>> checkList = new ArrayList<>();
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedWordList = new MutableLiveData<>(new ArrayList<>());
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedExcelList = new MutableLiveData<>(new ArrayList<>());
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPPTList = new MutableLiveData<>(new ArrayList<>());
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPDFList = new MutableLiveData<>(new ArrayList<>());
|
|
|
- private final MutableLiveData<List<FilesSearch.DocumentFile>> selectedList = new MutableLiveData<>(new ArrayList<>());
|
|
|
+ private final List<FilesSearch.DocumentFile> wordList = new ReverseArrayList<>();
|
|
|
+ private final List<FilesSearch.DocumentFile> excelList = new ReverseArrayList<>();
|
|
|
+ private final List<FilesSearch.DocumentFile> pptList = new ReverseArrayList<>();
|
|
|
+ private final List<FilesSearch.DocumentFile> pdfList = new ReverseArrayList<>();
|
|
|
+ private final List<FilesSearch.DocumentFile> selectList = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedWordList = new MutableLiveData<>();
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedExcelList = new MutableLiveData<>();
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPPTList = new MutableLiveData<>();
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPDFList = new MutableLiveData<>();
|
|
|
+ private final MutableLiveData<List<FilesSearch.DocumentFile>> selectedList = new MutableLiveData<>();
|
|
|
|
|
|
private final SingleLiveEvent<?> scrollTop = new SingleLiveEvent<>();
|
|
|
private final MutableLiveData<Boolean> showTrialView = new MutableLiveData<>();
|
|
|
@@ -167,6 +180,11 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
scanDisposable = Disposable.fromSubscription(s);
|
|
|
addDisposable(scanDisposable);
|
|
|
showScanDialogEvent.setValue(true);
|
|
|
+ wordList.clear();
|
|
|
+ excelList.clear();
|
|
|
+ pptList.clear();
|
|
|
+ pdfList.clear();
|
|
|
+ selectList.clear();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -174,24 +192,37 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
if (documentFiles == null || documentFiles.isEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
- MutableLiveData<List<FilesSearch.DocumentFile>> liveData = null;
|
|
|
+ int wordCount = 0;
|
|
|
+ int excelCount = 0;
|
|
|
+ int pptCount = 0;
|
|
|
+ int pdfCount = 0;
|
|
|
for (FilesSearch.DocumentFile item : documentFiles) {
|
|
|
+ detectedLastFileName.setValue(item.getName());
|
|
|
if (item.getCategory() == FilesSearch.DocumentFile.WORD) {
|
|
|
- liveData = detectedWordList;
|
|
|
+ wordCount++;
|
|
|
+ wordList.add(item);
|
|
|
} else if (item.getCategory() == FilesSearch.DocumentFile.EXCEL) {
|
|
|
- liveData = detectedExcelList;
|
|
|
+ excelCount++;
|
|
|
+ excelList.add(item);
|
|
|
} else if (item.getCategory() == FilesSearch.DocumentFile.PPT) {
|
|
|
- liveData = detectedPPTList;
|
|
|
+ pptCount++;
|
|
|
+ pptList.add(item);
|
|
|
} else if (item.getCategory() == FilesSearch.DocumentFile.PDF) {
|
|
|
- liveData = detectedPDFList;
|
|
|
- }
|
|
|
- if (liveData == null) {
|
|
|
- continue;
|
|
|
+ pdfCount++;
|
|
|
+ pdfList.add(item);
|
|
|
}
|
|
|
- detectedLastFileName.setValue(item.getName());
|
|
|
- List<FilesSearch.DocumentFile> list = getList(liveData);
|
|
|
- list.add(0, item);
|
|
|
- liveData.setValue(list);
|
|
|
+ }
|
|
|
+ if (wordCount > 0) {
|
|
|
+ detectedWordList.setValue(wordList);
|
|
|
+ }
|
|
|
+ if (excelCount > 0) {
|
|
|
+ detectedExcelList.setValue(excelList);
|
|
|
+ }
|
|
|
+ if (pptCount > 0) {
|
|
|
+ detectedPPTList.setValue(pptList);
|
|
|
+ }
|
|
|
+ if (pdfCount > 0) {
|
|
|
+ detectedPDFList.setValue(pdfList);
|
|
|
}
|
|
|
scrollTop.call();
|
|
|
}
|
|
|
@@ -219,67 +250,49 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
private void setFreeExport() {
|
|
|
if (isTrial) {
|
|
|
showTrialView.setValue(true);
|
|
|
- List<FilesSearch.DocumentFile> list = getList(detectedWordList);
|
|
|
- if (!list.isEmpty()) {
|
|
|
- list.get(0).setTrial(true);
|
|
|
+ if (!wordList.isEmpty()) {
|
|
|
+ wordList.get(0).setTrial(true);
|
|
|
}
|
|
|
- list = getList(detectedExcelList);
|
|
|
- if (!list.isEmpty()) {
|
|
|
- list.get(0).setTrial(true);
|
|
|
+ if (!excelList.isEmpty()) {
|
|
|
+ excelList.get(0).setTrial(true);
|
|
|
}
|
|
|
- list = getList(detectedPPTList);
|
|
|
- if (!list.isEmpty()) {
|
|
|
- list.get(0).setTrial(true);
|
|
|
+ if (!pptList.isEmpty()) {
|
|
|
+ pptList.get(0).setTrial(true);
|
|
|
}
|
|
|
- list = getList(detectedPDFList);
|
|
|
- if (!list.isEmpty()) {
|
|
|
- list.get(0).setTrial(true);
|
|
|
+ if (!pdfList.isEmpty()) {
|
|
|
+ pdfList.get(0).setTrial(true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- private List<FilesSearch.DocumentFile> getList(LiveData<List<FilesSearch.DocumentFile>> liveData) {
|
|
|
- List<FilesSearch.DocumentFile> selectList = liveData.getValue();
|
|
|
- if (selectList == null) {
|
|
|
- selectList = new ArrayList<>();
|
|
|
- }
|
|
|
- return selectList;
|
|
|
- }
|
|
|
-
|
|
|
public void onCheckAllClick(boolean isCheck) {
|
|
|
int index = BoxingUtil.boxing(checkPosition.getValue());
|
|
|
getCheckAll(index).setValue(isCheck);
|
|
|
int id = tabTitle[index];
|
|
|
- MutableLiveData<List<FilesSearch.DocumentFile>> liveData = null;
|
|
|
+ List<FilesSearch.DocumentFile> list = null;
|
|
|
if (id == R.string.word) {
|
|
|
- liveData = detectedWordList;
|
|
|
+ list = wordList;
|
|
|
} else if (id == R.string.excel) {
|
|
|
- liveData = detectedExcelList;
|
|
|
+ list = excelList;
|
|
|
} else if (id == R.string.ppt) {
|
|
|
- liveData = detectedPPTList;
|
|
|
+ list = pptList;
|
|
|
} else if (id == R.string.pdf) {
|
|
|
- liveData = detectedPDFList;
|
|
|
- }
|
|
|
- if (liveData == null) {
|
|
|
- return;
|
|
|
+ list = pdfList;
|
|
|
}
|
|
|
- List<FilesSearch.DocumentFile> list = getList(liveData);
|
|
|
- if (list.isEmpty()) {
|
|
|
+ if (list == null || list.isEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
- List<FilesSearch.DocumentFile> selectedList = getList(this.selectedList);
|
|
|
for (FilesSearch.DocumentFile item : list) {
|
|
|
if (item.isCheck() != isCheck) {
|
|
|
if (isCheck) {
|
|
|
- selectedList.add(item);
|
|
|
+ selectList.add(item);
|
|
|
} else {
|
|
|
- selectedList.remove(item);
|
|
|
+ selectList.remove(item);
|
|
|
}
|
|
|
}
|
|
|
item.setCheck(isCheck);
|
|
|
}
|
|
|
- this.selectedList.setValue(selectedList);
|
|
|
+ this.selectedList.setValue(selectList);
|
|
|
}
|
|
|
|
|
|
public MutableLiveData<Boolean> getCheckAll(int position) {
|
|
|
@@ -288,12 +301,11 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
|
|
|
|
|
|
public void onExportClick() {
|
|
|
- List<FilesSearch.DocumentFile> list = selectedList.getValue();
|
|
|
- if (list == null || list.isEmpty()) {
|
|
|
+ if (selectList == null || selectList.isEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
if (isTrial) {
|
|
|
- for (FilesSearch.DocumentFile file : list) {
|
|
|
+ for (FilesSearch.DocumentFile file : selectList) {
|
|
|
if (!file.isTrial()) {
|
|
|
showTrialExportFailDialog.call();
|
|
|
return;
|
|
|
@@ -304,24 +316,53 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
- showLoadingEvent.setValue(true);
|
|
|
- RxJavaUtil.doInBackground(() -> {
|
|
|
- for (FilesSearch.DocumentFile item : list) {
|
|
|
- MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_FILES, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_FILES, item.getName()));
|
|
|
- item.setCheck(false);
|
|
|
- }
|
|
|
- return true;
|
|
|
- }, o -> {
|
|
|
- getCheckAll(BoxingUtil.boxing(checkPosition.getValue())).setValue(false);
|
|
|
- showLoadingEvent.setValue(false);
|
|
|
- ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
|
|
|
- list.clear();
|
|
|
- selectedList.setValue(list);
|
|
|
- }, throwable -> {
|
|
|
- showLoadingEvent.setValue(false);
|
|
|
- ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
|
|
|
- BuglyHelper.postCatchedException(new Exception("文件导出:", throwable));
|
|
|
- });
|
|
|
+ Single.just(selectList.size())
|
|
|
+ .map(oldSize -> {
|
|
|
+ Iterator<FilesSearch.DocumentFile> iterator = selectList.iterator();
|
|
|
+ int errorCount = 0;
|
|
|
+ Exception exception = null;
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ FilesSearch.DocumentFile item = iterator.next();
|
|
|
+ try {
|
|
|
+ MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_FILES, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_FILES, item.getName()));
|
|
|
+ item.setCheck(false);
|
|
|
+ iterator.remove();
|
|
|
+ } catch (Exception throwable) {
|
|
|
+ errorCount++;
|
|
|
+ exception = throwable;
|
|
|
+ BuglyHelper.postCatchedException(new Exception("文件导出:", throwable));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (errorCount == oldSize) {
|
|
|
+ throw new Exception("导出失败" + (exception == null ? "" : ":" + exception.getMessage()));
|
|
|
+ } else if (errorCount > 0) {
|
|
|
+ throw new Exception("部分导出失败" + ":" + exception.getMessage());
|
|
|
+ }
|
|
|
+ return errorCount;
|
|
|
+ })
|
|
|
+ .compose(RxJavaUtil.SingleSchedule.io2Main())
|
|
|
+ .subscribe(new SingleObserver<Integer>() {
|
|
|
+ @Override
|
|
|
+ public void onSubscribe(@NonNull Disposable d) {
|
|
|
+ showLoadingEvent.setValue(true);
|
|
|
+ addDisposable(d);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSuccess(@NonNull Integer integer) {
|
|
|
+ showLoadingEvent.setValue(false);
|
|
|
+ selectedList.setValue(selectList);
|
|
|
+ ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
|
|
|
+ getCheckAll(BoxingUtil.boxing(checkPosition.getValue())).setValue(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(@NonNull Throwable throwable) {
|
|
|
+ showLoadingEvent.setValue(false);
|
|
|
+ selectedList.setValue(selectList);
|
|
|
+ ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
public void itemClick(FilesSearch.DocumentFile documentFile) {
|
|
|
@@ -329,13 +370,12 @@ public class FileRecoverViewModel extends BaseViewModel {
|
|
|
return;
|
|
|
}
|
|
|
documentFile.setCheck(!documentFile.isCheck());
|
|
|
- List<FilesSearch.DocumentFile> list = getList(selectedList);
|
|
|
if (documentFile.isCheck()) {
|
|
|
- list.add(documentFile);
|
|
|
+ selectList.add(documentFile);
|
|
|
} else {
|
|
|
- list.remove(documentFile);
|
|
|
+ selectList.remove(documentFile);
|
|
|
}
|
|
|
- this.selectedList.setValue(list);
|
|
|
+ this.selectedList.setValue(selectList);
|
|
|
}
|
|
|
|
|
|
@Override
|