PreviewActivity.java 11 KB

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