ImageRecoverViewModel.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. package com.datarecovery.master.module.imgrecover;
  2. import android.content.ContentResolver;
  3. import android.content.ContentUris;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.provider.MediaStore;
  9. import android.text.TextUtils;
  10. import android.util.Pair;
  11. import androidx.lifecycle.LiveData;
  12. import androidx.lifecycle.MutableLiveData;
  13. import androidx.lifecycle.Transformations;
  14. import com.atmob.app.lib.base.BaseViewModel;
  15. import com.atmob.app.lib.livedata.SingleLiveEvent;
  16. import com.atmob.common.logging.AtmobLog;
  17. import com.atmob.common.runtime.ActivityUtil;
  18. import com.atmob.common.runtime.ContextUtil;
  19. import com.datarecovery.master.R;
  20. import com.datarecovery.master.data.consts.EventId;
  21. import com.datarecovery.master.data.repositories.DeviceFuncRepository;
  22. import com.datarecovery.master.handler.EventHelper;
  23. import com.datarecovery.master.module.member.MemberActivity;
  24. import com.datarecovery.master.module.member.MemberType;
  25. import com.datarecovery.master.sdk.bugly.BuglyHelper;
  26. import com.datarecovery.master.utils.BoxingUtil;
  27. import com.datarecovery.master.utils.FileUtil;
  28. import com.datarecovery.master.utils.ImageDeepDetector;
  29. import com.datarecovery.master.utils.Maps;
  30. import com.datarecovery.master.utils.MediaStoreHelper;
  31. import com.datarecovery.master.utils.ReportUtil;
  32. import com.datarecovery.master.utils.ToastUtil;
  33. import org.reactivestreams.Subscription;
  34. import java.io.File;
  35. import java.util.ArrayList;
  36. import java.util.List;
  37. import java.util.Objects;
  38. import java.util.concurrent.TimeUnit;
  39. import javax.inject.Inject;
  40. import atmob.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
  41. import atmob.reactivex.rxjava3.annotations.NonNull;
  42. import atmob.reactivex.rxjava3.core.FlowableSubscriber;
  43. import atmob.reactivex.rxjava3.core.Single;
  44. import atmob.reactivex.rxjava3.core.SingleObserver;
  45. import atmob.reactivex.rxjava3.core.SingleSource;
  46. import atmob.reactivex.rxjava3.disposables.Disposable;
  47. import atmob.rxjava.utils.RxJavaUtil;
  48. import dagger.hilt.android.lifecycle.HiltViewModel;
  49. @HiltViewModel
  50. public class ImageRecoverViewModel extends BaseViewModel {
  51. private final long SCANNING_COUNTDOWN = 1000 * 60 * 6;
  52. private final long SCANNING_IS_TRIAL_COUNTDOWN = 1000 * 5;
  53. private final List<ImageDeepDetector.ImageFile> detectedPhotoList = new ArrayList<>();
  54. private final List<ImageDeepDetector.ImageFile> detectedWxList = new ArrayList<>();
  55. private final List<ImageDeepDetector.ImageFile> detectedQQList = new ArrayList<>();
  56. private final List<ImageDeepDetector.ImageFile> detectedOtherList = new ArrayList<>();
  57. private final List<ImageDeepDetector.ImageFile> selectList = new ArrayList<>();
  58. private final MutableLiveData<List<ImageDeepDetector.ImageFile>> detectedPhotoImg = new MutableLiveData<>();
  59. private final MutableLiveData<List<ImageDeepDetector.ImageFile>> detectedWxImg = new MutableLiveData<>();
  60. private final MutableLiveData<List<ImageDeepDetector.ImageFile>> detectedQQImg = new MutableLiveData<>();
  61. private final MutableLiveData<List<ImageDeepDetector.ImageFile>> detectedOtherImg = new MutableLiveData<>();
  62. private final MutableLiveData<List<ImageDeepDetector.ImageFile>> selectedList = new MutableLiveData<>();
  63. private final SingleLiveEvent<List<Uri>> deleteUriListSdk11 = new SingleLiveEvent<>();
  64. private final SingleLiveEvent<?> showTrialFinishDialog = new SingleLiveEvent<>();
  65. private final SingleLiveEvent<?> showTrialExportFailDialog = new SingleLiveEvent<>();
  66. private final MutableLiveData<Boolean> showTrialView = new MutableLiveData<>();
  67. private final DeviceFuncRepository deviceFuncRepository;
  68. private LiveData<String> detectedPhotoTitle;
  69. private LiveData<String> detectedWxTitle;
  70. private LiveData<String> detectedQQTitle;
  71. private LiveData<String> detectedOtherTitle;
  72. private final SingleLiveEvent<Pair<List<ImageDeepDetector.ImageFile>, Integer>> previewEvent = new SingleLiveEvent<>();
  73. private final SingleLiveEvent<?> showClearDialog = new SingleLiveEvent<>();
  74. private final SingleLiveEvent<Boolean> showScanDialogEvent = new SingleLiveEvent<>();
  75. private final SingleLiveEvent<Boolean> showLoadingEvent = new SingleLiveEvent<>();
  76. private final SingleLiveEvent<?> scrollTop = new SingleLiveEvent<>();
  77. private final SingleLiveEvent<?> notifyList = new SingleLiveEvent<>();
  78. private final MutableLiveData<String> barTitle = new MutableLiveData<>();
  79. private final MutableLiveData<Boolean> checkAll = new MutableLiveData<>(false);
  80. //总探测到的图片数量
  81. private int totalCount = 0;
  82. private final MutableLiveData<Integer> totalDetectedCount = new MutableLiveData<>();
  83. private final MutableLiveData<String> detectedLastFileName = new MutableLiveData<>();
  84. private LiveData<String> selectedCountTxt;
  85. private Disposable scanDisposable;
  86. @MemberType
  87. private String type;
  88. private SingleObserver<? super Boolean> dealMediaObserver;
  89. //是否会员试用
  90. private boolean isTrial;
  91. private long detectTime;
  92. @Inject
  93. public ImageRecoverViewModel(DeviceFuncRepository deviceFuncRepository) {
  94. this.deviceFuncRepository = deviceFuncRepository;
  95. barTitle.setValue(ContextUtil.getContext().getString(R.string.iamge_recover_all));
  96. initLiveData();
  97. }
  98. public LiveData<?> getScrollTop() {
  99. return scrollTop;
  100. }
  101. public LiveData<?> getShowTrialFinishDialog() {
  102. return showTrialFinishDialog;
  103. }
  104. public LiveData<?> getShowTrialExportFailDialog() {
  105. return showTrialExportFailDialog;
  106. }
  107. public LiveData<String> getDetectedLastFileName() {
  108. return detectedLastFileName;
  109. }
  110. public LiveData<Boolean> getShowTrialView() {
  111. return showTrialView;
  112. }
  113. public boolean isTrial() {
  114. if (Objects.equals(type, MemberType.APP_IMAGE_CLEAN)) {
  115. return !deviceFuncRepository.isHaveAuth(type);
  116. } else {
  117. return isTrial;
  118. }
  119. }
  120. public LiveData<List<Uri>> getDeleteUriListSdk11() {
  121. return deleteUriListSdk11;
  122. }
  123. public LiveData<?> getShowClearDialog() {
  124. return showClearDialog;
  125. }
  126. public LiveData<?> getNotifyList() {
  127. return notifyList;
  128. }
  129. public LiveData<Boolean> getShowLoadingEvent() {
  130. return showLoadingEvent;
  131. }
  132. public LiveData<Pair<List<ImageDeepDetector.ImageFile>, Integer>> getPreviewEvent() {
  133. return previewEvent;
  134. }
  135. public LiveData<Integer> getTotalDetectedCount() {
  136. return totalDetectedCount;
  137. }
  138. public LiveData<String> getSelectedCountTxt() {
  139. return selectedCountTxt;
  140. }
  141. public LiveData<List<ImageDeepDetector.ImageFile>> getSelectedList() {
  142. return selectedList;
  143. }
  144. public LiveData<List<ImageDeepDetector.ImageFile>> getDetectedPhotoImg() {
  145. return detectedPhotoImg;
  146. }
  147. public LiveData<List<ImageDeepDetector.ImageFile>> getDetectedWxImg() {
  148. return detectedWxImg;
  149. }
  150. public LiveData<List<ImageDeepDetector.ImageFile>> getDetectedQQImg() {
  151. return detectedQQImg;
  152. }
  153. public LiveData<List<ImageDeepDetector.ImageFile>> getDetectedOtherImg() {
  154. return detectedOtherImg;
  155. }
  156. public LiveData<String> getDetectedPhotoTitle() {
  157. return detectedPhotoTitle;
  158. }
  159. public LiveData<String> getDetectedWxTitle() {
  160. return detectedWxTitle;
  161. }
  162. public LiveData<String> getDetectedQQTitle() {
  163. return detectedQQTitle;
  164. }
  165. public LiveData<String> getDetectedOtherTitle() {
  166. return detectedOtherTitle;
  167. }
  168. public LiveData<Boolean> getShowScanDialogEvent() {
  169. return showScanDialogEvent;
  170. }
  171. public LiveData<Boolean> getCheckAll() {
  172. return checkAll;
  173. }
  174. public LiveData<String> getBarTitle() {
  175. return barTitle;
  176. }
  177. public String getType() {
  178. return type;
  179. }
  180. private void initLiveData() {
  181. detectedPhotoTitle = Transformations.map(detectedPhotoImg, list ->
  182. ContextUtil.getContext().getString(R.string.photo_count, (list == null || list.isEmpty()) ? 0 : list.size()));
  183. detectedWxTitle = Transformations.map(detectedWxImg, list ->
  184. ContextUtil.getContext().getString(R.string.wx_count, (list == null || list.isEmpty()) ? 0 : list.size()));
  185. detectedQQTitle = Transformations.map(detectedQQImg, list ->
  186. ContextUtil.getContext().getString(R.string.qq_count, (list == null || list.isEmpty()) ? 0 : list.size()));
  187. detectedOtherTitle = Transformations.map(detectedOtherImg, list ->
  188. ContextUtil.getContext().getString(R.string.other_count, (list == null || list.isEmpty()) ? 0 : list.size()));
  189. }
  190. public void onCheckAllClick(boolean isCheck) {
  191. checkAll.setValue(isCheck);
  192. setListCheck(detectedPhotoList, isCheck);
  193. setListCheck(detectedWxList, isCheck);
  194. setListCheck(detectedQQList, isCheck);
  195. setListCheck(detectedOtherList, isCheck);
  196. if (isCheck) {
  197. selectList.clear();
  198. selectList.addAll(detectedPhotoList);
  199. selectList.addAll(detectedWxList);
  200. selectList.addAll(detectedQQList);
  201. selectList.addAll(detectedOtherList);
  202. } else {
  203. selectList.clear();
  204. }
  205. selectedList.setValue(selectList);
  206. }
  207. private void setListCheck(List<ImageDeepDetector.ImageFile> list, boolean isCheck) {
  208. if (list == null || list.isEmpty()) {
  209. return;
  210. }
  211. for (ImageDeepDetector.ImageFile imageFile : list) {
  212. imageFile.setCheck(isCheck);
  213. }
  214. }
  215. public void startImageScanning() {
  216. if (scanDisposable != null && !scanDisposable.isDisposed()) {
  217. return;
  218. }
  219. ImageDeepDetector.detect(ContextUtil.getContext())
  220. .take(isTrial ? SCANNING_IS_TRIAL_COUNTDOWN : SCANNING_COUNTDOWN, TimeUnit.MILLISECONDS)
  221. .observeOn(AndroidSchedulers.mainThread())
  222. .subscribe(new FlowableSubscriber<List<ImageDeepDetector.ImageFile>>() {
  223. @Override
  224. public void onSubscribe(@NonNull Subscription s) {
  225. s.request(Integer.MAX_VALUE);
  226. scanDisposable = Disposable.fromSubscription(s);
  227. addDisposable(scanDisposable);
  228. showScanDialogEvent.setValue(true);
  229. checkAll.setValue(false);
  230. totalCount = 0;
  231. totalDetectedCount.setValue(0);
  232. detectTime = System.currentTimeMillis();
  233. detectedPhotoList.clear();
  234. detectedWxList.clear();
  235. detectedQQList.clear();
  236. detectedOtherList.clear();
  237. selectList.clear();
  238. }
  239. @Override
  240. public void onNext(List<ImageDeepDetector.ImageFile> imageFiles) {
  241. if (imageFiles == null) {
  242. return;
  243. }
  244. totalCount += imageFiles.size();
  245. totalDetectedCount.setValue(totalCount);
  246. int photoCount = 0;
  247. int wxCount = 0;
  248. int qqCount = 0;
  249. int otherCount = 0;
  250. for (ImageDeepDetector.ImageFile imageFile : imageFiles) {
  251. if (imageFile.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
  252. detectedPhotoList.add(imageFile);
  253. photoCount++;
  254. } else if (imageFile.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_WECHAT) {
  255. detectedWxList.add(imageFile);
  256. wxCount++;
  257. } else if (imageFile.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_QQ) {
  258. detectedQQList.add(imageFile);
  259. qqCount++;
  260. } else {
  261. detectedOtherList.add(imageFile);
  262. otherCount++;
  263. }
  264. detectedLastFileName.setValue(imageFile.getName());
  265. }
  266. if (photoCount > 0) {
  267. detectedPhotoImg.setValue(detectedPhotoList);
  268. }
  269. if (wxCount > 0) {
  270. detectedWxImg.setValue(detectedWxList);
  271. }
  272. if (qqCount > 0) {
  273. detectedQQImg.setValue(detectedQQList);
  274. }
  275. if (otherCount > 0) {
  276. detectedOtherImg.setValue(detectedOtherList);
  277. }
  278. scrollTop.call();
  279. }
  280. @Override
  281. public void onError(Throwable t) {
  282. showScanDialogEvent.setValue(false);
  283. }
  284. @Override
  285. public void onComplete() {
  286. setFreeExport();
  287. AtmobLog.d("ImageRecoverViewModel", System.currentTimeMillis() - detectTime + "ms - " + totalCount);
  288. if (isTrial) {
  289. showTrialFinishDialog.call();
  290. }
  291. showScanDialogEvent.setValue(false);
  292. }
  293. });
  294. }
  295. private void setFreeExport() {
  296. if (isTrial) {
  297. showTrialView.setValue(true);
  298. if (!detectedPhotoList.isEmpty()) {
  299. detectedPhotoList.get(0).setTrial(true);
  300. return;
  301. }
  302. if (!detectedWxList.isEmpty()) {
  303. detectedWxList.get(0).setTrial(true);
  304. return;
  305. }
  306. if (!detectedQQList.isEmpty()) {
  307. detectedQQList.get(0).setTrial(true);
  308. return;
  309. }
  310. if (!detectedOtherList.isEmpty()) {
  311. detectedOtherList.get(0).setTrial(true);
  312. return;
  313. }
  314. }
  315. }
  316. public void cancelScan() {
  317. if (scanDisposable != null) scanDisposable.dispose();
  318. showScanDialogEvent.setValue(false);
  319. setFreeExport();
  320. }
  321. public void setItemCheck(@NonNull ImageDeepDetector.ImageFile imageFile) {
  322. imageFile.setCheck(!imageFile.isCheck());
  323. if (imageFile.isCheck()) {
  324. selectList.add(imageFile);
  325. } else {
  326. selectList.remove(imageFile);
  327. }
  328. selectedList.setValue(selectList);
  329. }
  330. public void checkPreview(@NonNull ImageDeepDetector.ImageFile imageFile) {
  331. if (isTrial) {
  332. sendPreviewEvent(imageFile);
  333. return;
  334. }
  335. if (Objects.equals(type, MemberType.APP_IMAGE_CLEAN)) {
  336. return;
  337. }
  338. if (Objects.equals(type, MemberType.APP_IMAGE_RECOVER) && !deviceFuncRepository.isHaveAuth(type)) {
  339. return;
  340. } else if (Objects.equals(type, MemberType.APP_IMAGE_CLEAN) && !deviceFuncRepository.isHaveAuth(type)) {
  341. return;
  342. }
  343. sendPreviewEvent(imageFile);
  344. }
  345. public void sendPreviewEvent(@NonNull ImageDeepDetector.ImageFile imageFile) {
  346. List<ImageDeepDetector.ImageFile> allDetectedList = getAllDetectedList();
  347. int position = getPosition(allDetectedList, imageFile);
  348. previewEvent.setValue(new Pair<>(allDetectedList, position));
  349. }
  350. public void onOperationClick() {
  351. if (Objects.equals(type, MemberType.APP_IMAGE_CLEAN)) {
  352. if (deviceFuncRepository.isHaveAuth(type)) {
  353. showClearDialog.call();
  354. } else {
  355. MemberActivity.start(ActivityUtil.getTopActivity(), type);
  356. }
  357. } else {
  358. onExportClick();
  359. }
  360. }
  361. public void executeImageDelete() {
  362. if (selectList.isEmpty()) {
  363. return;
  364. }
  365. Single.just(Build.VERSION.SDK_INT)
  366. .map(sdkInt -> sdkInt >= Build.VERSION_CODES.R)
  367. .map(isSdk11 -> {
  368. List<ImageDeepDetector.ImageFile> safList = new ArrayList<>();
  369. List<Uri> uriList = new ArrayList<>();
  370. if (isSdk11) {
  371. for (ImageDeepDetector.ImageFile item : selectList) {
  372. File tempFile = new File(item.getPath());
  373. long mediaID = getFilePathToMediaID(tempFile.getAbsolutePath(), ContextUtil.getContext());
  374. if (mediaID > 0) {
  375. Uri Uri_one = ContentUris.withAppendedId(MediaStore.Images.Media.getContentUri("external"), mediaID);
  376. uriList.add(Uri_one);
  377. } else {
  378. safList.add(item);
  379. }
  380. }
  381. } else {
  382. safList.addAll(selectList);
  383. }
  384. return new Pair<>(safList, uriList);
  385. })
  386. .map(pair -> {
  387. if (pair.first != null && !pair.first.isEmpty()) {
  388. for (ImageDeepDetector.ImageFile item : pair.first) {
  389. try {
  390. item.delete();
  391. if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
  392. detectedPhotoList.remove(item);
  393. } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_WECHAT) {
  394. detectedWxList.remove(item);
  395. } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_QQ) {
  396. detectedQQList.remove(item);
  397. } else {
  398. detectedOtherList.remove(item);
  399. }
  400. } catch (Exception ignore) {
  401. }
  402. }
  403. selectList.removeAll(pair.first);
  404. selectedList.postValue(selectList);
  405. notifyList.postValue(null);
  406. }
  407. return pair.second;
  408. })
  409. .map(uriList -> {
  410. if (uriList != null && !uriList.isEmpty()) {
  411. deleteUriListSdk11.postValue(uriList);
  412. return false;
  413. } else {
  414. return true;
  415. }
  416. })
  417. .flatMap(aBoolean -> {
  418. if (BoxingUtil.boxing(aBoolean)) {
  419. return Single.just(true);
  420. } else {
  421. return (SingleSource<Boolean>) observer -> this.dealMediaObserver = observer;
  422. }
  423. })
  424. .compose(RxJavaUtil.SingleSchedule.io2Main())
  425. .subscribe(new SingleObserver<Boolean>() {
  426. @Override
  427. public void onSubscribe(@NonNull Disposable d) {
  428. showLoadingEvent.setValue(true);
  429. }
  430. @Override
  431. public void onSuccess(@NonNull Boolean result) {
  432. showLoadingEvent.setValue(false);
  433. if (result) {
  434. for (ImageDeepDetector.ImageFile item : selectList) {
  435. try {
  436. item.delete();
  437. if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
  438. detectedPhotoList.remove(item);
  439. } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_WECHAT) {
  440. detectedWxList.remove(item);
  441. } else if (item.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_QQ) {
  442. detectedQQList.remove(item);
  443. } else {
  444. detectedOtherList.remove(item);
  445. }
  446. } catch (Exception ignore) {
  447. }
  448. }
  449. ToastUtil.show(R.string.delete_success, ToastUtil.LENGTH_SHORT);
  450. selectList.clear();
  451. selectedList.setValue(selectList);
  452. notifyList.call();
  453. }
  454. checkAll.setValue(false);
  455. }
  456. @Override
  457. public void onError(@NonNull Throwable throwable) {
  458. showLoadingEvent.setValue(false);
  459. ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
  460. BuglyHelper.postCatchedException(new Exception("图片删除:", throwable));
  461. }
  462. });
  463. }
  464. public long getFilePathToMediaID(String songPath, Context context) {
  465. long id = 0;
  466. ContentResolver cr = context.getContentResolver();
  467. Uri uri = MediaStore.Files.getContentUri("external");
  468. String selection = MediaStore.Audio.Media.DATA;
  469. String[] selectionArgs = {songPath};
  470. String[] projection = {MediaStore.Audio.Media._ID};
  471. String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
  472. Cursor cursor = cr.query(uri, projection, selection + "=?", selectionArgs, null);
  473. if (cursor != null) {
  474. while (cursor.moveToNext()) {
  475. int idIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
  476. id = Long.parseLong(cursor.getString(idIndex));
  477. }
  478. }
  479. return id;
  480. }
  481. public void onExportClick() {
  482. if (selectList.isEmpty()) {
  483. return;
  484. }
  485. if (isTrial) {
  486. for (ImageDeepDetector.ImageFile imageFile : selectList) {
  487. if (!imageFile.isTrial()) {
  488. showTrialExportFailDialog.call();
  489. return;
  490. }
  491. }
  492. } else {
  493. if (Objects.equals(type, MemberType.APP_IMAGE_RECOVER) && !deviceFuncRepository.isHaveAuth(type)) {
  494. return;
  495. } else if (Objects.equals(type, MemberType.APP_IMAGE_CLEAN) && !deviceFuncRepository.isHaveAuth(type)) {
  496. return;
  497. }
  498. }
  499. showLoadingEvent.setValue(true);
  500. RxJavaUtil.doInBackground(() -> {
  501. for (ImageDeepDetector.ImageFile item : selectList) {
  502. MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_IMAGE, item.newInputStream(), FileUtil.getExportImageFileName(item.getName()));
  503. item.setCheck(false);
  504. }
  505. return true;
  506. }, o -> {
  507. checkAll.setValue(false);
  508. showLoadingEvent.setValue(false);
  509. ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
  510. selectList.clear();
  511. selectedList.setValue(selectList);
  512. }, throwable -> {
  513. showLoadingEvent.setValue(false);
  514. ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
  515. BuglyHelper.postCatchedException(new Exception("图片导出:", throwable));
  516. });
  517. }
  518. public List<ImageDeepDetector.ImageFile> getAllDetectedList() {
  519. ArrayList<ImageDeepDetector.ImageFile> allList = new ArrayList<>();
  520. allList.addAll(detectedPhotoList);
  521. allList.addAll(detectedWxList);
  522. allList.addAll(detectedQQList);
  523. allList.addAll(detectedOtherList);
  524. return allList;
  525. }
  526. public int getPosition(@NonNull List<ImageDeepDetector.ImageFile> list, ImageDeepDetector.ImageFile target) {
  527. return list.indexOf(target);
  528. }
  529. public void setType(@MemberType String type) {
  530. if (!TextUtils.isEmpty(this.type)) {
  531. return;
  532. }
  533. this.type = type;
  534. switch (type) {
  535. case MemberType.APP_IMAGE_CLEAN:
  536. EventHelper.report(EventId.hf1000514);
  537. EventHelper.timeEvent(EventId.hf1000529);
  538. selectedCountTxt = Transformations.map(selectedList, list -> {
  539. if (list == null || list.isEmpty()) {
  540. return ContextUtil.getContext().getString(R.string.delete);
  541. }
  542. return ContextUtil.getContext().getString(R.string.delete_count, list.size());
  543. });
  544. break;
  545. case MemberType.APP_IMAGE_RECOVER:
  546. EventHelper.report(EventId.hf1000506);
  547. EventHelper.timeEvent(EventId.hf1000521);
  548. selectedCountTxt = Transformations.map(selectedList, list -> {
  549. if (list == null || list.isEmpty()) {
  550. return ContextUtil.getContext().getString(R.string.export);
  551. }
  552. return ContextUtil.getContext().getString(R.string.export_count, list.size());
  553. });
  554. break;
  555. }
  556. }
  557. @Override
  558. protected void onCleared() {
  559. super.onCleared();
  560. switch (type) {
  561. case MemberType.APP_IMAGE_CLEAN:
  562. EventHelper.report(EventId.hf1000529);
  563. break;
  564. case MemberType.APP_IMAGE_RECOVER:
  565. EventHelper.report(EventId.hf1000521);
  566. break;
  567. }
  568. }
  569. public void callDealComplete(boolean isDelete) {
  570. if (dealMediaObserver != null) {
  571. dealMediaObserver.onSuccess(isDelete);
  572. }
  573. }
  574. public void setIsTrial(boolean isTrial) {
  575. this.isTrial = isTrial;
  576. }
  577. public void onTrialRecoverClick() {
  578. MemberActivity.start(ActivityUtil.getTopActivity(), type);
  579. }
  580. public void onViewTrialRecoverClick() {
  581. EventHelper.report(EventId.hf1001117, Maps.asMap(EventId.EVENT_ID, ReportUtil.getReportId(type)));
  582. MemberActivity.start(ActivityUtil.getTopActivity(), type);
  583. }
  584. public void scrollPosition(int lastCompletelyItemPosition, int itemCount) {
  585. if (scanDisposable == null || !scanDisposable.isDisposed()) {
  586. return;
  587. }
  588. if (lastCompletelyItemPosition == itemCount - 1 && !BoxingUtil.boxing(showScanDialogEvent.getValue())) {
  589. showTrialFinishDialog.call();
  590. EventHelper.report(EventId.hf1001119, Maps.asMap(EventId.EVENT_ID, ReportUtil.getReportId(type)));
  591. }
  592. }
  593. }