|
@@ -45,7 +45,7 @@ public class ImageDeepDetector {
|
|
|
private static final int IMAGE_SUFFIX = 1;
|
|
private static final int IMAGE_SUFFIX = 1;
|
|
|
private static final int WECHAT_CACHE = 2;
|
|
private static final int WECHAT_CACHE = 2;
|
|
|
private static final int GALLERY_CACHE = 3;
|
|
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 OPPO_GALLERY_CACHE = 5;
|
|
|
private static final int VIVO_GALLERY_CACHE = 6;
|
|
private static final int VIVO_GALLERY_CACHE = 6;
|
|
|
private static final int XIAOMI_GALLERY_CACHE = 7;
|
|
private static final int XIAOMI_GALLERY_CACHE = 7;
|
|
@@ -65,6 +65,11 @@ public class ImageDeepDetector {
|
|
|
public boolean acceptDirectory(XFile file) {
|
|
public boolean acceptDirectory(XFile file) {
|
|
|
return isAcceptDirectory(file);
|
|
return isAcceptDirectory(file);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean filterDirectory(XFile file) {
|
|
|
|
|
+ return isFilterDirectory(file);
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
new XFileSearch.FileSearchCallback() {
|
|
new XFileSearch.FileSearchCallback() {
|
|
|
@Override
|
|
@Override
|
|
@@ -90,7 +95,7 @@ public class ImageDeepDetector {
|
|
|
.flatMap((Function<XFile, Publisher<ImageFile>>) xFile -> {
|
|
.flatMap((Function<XFile, Publisher<ImageFile>>) xFile -> {
|
|
|
int tag = (int) xFile.getTag();
|
|
int tag = (int) xFile.getTag();
|
|
|
switch (tag) {
|
|
switch (tag) {
|
|
|
- case JPG_MAGIC:
|
|
|
|
|
|
|
+ case IMG_MAGIC:
|
|
|
case IMAGE_SUFFIX:
|
|
case IMAGE_SUFFIX:
|
|
|
return Flowable.just(new ImageFile(xFile));
|
|
return Flowable.just(new ImageFile(xFile));
|
|
|
case XIAOMI_GALLERY_CACHE:
|
|
case XIAOMI_GALLERY_CACHE:
|
|
@@ -137,6 +142,49 @@ public class ImageDeepDetector {
|
|
|
wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
|
|
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) {
|
|
private static Flowable<ImageFile> detectMeizuGalleryCache(Context context, XFile xFile) {
|
|
|
return new GenericImgCollectionDetector(context, xFile, ImageFile.CATEGORY_GALLERY)
|
|
return new GenericImgCollectionDetector(context, xFile, ImageFile.CATEGORY_GALLERY)
|
|
|
.subscribeOn(Schedulers.io())
|
|
.subscribeOn(Schedulers.io())
|
|
@@ -218,25 +266,27 @@ public class ImageDeepDetector {
|
|
|
}
|
|
}
|
|
|
} catch (Exception ignore) {
|
|
} catch (Exception ignore) {
|
|
|
}
|
|
}
|
|
|
- if (hasJpgMagic(file)) {
|
|
|
|
|
- file.setTag(JPG_MAGIC);
|
|
|
|
|
|
|
+ if (hasImgMagic(file)) {
|
|
|
|
|
+ file.setTag(IMG_MAGIC);
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static boolean hasJpgMagic(XFile file) {
|
|
|
|
|
|
|
+ private static boolean hasImgMagic(XFile file) {
|
|
|
try (InputStream inputStream = file.newInputStream()) {
|
|
try (InputStream inputStream = file.newInputStream()) {
|
|
|
- if (inputStream.available() < 4) {
|
|
|
|
|
|
|
+ byte[] bytes = new byte[8];
|
|
|
|
|
+ if (inputStream.read(bytes) != 8) {
|
|
|
return false;
|
|
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) {
|
|
if (!hasHeaderMagic) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|