Browse Source

优化图片清除逻辑

zk 1 year ago
parent
commit
68e6252d1b

+ 0 - 1
app/src/main/java/com/datarecovery/master/data/api/bean/MemberGoodsBean.java

@@ -1,6 +1,5 @@
 package com.datarecovery.master.data.api.bean;
 
-import android.graphics.drawable.Drawable;
 
 import androidx.databinding.BaseObservable;
 import androidx.databinding.Bindable;

+ 115 - 64
app/src/main/java/com/datarecovery/master/module/imgrecover/ImageRecoverViewModel.java

@@ -51,8 +51,10 @@ import atmob.reactivex.rxjava3.annotations.NonNull;
 import atmob.reactivex.rxjava3.core.FlowableSubscriber;
 import atmob.reactivex.rxjava3.core.Single;
 import atmob.reactivex.rxjava3.core.SingleObserver;
+import atmob.reactivex.rxjava3.core.SingleOnSubscribe;
 import atmob.reactivex.rxjava3.core.SingleSource;
 import atmob.reactivex.rxjava3.disposables.Disposable;
+import atmob.reactivex.rxjava3.schedulers.Schedulers;
 import atmob.rxjava.utils.RxJavaUtil;
 import dagger.hilt.android.lifecycle.HiltViewModel;
 
