PreviewActivity.java 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package com.datarecovery.master.module.preview;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.media.MediaPlayer;
  6. import android.net.Uri;
  7. import android.os.Bundle;
  8. import android.view.SurfaceHolder;
  9. import android.widget.SeekBar;
  10. import androidx.annotation.IntDef;
  11. import androidx.annotation.NonNull;
  12. import androidx.annotation.Nullable;
  13. import androidx.viewpager2.widget.ViewPager2;
  14. import com.atmob.app.lib.base.BaseActivity;
  15. import com.atmob.common.logging.AtmobLog;
  16. import com.atmob.common.ui.SizeUtil;
  17. import com.datarecovery.master.R;
  18. import com.datarecovery.master.databinding.ActivityPreviewBinding;
  19. import com.datarecovery.master.dialog.CommonSureDialog;
  20. import com.datarecovery.master.utils.FilesSearch;
  21. import com.datarecovery.master.utils.ImageDeepDetector;
  22. import com.datarecovery.master.utils.SafeMediaPlayer;
  23. import com.datarecovery.master.utils.ToastUtil;
  24. import com.gyf.immersionbar.ImmersionBar;
  25. import java.lang.ref.WeakReference;
  26. import java.util.List;
  27. import java.util.Timer;
  28. import java.util.TimerTask;
  29. import dagger.hilt.android.AndroidEntryPoint;
  30. @AndroidEntryPoint
  31. public class PreviewActivity extends BaseActivity<ActivityPreviewBinding> {
  32. public static final int TYPE_IMG = 1;
  33. public static final int TYPE_VIDEO = 2;
  34. public static final int TYPE_AUDIO = 3;
  35. private PreviewViewModel previewViewModel;
  36. private MediaPlayer mediaPlayer;
  37. private boolean isSurfaceCreated;
  38. private CommonSureDialog showTrialExportFailDialog;
  39. private ViewPager2.OnPageChangeCallback onPageChangeCallback;
  40. @IntDef({TYPE_IMG, TYPE_VIDEO, TYPE_AUDIO})
  41. @interface Type {
  42. }
  43. public static void startImagePreView(Context context, List<ImageDeepDetector.ImageFile> imageFileList, int position, boolean isTrial) {
  44. Intent intent = new Intent(context, PreviewActivity.class);
  45. intent.putExtra("type", TYPE_IMG);
  46. intent.putExtra("position", position);
  47. intent.putExtra("isTrial", isTrial);
  48. PreviewViewModel.weakReference = new WeakReference<>(imageFileList);
  49. if (!(context instanceof Activity)) {
  50. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  51. }
  52. context.startActivity(intent);
  53. }
  54. public static void startDocumentPreView(Context context, @Type int type, FilesSearch.DocumentFile documentFile, boolean isTrial) {
  55. Intent intent = new Intent(context, PreviewActivity.class);
  56. intent.putExtra("type", type);
  57. intent.putExtra("isTrial", isTrial);
  58. PreviewViewModel.weakReference = new WeakReference<>(documentFile);
  59. if (!(context instanceof Activity)) {
  60. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  61. }
  62. context.startActivity(intent);
  63. }
  64. @Override
  65. protected boolean shouldImmersion() {
  66. return true;
  67. }
  68. @Override
  69. protected void configImmersion(@NonNull ImmersionBar immersionBar) {
  70. immersionBar.statusBarDarkFont(true);
  71. }
  72. @Override
  73. protected void initViewModel() {
  74. previewViewModel = getViewModelProvider().get(PreviewViewModel.class);
  75. binding.setPreviewViewModel(previewViewModel);
  76. }
  77. @Override
  78. protected void onCreate(@Nullable Bundle savedInstanceState) {
  79. super.onCreate(savedInstanceState);
  80. initView();
  81. initIntentData();
  82. initObserver();
  83. }
  84. private void initObserver() {
  85. previewViewModel.getRefreshCurrentProgress().observe(this, o -> binding.previewAudioSeekbar.setProgress(mediaPlayer.getCurrentPosition()));
  86. previewViewModel.getShowTrialExportFailDialog().observe(this, o -> showTrialExportFailDialog());
  87. }
  88. private void showTrialExportFailDialog() {
  89. if (showTrialExportFailDialog == null) {
  90. showTrialExportFailDialog = new CommonSureDialog(this);
  91. showTrialExportFailDialog.setDialogTitle(R.string.trial_export_fail_title)
  92. .setDialogContent(R.string.trial_export_fail_content).setSureText(R.string.dialog_trial_recover);
  93. showTrialExportFailDialog.setOnDialogClickListener(() -> previewViewModel.onTrialRecoverClick());
  94. }
  95. showTrialExportFailDialog.show();
  96. }
  97. private void initIntentData() {
  98. int type = getIntent().getIntExtra("type", 0);
  99. int position = getIntent().getIntExtra("position", 0);
  100. boolean isTrial = getIntent().getBooleanExtra("isTrial", false);
  101. previewViewModel.setPreviewData(type, position, isTrial);
  102. if (type == TYPE_IMG) {
  103. initImagePreviewPager();
  104. } else {
  105. if (type == TYPE_VIDEO || type == TYPE_AUDIO) {
  106. initMediaPlayer(previewViewModel.getUri());
  107. }
  108. if (type == TYPE_VIDEO) {
  109. initSurfaceView();
  110. }
  111. }
  112. }
  113. private void initSeekBar() {
  114. binding.previewAudioSeekbar.setProgress(0);
  115. binding.previewAudioSeekbar.setMax(mediaPlayer.getDuration());
  116. binding.previewAudioSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
  117. @Override
  118. public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  119. if (fromUser) {
  120. mediaPlayer.seekTo(progress);
  121. }
  122. }
  123. @Override
  124. public void onStartTrackingTouch(SeekBar seekBar) {
  125. previewViewModel.setSeekbarChanging(true);
  126. }
  127. @Override
  128. public void onStopTrackingTouch(SeekBar seekBar) {
  129. previewViewModel.setSeekbarChanging(false);
  130. mediaPlayer.seekTo(seekBar.getProgress());
  131. }
  132. });
  133. previewViewModel.startMediaTimer();
  134. }
  135. private void initView() {
  136. binding.previewHeader.setNavigationOnClickListener(v -> finish());
  137. addTopStatusBarHeight(binding.previewHeader);
  138. binding.previewVideoContainer.setOnClickListener(v -> {
  139. if (isSurfaceCreated) {
  140. previewViewModel.setIsPlayStart();
  141. if (mediaPlayer.isPlaying()) {
  142. mediaPlayer.pause();
  143. } else {
  144. mediaPlayer.start();
  145. }
  146. previewViewModel.setIsPlaying(mediaPlayer.isPlaying());
  147. }
  148. });
  149. binding.previewAudioPlay.setOnClickListener(v -> {
  150. if (mediaPlayer.isPlaying()) {
  151. mediaPlayer.pause();
  152. } else {
  153. mediaPlayer.start();
  154. }
  155. previewViewModel.setIsPlaying(mediaPlayer.isPlaying());
  156. });
  157. }
  158. private void initImagePreviewPager() {
  159. PreviewImagePagerAdapter imagePagerAdapter = new PreviewImagePagerAdapter(previewViewModel.getImagePreviewList(), previewViewModel.isTrial());
  160. binding.previewViewPager.setAdapter(imagePagerAdapter);
  161. onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {
  162. @Override
  163. public void onPageSelected(int position) {
  164. previewViewModel.setPosition(position);
  165. }
  166. };
  167. binding.previewViewPager.registerOnPageChangeCallback(onPageChangeCallback);
  168. binding.previewViewPager.setCurrentItem(previewViewModel.getPosition(), false);
  169. }
  170. private void initSurfaceView() {
  171. SurfaceHolder holder = binding.previewVideo.getHolder();
  172. holder.addCallback(new SurfaceHolder.Callback() {
  173. @Override
  174. public void surfaceCreated(@NonNull SurfaceHolder holder) {
  175. mediaPlayer.setDisplay(holder);
  176. isSurfaceCreated = true;
  177. }
  178. @Override
  179. public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
  180. }
  181. @Override
  182. public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
  183. mediaPlayer.stop();
  184. mediaPlayer.setDisplay(null);
  185. }
  186. });
  187. }
  188. private void initMediaPlayer(Uri uri) {
  189. mediaPlayer = new SafeMediaPlayer();
  190. try {
  191. mediaPlayer.setDataSource(this, uri);
  192. mediaPlayer.setOnPreparedListener(mp -> {
  193. if (previewViewModel.getType() == TYPE_VIDEO) {
  194. int videoWidth = mediaPlayer.getVideoWidth();
  195. int screenWidth = SizeUtil.getScreenWidth();
  196. float scaleX = screenWidth / (videoWidth * 1f);
  197. int width = (int) (videoWidth * scaleX);
  198. int height = (int) (mediaPlayer.getVideoHeight() * scaleX);
  199. binding.previewVideo.resize(width, height);
  200. } else if (previewViewModel.getType() == TYPE_AUDIO) {
  201. initSeekBar();
  202. }
  203. });
  204. mediaPlayer.prepareAsync();
  205. mediaPlayer.setOnErrorListener((mp, what, extra) -> {
  206. ToastUtil.show(R.string.preview_source_error, ToastUtil.LENGTH_SHORT);
  207. return false;
  208. });
  209. mediaPlayer.setOnCompletionListener(mp -> {
  210. if (previewViewModel.getType() == TYPE_VIDEO) {
  211. previewViewModel.setIsPlaying(false);
  212. previewViewModel.setIsPlayStart(false);
  213. } else if (previewViewModel.getType() == TYPE_AUDIO) {
  214. mediaPlayer.seekTo(0);
  215. previewViewModel.setIsPlaying(false);
  216. }
  217. });
  218. } catch (Exception ignored) {
  219. }
  220. }
  221. @Override
  222. protected void onDestroy() {
  223. super.onDestroy();
  224. if (mediaPlayer != null) mediaPlayer.release();
  225. binding.previewViewPager.unregisterOnPageChangeCallback(onPageChangeCallback);
  226. }
  227. }