Browse Source

[New]图片扫描新增文件夹过滤 & 新增PNG搜索

zhipeng 1 year ago
parent
commit
7761fff96a

+ 5 - 0
app/src/main/java/com/datarecovery/master/utils/FilesSearch.java

@@ -43,6 +43,11 @@ public class FilesSearch {
                             public boolean acceptDirectory(XFile file) {
                                 return false;
                             }
+
+                            @Override
+                            public boolean filterDirectory(XFile file) {
+                                return false;
+                            }
                         }, new XFileSearch.FileSearchCallback() {
                             @Override
                             public void onStart() {

+ 60 - 10
app/src/main/java/com/datarecovery/master/utils/ImageDeepDetector.java

@@ -45,7 +45,7 @@ public class ImageDeepDetector {
     private static final int IMAGE_SUFFIX = 1;
     private static final int WECHAT_CACHE = 2;
     private static final int GALLERY_CACHE = 3;
-    private static final int JPG_MAGIC = 4;
+    private static final int IMG_MAGIC = 4;
     private static final int OPPO_GALLERY_CACHE = 5;
     private static final int VIVO_GALLERY_CACHE = 6;
     private static final int XIAOMI_GALLERY_CACHE = 7;
@@ -65,6 +65,11 @@ public class ImageDeepDetector {
                                     public boolean acceptDirectory(XFile file) {
                                         return isAcceptDirectory(file);
                                     }
+
+                                    @Override
+                                    public boolean filterDirectory(XFile file) {
+                                        return isFilterDirectory(file);
+                                    }
                                 },
                                 new XFileSearch.FileSearchCallback() {
                                     @Override
@@ -90,7 +95,7 @@ public class ImageDeepDetector {
                 .flatMap((Function<XFile, Publisher<ImageFile>>) xFile -> {
                     int tag = (int) xFile.getTag();
                     switch (tag) {
-                        case JPG_MAGIC:
+                        case IMG_MAGIC:
                         case IMAGE_SUFFIX:
                             return Flowable.just(new ImageFile(xFile));
                         case XIAOMI_GALLERY_CACHE:
@@ -137,6 +142,49 @@ public class ImageDeepDetector {
         wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
     }
 
+    private static boolean isFilterDirectory(XFile file) {
+        try {
+            String path = file.getPath();
+            if (TextUtils.isEmpty(path)) {
+                return false;
+            }
+            if (path.contains("com.kuaishou.nebula") && (path.contains("live_gift_store_icon_directory") ||
+                    path.contains("magic_finger_resource") || path.contains("theme_resource") ||
+                    path.contains("magic_emoji_resource") || path.contains(".material_library_resource") ||
+                    path.contains("sticker_resource")
+            )) {
+                return true;
+            }
+            if ((path.contains("com.tencent.mobileqq") || path.contains("com.tencent.tim")) && (path.contains("qvideo_newvideo_tips") ||
+                    path.contains("Gameicon"))) {
+                return true;
+            }
+            if ((path.contains("com.ss.android.article.video") || path.contains("com.ss.android.ugc.aweme")) && (path.contains("liveroom") ||
+                    path.contains("effect") || path.contains("card_3d_res") || path.contains("weboffline") || path.contains("fantasy_lottie_res")
+            )) {
+                return true;
+            }
+            if ((path.contains("com.taobao.taobao") || path.contains("com.tmall.wireless")) && (path.contains("AVFSCache") ||
+                    path.contains("gs_fs"))) {
+                return true;
+            }
+            if ((path.contains("com.baidu.BaiduMap")) && (path.contains("sticker"))) {
+                return true;
+            }
+            if ((path.contains("com.eg.android.AlipayGphone")) && (path.contains("Sandbox"))) {
+                return true;
+            }
+            if ((path.contains("air.tv.douyu.android")) && (path.contains("skin_download_dir"))) {
+                return true;
+            }
+            if (path.contains("tencent/MobileQQ/doodle_template") || path.contains("tencent%2FMobileQQ%2Fdoodle_template")) {
+                return true;
+            }
+        } catch (Exception ignore) {
+        }
+        return false;
+    }
+
     private static Flowable<ImageFile> detectMeizuGalleryCache(Context context, XFile xFile) {
         return new GenericImgCollectionDetector(context, xFile, ImageFile.CATEGORY_GALLERY)
                 .subscribeOn(Schedulers.io())
@@ -218,25 +266,27 @@ public class ImageDeepDetector {
             }
         } catch (Exception ignore) {
         }
-        if (hasJpgMagic(file)) {
-            file.setTag(JPG_MAGIC);
+        if (hasImgMagic(file)) {
+            file.setTag(IMG_MAGIC);
             return true;
         }
         return false;
     }
 
-    private static boolean hasJpgMagic(XFile file) {
+    private static boolean hasImgMagic(XFile file) {
         try (InputStream inputStream = file.newInputStream()) {
-            if (inputStream.available() < 4) {
+            byte[] bytes = new byte[8];
+            if (inputStream.read(bytes) != 8) {
                 return false;
             }
 
-            byte[] bytes = new byte[2];
-            if (inputStream.read(bytes) != 2) {
-                return false;
+            if (bytes[0] == (byte) 0x89 && bytes[1] == (byte) 0x50 && bytes[2] == (byte) 0x4E && bytes[3] == (byte) 0x47
+                    && bytes[4] == (byte) 0x0D && bytes[5] == (byte) 0x0A && bytes[6] == (byte) 0x1A && bytes[7] == (byte) 0x0A) {
+                // png
+                return true;
             }
-            boolean hasHeaderMagic = bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xD8;
 
+            boolean hasHeaderMagic = bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xD8; // jpg header
             if (!hasHeaderMagic) {
                 return false;
             }

+ 38 - 8
app/src/main/java/com/datarecovery/master/utils/xfile/XFileSearch.java

@@ -293,10 +293,17 @@ public class XFileSearch {
                         continue;
                     }
                     if (childFile.isDirectory()) {
-                        if (fileFilter == null || !fileFilter.acceptDirectory(childFile)) {
+                        if (fileFilter == null) {
                             fileStock.push(childFile);
-                        } else {
+                            continue;
+                        }
+                        if (fileFilter.filterDirectory(childFile)) {
+                            continue;
+                        }
+                        if (fileFilter.acceptDirectory(childFile)) {
                             result.add(childFile);
+                        } else {
+                            fileStock.push(childFile);
                         }
                     } else if (fileFilter == null || fileFilter.acceptFile(childFile)) {
                         result.add(childFile);
@@ -337,12 +344,19 @@ public class XFileSearch {
                         continue;
                     }
                     if (childFile.isDirectory()) {
-                        if (fileFilter == null || !fileFilter.acceptDirectory(childFile)) {
+                        if (fileFilter == null) {
                             fileStock.push(childFile);
-                        } else {
+                            continue;
+                        }
+                        if (fileFilter.filterDirectory(childFile)) {
+                            continue;
+                        }
+                        if (fileFilter.acceptDirectory(childFile)) {
                             if (callback != null) {
                                 callback.onEachFile(childFile);
                             }
+                        } else {
+                            fileStock.push(childFile);
                         }
                     } else if (fileFilter == null || fileFilter.acceptFile(childFile)) {
                         if (callback != null) {
@@ -380,10 +394,17 @@ public class XFileSearch {
                         continue;
                     }
                     if (childFile.isDirectory()) {
-                        if (fileFilter == null || !fileFilter.acceptDirectory(childFile)) {
+                        if (fileFilter == null) {
                             fileQueue.offer(childFile);
-                        } else {
+                            continue;
+                        }
+                        if (fileFilter.filterDirectory(childFile)) {
+                            continue;
+                        }
+                        if (fileFilter.acceptDirectory(childFile)) {
                             result.add(childFile);
+                        } else {
+                            fileQueue.offer(childFile);
                         }
                     } else if (fileFilter == null || fileFilter.acceptFile(childFile)) {
                         result.add(childFile);
@@ -423,12 +444,19 @@ public class XFileSearch {
                         continue;
                     }
                     if (childFile.isDirectory()) {
-                        if (fileFilter == null || !fileFilter.acceptDirectory(childFile)) {
+                        if (fileFilter == null) {
                             fileQueue.offer(childFile);
-                        } else {
+                            continue;
+                        }
+                        if (fileFilter.filterDirectory(childFile)) {
+                            continue;
+                        }
+                        if (fileFilter.acceptDirectory(childFile)) {
                             if (callback != null) {
                                 callback.onEachFile(childFile);
                             }
+                        } else {
+                            fileQueue.offer(childFile);
                         }
                     } else if (fileFilter == null || fileFilter.acceptFile(childFile)) {
                         if (callback != null) {
@@ -449,6 +477,8 @@ public class XFileSearch {
         boolean acceptFile(XFile file);
 
         boolean acceptDirectory(XFile file);
+
+        boolean filterDirectory(XFile file);
     }
 
     public interface FileSearchCallback {