@@ -424,14 +426,15 @@ public class ImageRecoverViewModel extends BaseViewModel {
                 .map(sdkInt -> sdkInt >= Build.VERSION_CODES.R)
                 .map(isSdk11 -> {
                     List<ImageDeepDetector.ImageFile> safList = new ArrayList<>();
-                    List<Uri> uriList = new ArrayList<>();
+                    List<ImageDeepDetector.ImageFile> uriList = new ArrayList<>();
                     if (isSdk11) {
                         for (ImageDeepDetector.ImageFile item : selectList) {
                             File tempFile = new File(item.getPath());
                             long mediaID = getFilePathToMediaID(tempFile.getAbsolutePath(), ContextUtil.getContext());
                             if (mediaID > 0) {
-                                Uri Uri_one = ContentUris.withAppendedId(MediaStore.Images.Media.getContentUri("external"), mediaID);
-                                uriList.add(Uri_one);
+                                Uri externalUri = ContentUris.withAppendedId(MediaStore.Images.Media.getContentUri("external"), mediaID);
+                                item.setExternalUri(externalUri);
+                                uriList.add(item);
                             } else {
                                 safList.add(item);
                             }
@@ -441,11 +444,77 @@ public class ImageRecoverViewModel extends BaseViewModel {
                     }
                     return new Pair<>(safList, uriList);
                 })
-                .map(pair -> {
-                    if (pair.first != null && !pair.first.isEmpty()) {
-                        for (ImageDeepDetector.ImageFile item : pair.first) {
+                .flatMap(pair -> Single.zip(
+                        imageDelete(pair.first).subscribeOn(Schedulers.io()),
+                        externalDelete(pair.second).subscribeOn(Schedulers.io()),
+                        Pair::new
+                ))
+                .compose(RxJavaUtil.SingleSchedule.io2Main())
+                .subscribe(new SingleObserver<Pair<Pair<ImageDeepDetector.ImageFile, Exception>, Pair<ImageDeepDetector.ImageFile, Exception>>>() {
+                    @Override
+                    public void onSubscribe(@NonNull Disposable d) {
+                        addDisposable(d);
+                        showLoadingEvent.setValue(true);
+                    }
+
+                    @Override
+                    public void onSuccess(@NonNull Pair<Pair<ImageDeepDetector.ImageFile, Exception>, Pair<ImageDeepDetector.ImageFile, Exception>> pairPairPair) {
+                        showLoadingEvent.setValue(false);
+                        if (pairPairPair.first.second != null) {
+                            ToastUtil.show("部分图片清除失败:" + pairPairPair.first.second.getMessage(), ToastUtil.LENGTH_SHORT);
+                            failScrollPosition.setValue(pairPairPair.first.first);
+                            return;
+                        }
+                        if (pairPairPair.second.second instanceof CancelDeleteException) {
+                            return;
+                        }
+                        if (pairPairPair.second.second != null) {
+                            ToastUtil.show("部分图片清除失败:" + pairPairPair.second.second.getMessage(), ToastUtil.LENGTH_SHORT);
+                            failScrollPosition.setValue(pairPairPair.second.first);
+                            return;
+                        }
+                        if (pairPairPair.first.first == null && pairPairPair.second.first == null) {
+                            ToastUtil.show(R.string.delete_success, ToastUtil.LENGTH_SHORT);
+                        }
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable e) {
+                        showLoadingEvent.setValue(false);
+                        ToastUtil.show(R.string.delete_fail, ToastUtil.LENGTH_SHORT);
+                    }
+                });
+    }
+
+
+    private @NonNull Single<Pair<ImageDeepDetector.ImageFile, Exception>> externalDelete(List<ImageDeepDetector.ImageFile> externalList) {
+        return Single.create((SingleOnSubscribe<List<Uri>>) emitter -> {
+                    List<Uri> uriDeleteList = new ArrayList<>();
+                    if (externalList.isEmpty()) {
+                        emitter.onSuccess(uriDeleteList);
+                        return;
+                    }
+                    for (ImageDeepDetector.ImageFile item : externalList) {
+                        uriDeleteList.add(item.getExternalUri());
+                    }
+                    emitter.onSuccess(uriDeleteList);
+                })
+                .flatMap(uriDeleteList -> {
+                    if (!uriDeleteList.isEmpty()) {
+                        deleteUriListSdk11.postValue(uriDeleteList);
+                        return (SingleSource<Boolean>) observer -> this.dealMediaObserver = observer;
+                    } else {
+                        return Single.just(true);
+                    }
+                })
+                .flatMap(state -> {
+                    if (BoxingUtil.boxing(state)) {
+                        Exception exception = null;
+                        ImageDeepDetector.ImageFile deleteError = null;
+                        for (ImageDeepDetector.ImageFile item : externalList) {
                             try {
                                 item.delete();
+                                selectList.remove(item);
                                 if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
                                     detectedPhotoList.remove(item);
                                 } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_WECHAT) {
@@ -455,75 +524,57 @@ public class ImageRecoverViewModel extends BaseViewModel {
                                 } else {
                                     detectedOtherList.remove(item);
                                 }
-                            } catch (Exception ignore) {
+                            } catch (Exception throwable) {
+                                exception = throwable;
+                                deleteError = item;
+                                BuglyHelper.postCatchedException(new Exception("图片删除External:", throwable));
                             }
                         }
-                        selectList.removeAll(pair.first);
                         selectedList.postValue(selectList);
                         notifyList.postValue(null);
-                    }
-                    return pair.second;
-                })
-                .map(uriList -> {
-                    if (uriList != null && !uriList.isEmpty()) {
-                        deleteUriListSdk11.postValue(uriList);
-                        return false;
+                        return Single.just(new Pair<>(deleteError, exception));
                     } else {
-                        return true;
-                    }
-                })
-                .flatMap(aBoolean -> {
-                    if (BoxingUtil.boxing(aBoolean)) {
-                        return Single.just(true);
-                    } else {
-                        return (SingleSource<Boolean>) observer -> this.dealMediaObserver = observer;
-                    }
-                })
-                .compose(RxJavaUtil.SingleSchedule.io2Main())
-                .subscribe(new SingleObserver<Boolean>() {
-
-                    @Override
-                    public void onSubscribe(@NonNull Disposable d) {
-                        showLoadingEvent.setValue(true);
+                        return Single.just(new Pair<>(null, new CancelDeleteException()));
                     }
+                });
+    }
 
-                    @Override
-                    public void onSuccess(@NonNull Boolean result) {
-                        showLoadingEvent.setValue(false);
-                        if (result) {
-                            for (ImageDeepDetector.ImageFile item : selectList) {
-                                try {
-                                    item.delete();
-                                    if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
-                                        detectedPhotoList.remove(item);
-                                    } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_WECHAT) {
-                                        detectedWxList.remove(item);
-                                    } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_QQ) {
-                                        detectedQQList.remove(item);
-                                    } else {
-                                        detectedOtherList.remove(item);
-                                    }
-                                } catch (Exception ignore) {
-                                }
-                            }
-                            ToastUtil.show(R.string.delete_success, ToastUtil.LENGTH_SHORT);
-                            selectList.clear();
-                            selectedList.setValue(selectList);
-                            notifyList.call();
-                        }
-                        checkAll.setValue(false);
-                    }
+    private static class CancelDeleteException extends Exception {
+    }
 
-                    @Override
-                    public void onError(@NonNull Throwable throwable) {
-                        showLoadingEvent.setValue(false);
-                        ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
-                        BuglyHelper.postCatchedException(new Exception("图片删除:", throwable));
+    private Single<Pair<ImageDeepDetector.ImageFile, Exception>> imageDelete(List<ImageDeepDetector.ImageFile> safList) {
+        return Single.create(emitter -> {
+            Exception exception = null;
+            ImageDeepDetector.ImageFile deleteError = null;
+            if (safList.isEmpty()) {
+                emitter.onSuccess(new Pair<>(deleteError, exception));
+                return;
+            }
+            for (ImageDeepDetector.ImageFile item : safList) {
+                try {
+                    item.delete();
+                    selectList.remove(item);
+                    if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
+                        detectedPhotoList.remove(item);
+                    } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_WECHAT) {
+                        detectedWxList.remove(item);
+                    } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_QQ) {
+                        detectedQQList.remove(item);
+                    } else {
+                        detectedOtherList.remove(item);
                     }
-                });
+                } catch (Exception throwable) {
+                    exception = throwable;
+                    deleteError = item;
+                    BuglyHelper.postCatchedException(new Exception("图片删除:", throwable));
+                }
+            }
+            selectedList.postValue(selectList);
+            notifyList.postValue(null);
+            emitter.onSuccess(new Pair<>(deleteError, exception));
+        });
     }
 
-
     public long getFilePathToMediaID(String songPath, Context context) {
         long id = 0;
         ContentResolver cr = context.getContentResolver();

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

@@ -556,6 +556,8 @@ public class ImageDeepDetector {
 
         private boolean isTrial;
 
+        private Uri externalUri;
+
 
         public ImageFile(XFile xFile) {
             this(xFile, CATEGORY_UNKNOWN);
@@ -604,6 +606,14 @@ public class ImageDeepDetector {
                     '}';
         }
 
+        public Uri getExternalUri() {
+            return externalUri;
+        }
+
+        public void setExternalUri(Uri externalUri) {
+            this.externalUri = externalUri;
+        }
+
         @Bindable
         public boolean isTrial() {
             return isTrial;