|
|
@@ -0,0 +1,233 @@
|
|
|
+package com.datarecovery.master.utils;
|
|
|
+
|
|
|
+import static android.content.Context.POWER_SERVICE;
|
|
|
+
|
|
|
+import android.content.Context;
|
|
|
+import android.net.Uri;
|
|
|
+import android.os.CancellationSignal;
|
|
|
+import android.os.PowerManager;
|
|
|
+import android.text.TextUtils;
|
|
|
+
|
|
|
+import com.datarecovery.master.utils.xfile.XFile;
|
|
|
+import com.datarecovery.master.utils.xfile.XFileSearch;
|
|
|
+
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.HashSet;
|
|
|
+
|
|
|
+import atmob.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
|
|
+import atmob.reactivex.rxjava3.core.BackpressureStrategy;
|
|
|
+import atmob.reactivex.rxjava3.core.Flowable;
|
|
|
+import atmob.reactivex.rxjava3.core.FlowableOnSubscribe;
|
|
|
+
|
|
|
+public class FilesSearch {
|
|
|
+
|
|
|
+ public static Flowable<DocumentFile> search(Context context, int... acceptCategory) {
|
|
|
+ if (acceptCategory == null || acceptCategory.length == 0) {
|
|
|
+ return Flowable.empty();
|
|
|
+ }
|
|
|
+ HashSet<Integer> categories = new HashSet<>();
|
|
|
+ for (int category : acceptCategory) {
|
|
|
+ categories.add(category);
|
|
|
+ }
|
|
|
+ return Flowable.create((FlowableOnSubscribe<XFile>) emitter -> {
|
|
|
+ try {
|
|
|
+ CancellationSignal cancellationSignal = XFileSearch.searchExternalStorageAsync(context, new XFileSearch.FileFilter() {
|
|
|
+ @Override
|
|
|
+ public boolean acceptFile(XFile file) {
|
|
|
+ return isAcceptFile(file);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean acceptDirectory(XFile file) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }, new XFileSearch.FileSearchCallback() {
|
|
|
+ @Override
|
|
|
+ public void onStart() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onEachFile(XFile file) {
|
|
|
+ emitter.onNext(file);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onFinish() {
|
|
|
+ emitter.onComplete();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ emitter.setCancellable(cancellationSignal::cancel);
|
|
|
+ } catch (Exception e) {
|
|
|
+ emitter.onError(e);
|
|
|
+ }
|
|
|
+ }, BackpressureStrategy.BUFFER)
|
|
|
+ .filter(xFile -> xFile.getTag() != null)
|
|
|
+ .filter(xFile -> {
|
|
|
+ Integer tag = (Integer) xFile.getTag();
|
|
|
+ return categories.contains(tag);
|
|
|
+ })
|
|
|
+ .map(xFile -> new DocumentFile(xFile, (Integer) xFile.getTag()))
|
|
|
+ .doOnSubscribe(subscription -> {
|
|
|
+ subscription.request(Long.MAX_VALUE);
|
|
|
+
|
|
|
+ acquireWakeLock(context);
|
|
|
+ })
|
|
|
+ .doOnCancel(() -> releaseWakeLock(context))
|
|
|
+ .doOnTerminate(() -> releaseWakeLock(context))
|
|
|
+ .subscribeOn(AndroidSchedulers.mainThread());
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void releaseWakeLock(Context context) {
|
|
|
+ PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
|
|
|
+ PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
|
|
+ "DocumentSearch::search");
|
|
|
+ if (wakeLock.isHeld()) {
|
|
|
+ wakeLock.release();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void acquireWakeLock(Context context) {
|
|
|
+ PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
|
|
|
+ PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
|
|
+ "DocumentSearch::search");
|
|
|
+ wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isAcceptFile(XFile file) {
|
|
|
+ if (file == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ String name = file.getName();
|
|
|
+ if (TextUtils.isEmpty(name)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (isWordFile(name)) {
|
|
|
+ file.setTag(DocumentFile.WORD);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (isExcelFile(name)) {
|
|
|
+ file.setTag(DocumentFile.EXCEL);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (isPPTFile(name)) {
|
|
|
+ file.setTag(DocumentFile.PPT);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (isPDFFile(name)) {
|
|
|
+ file.setTag(DocumentFile.PDF);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (isVideoFile(name)) {
|
|
|
+ file.setTag(DocumentFile.VIDEO);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (isAudioFile(name)) {
|
|
|
+ file.setTag(DocumentFile.AUDIO);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isAudioFile(String name) {
|
|
|
+ return name.endsWith(".mp3") || name.endsWith(".wav") || name.endsWith(".wma") ||
|
|
|
+ name.endsWith(".ogg") || name.endsWith(".ape") || name.endsWith(".flac") ||
|
|
|
+ name.endsWith(".aac") || name.endsWith(".m4a") || name.endsWith(".ac3") ||
|
|
|
+ name.endsWith(".mmf") || name.endsWith(".amr") || name.endsWith(".m4r") ||
|
|
|
+ name.endsWith(".m4b") || name.endsWith(".midi") || name.endsWith(".mp2") ||
|
|
|
+ name.endsWith(".mka") || name.endsWith(".mpa") || name.endsWith(".mpc") ||
|
|
|
+ name.endsWith(".ra") || name.endsWith(".rm") || name.endsWith(".tta") ||
|
|
|
+ name.endsWith(".wv") || name.endsWith(".opus");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isVideoFile(String name) {
|
|
|
+ return name.endsWith(".mp4") || name.endsWith(".avi") || name.endsWith(".mov") ||
|
|
|
+ name.endsWith(".wmv") || name.endsWith(".flv") || name.endsWith(".mkv") ||
|
|
|
+ name.endsWith(".rmvb") || name.endsWith(".rm") || name.endsWith(".3gp") ||
|
|
|
+ name.endsWith(".mpeg") || name.endsWith(".mpg") || name.endsWith(".ts") ||
|
|
|
+ name.endsWith(".webm") || name.endsWith(".vob") || name.endsWith(".swf");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isPDFFile(String name) {
|
|
|
+ return name.endsWith(".pdf");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isPPTFile(String name) {
|
|
|
+ return name.endsWith(".ppt") || name.endsWith(".pptx") || name.endsWith(".dps");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isExcelFile(String name) {
|
|
|
+ return name.endsWith(".xls") || name.endsWith(".xlsx") || name.endsWith(".et");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isWordFile(String name) {
|
|
|
+ return name.endsWith(".doc") || name.endsWith(".docx") || name.endsWith(".wps");
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class DocumentFile {
|
|
|
+ public static final int WORD = 1;
|
|
|
+ public static final int EXCEL = 2;
|
|
|
+ public static final int PPT = 3;
|
|
|
+ public static final int PDF = 4;
|
|
|
+ public static final int VIDEO = 5;
|
|
|
+ public static final int AUDIO = 6;
|
|
|
+ private final XFile xFile;
|
|
|
+ private final int category;
|
|
|
+ private String name;
|
|
|
+ private long size;
|
|
|
+ private Uri uri;
|
|
|
+ private String path;
|
|
|
+
|
|
|
+ public DocumentFile(XFile xFile, int category) {
|
|
|
+ this.xFile = xFile;
|
|
|
+ this.category = category;
|
|
|
+ try {
|
|
|
+ this.name = xFile.getName();
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ this.size = xFile.length();
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ this.uri = xFile.getUri();
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ this.path = xFile.getPath();
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getCategory() {
|
|
|
+ return category;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getName() {
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+ public long getSize() {
|
|
|
+ return size;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Uri getUri() {
|
|
|
+ return uri;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getPath() {
|
|
|
+ return path;
|
|
|
+ }
|
|
|
+
|
|
|
+ public InputStream newInputStream() throws Exception {
|
|
|
+ return xFile.newInputStream();
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean delete() throws Exception {
|
|
|
+ return xFile.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|