11package com .simplemobiletools .camera .activities ;
22
33import android .Manifest ;
4+ import android .content .ActivityNotFoundException ;
5+ import android .content .ContentResolver ;
46import android .content .Intent ;
57import android .content .pm .PackageManager ;
68import android .content .res .Resources ;
9+ import android .database .Cursor ;
10+ import android .graphics .Bitmap ;
11+ import android .graphics .Matrix ;
712import android .hardware .Camera ;
813import android .hardware .Sensor ;
914import android .hardware .SensorEvent ;
1015import android .hardware .SensorEventListener ;
1116import android .hardware .SensorManager ;
17+ import android .media .MediaScannerConnection ;
1218import android .net .Uri ;
1319import android .os .Bundle ;
1420import android .os .Handler ;
4147import butterknife .ButterKnife ;
4248import butterknife .OnClick ;
4349
44- public class MainActivity extends AppCompatActivity implements SensorEventListener , PreviewListener , PhotoProcessor .MediaSavedListener {
50+ public class MainActivity extends AppCompatActivity
51+ implements SensorEventListener , PreviewListener , PhotoProcessor .MediaSavedListener , MediaScannerConnection .OnScanCompletedListener {
4552 @ BindView (R .id .viewHolder ) RelativeLayout mViewHolder ;
4653 @ BindView (R .id .toggle_camera ) ImageView mToggleCameraBtn ;
4754 @ BindView (R .id .toggle_flash ) ImageView mToggleFlashBtn ;
4855 @ BindView (R .id .toggle_photo_video ) ImageView mTogglePhotoVideoBtn ;
4956 @ BindView (R .id .shutter ) ImageView mShutterBtn ;
5057 @ BindView (R .id .video_rec_curr_timer ) TextView mRecCurrTimer ;
5158 @ BindView (R .id .about ) View mAboutBtn ;
59+ @ BindView (R .id .last_photo_video_preview ) ImageView mLastPhotoVideoPreview ;
5260
61+ private static final String TAG = MainActivity .class .getSimpleName ();
5362 private static final int CAMERA_STORAGE_PERMISSION = 1 ;
5463 private static final int AUDIO_PERMISSION = 2 ;
5564
5665 private static SensorManager mSensorManager ;
5766 private static Preview mPreview ;
5867 private static Handler mTimerHandler ;
68+ private static Uri mPreviewUri ;
5969
6070 private static boolean mIsFlashEnabled ;
6171 private static boolean mIsInPhotoMode ;
@@ -153,6 +163,7 @@ private void initializeCamera() {
153163 mSensorManager = (SensorManager ) getSystemService (SENSOR_SERVICE );
154164 mIsInPhotoMode = true ;
155165 mTimerHandler = new Handler ();
166+ setupPreviewImage (true );
156167 }
157168
158169 private boolean hasCameraAndStoragePermission () {
@@ -209,6 +220,25 @@ public void toggleCamera() {
209220 }
210221 }
211222
223+ @ OnClick (R .id .last_photo_video_preview )
224+ public void showLastMediaPreview () {
225+ if (mPreviewUri == null )
226+ return ;
227+
228+ try {
229+ final String REVIEW_ACTION = "com.android.camera.action.REVIEW" ;
230+ Intent intent = new Intent (REVIEW_ACTION , mPreviewUri );
231+ this .startActivity (intent );
232+ } catch (ActivityNotFoundException e ) {
233+ Intent intent = new Intent (Intent .ACTION_VIEW , mPreviewUri );
234+ if (intent .resolveActivity (getPackageManager ()) != null ) {
235+ startActivity (intent );
236+ } else {
237+ Utils .showToast (getApplicationContext (), R .string .no_gallery_app_available );
238+ }
239+ }
240+ }
241+
212242 @ OnClick (R .id .toggle_flash )
213243 public void toggleFlash () {
214244 if (!checkCameraAvailable ()) {
@@ -304,7 +334,7 @@ private void checkButtons() {
304334 if (mIsInPhotoMode ) {
305335 initPhotoButtons ();
306336 } else {
307- initVideoButtons ();
337+ tryInitVideoButtons ();
308338 }
309339 }
310340
@@ -313,24 +343,101 @@ private void initPhotoButtons() {
313343 mTogglePhotoVideoBtn .setImageDrawable (res .getDrawable (R .mipmap .videocam ));
314344 mShutterBtn .setImageDrawable (res .getDrawable (R .mipmap .camera ));
315345 mPreview .initPhotoMode ();
346+ setupPreviewImage (true );
316347 }
317348
318- private void initVideoButtons () {
349+ private void tryInitVideoButtons () {
319350 if (mPreview .initRecorder ()) {
320- setupVideoIcons ();
351+ initVideoButtons ();
321352 } else {
322353 if (!mIsVideoCaptureIntent ) {
323354 Utils .showToast (getApplicationContext (), R .string .video_mode_error );
324355 }
325356 }
326357 }
327358
328- private void setupVideoIcons () {
359+ private void initVideoButtons () {
329360 final Resources res = getResources ();
330361 mTogglePhotoVideoBtn .setImageDrawable (res .getDrawable (R .mipmap .photo ));
331362 mToggleCameraBtn .setVisibility (View .VISIBLE );
332363 mShutterBtn .setImageDrawable (res .getDrawable (R .mipmap .video_rec ));
333364 checkFlash ();
365+ setupPreviewImage (false );
366+ }
367+
368+ private void setupPreviewImage (boolean isPhoto ) {
369+ final Uri uri = (isPhoto ) ? MediaStore .Images .Media .EXTERNAL_CONTENT_URI : MediaStore .Video .Media .EXTERNAL_CONTENT_URI ;
370+ final long lastMediaId = getLastMediaId (uri );
371+ if (lastMediaId == 0 ) {
372+ return ;
373+ }
374+ final ContentResolver cr = getContentResolver ();
375+ mPreviewUri = Uri .withAppendedPath (uri , String .valueOf (lastMediaId ));
376+ Bitmap tmb ;
377+
378+ if (isPhoto ) {
379+ tmb = MediaStore .Images .Thumbnails .getThumbnail (cr , lastMediaId , MediaStore .Images .Thumbnails .MICRO_KIND , null );
380+ final int rotationDegrees = getImageRotation ();
381+ tmb = rotateThumbnail (tmb , rotationDegrees );
382+ } else {
383+ tmb = MediaStore .Video .Thumbnails .getThumbnail (cr , lastMediaId , MediaStore .Video .Thumbnails .MICRO_KIND , null );
384+ }
385+
386+ setPreviewImage (tmb );
387+ }
388+
389+ private int getImageRotation () {
390+ final String [] projection = {MediaStore .Images .ImageColumns .ORIENTATION };
391+ Cursor cursor = null ;
392+ try {
393+ cursor = getContentResolver ().query (MediaStore .Images .Media .EXTERNAL_CONTENT_URI , projection , null , null , null );
394+ if (cursor != null && cursor .moveToFirst ()) {
395+ final int orientationIndex = cursor .getColumnIndex (MediaStore .Images .ImageColumns .ORIENTATION );
396+ return cursor .getInt (orientationIndex );
397+ }
398+ } finally {
399+ if (cursor != null ) {
400+ cursor .close ();
401+ }
402+ }
403+ return 0 ;
404+ }
405+
406+ private Bitmap rotateThumbnail (Bitmap tmb , int degrees ) {
407+ if (degrees == 0 )
408+ return tmb ;
409+
410+ final Matrix matrix = new Matrix ();
411+ matrix .setRotate (degrees , tmb .getWidth () / 2 , tmb .getHeight () / 2 );
412+ return Bitmap .createBitmap (tmb , 0 , 0 , tmb .getWidth (), tmb .getHeight (), matrix , true );
413+ }
414+
415+ private void setPreviewImage (final Bitmap bmp ) {
416+ if (bmp != null ) {
417+ mLastPhotoVideoPreview .post (new Runnable () {
418+ @ Override
419+ public void run () {
420+ mLastPhotoVideoPreview .setImageBitmap (bmp );
421+ }
422+ });
423+ }
424+ }
425+
426+ private long getLastMediaId (Uri uri ) {
427+ final String [] projection = {MediaStore .Images .ImageColumns ._ID };
428+ Cursor cursor = null ;
429+ try {
430+ cursor = getContentResolver ().query (uri , projection , null , null , MediaStore .Images .ImageColumns .DATE_TAKEN + " DESC" );
431+ if (cursor != null && cursor .moveToFirst ()) {
432+ final int idIndex = cursor .getColumnIndex (MediaStore .Images .ImageColumns ._ID );
433+ return cursor .getLong (idIndex );
434+ }
435+ } finally {
436+ if (cursor != null ) {
437+ cursor .close ();
438+ }
439+ }
440+ return 0 ;
334441 }
335442
336443 private void hideNavigationBarIcons () {
@@ -364,6 +471,7 @@ protected void onResume() {
364471 super .onResume ();
365472 if (hasCameraAndStoragePermission ()) {
366473 resumeCameraItems ();
474+ setupPreviewImage (mIsInPhotoMode );
367475
368476 if (mIsVideoCaptureIntent && mIsInPhotoMode ) {
369477 togglePhotoVideo ();
@@ -387,7 +495,7 @@ private void resumeCameraItems() {
387495 }
388496
389497 if (!mIsInPhotoMode ) {
390- setupVideoIcons ();
498+ initVideoButtons ();
391499 }
392500 } else {
393501 Utils .showToast (getApplicationContext (), R .string .camera_switch_error );
@@ -461,6 +569,7 @@ public int getCurrentOrientation() {
461569
462570 @ Override
463571 public void videoSaved (Uri uri ) {
572+ setupPreviewImage (mIsInPhotoMode );
464573 if (mIsVideoCaptureIntent ) {
465574 final Intent intent = new Intent ();
466575 intent .setData (uri );
@@ -471,7 +580,10 @@ public void videoSaved(Uri uri) {
471580 }
472581
473582 @ Override
474- public void mediaSaved () {
583+ public void mediaSaved (String path ) {
584+ final String [] paths = {path };
585+ MediaScannerConnection .scanFile (getApplicationContext (), paths , null , this );
586+
475587 if (mIsImageCaptureIntent ) {
476588 setResult (RESULT_OK );
477589 finish ();
@@ -485,4 +597,9 @@ protected void onDestroy() {
485597 if (mPreview != null )
486598 mPreview .releaseCamera ();
487599 }
600+
601+ @ Override
602+ public void onScanCompleted (String path , Uri uri ) {
603+ setupPreviewImage (mIsInPhotoMode );
604+ }
488605}
0 commit comments