@@ -73,6 +73,7 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi
73
73
private static final String E_CAMERA_IS_NOT_AVAILABLE = "E_CAMERA_IS_NOT_AVAILABLE" ;
74
74
private static final String E_CANNOT_LAUNCH_CAMERA = "E_CANNOT_LAUNCH_CAMERA" ;
75
75
private static final String E_ERROR_WHILE_CLEANING_FILES = "E_ERROR_WHILE_CLEANING_FILES" ;
76
+ private static final String E_LOW_MEMORY_ERROR = "E_LOW_MEMORY_ERROR" ;
76
77
77
78
private static final String E_NO_LIBRARY_PERMISSION_KEY = "E_NO_LIBRARY_PERMISSION" ;
78
79
private static final String E_NO_LIBRARY_PERMISSION_MSG = "User did not grant library permission." ;
@@ -368,28 +369,21 @@ private void initiateCamera(Activity activity) {
368
369
private void initiatePicker (final Activity activity ) {
369
370
try {
370
371
PickVisualMediaRequest .Builder builder = new PickVisualMediaRequest .Builder ();
371
- PickVisualMediaRequest request = new PickVisualMediaRequest ();
372
-
373
- if (cropping || mediaType .equals ("photo" )) {
374
- request = builder .setMediaType (new ActivityResultContracts .PickVisualMedia .SingleMimeType ("image/*" )).build ();
375
- }
376
- else {
377
- if (cropping ) {
378
- request = builder .setMediaType (ActivityResultContracts .PickVisualMedia .ImageOnly .INSTANCE ).build ();
379
- }
380
- else if (mediaType .equals ("video" )) {
381
- request = builder .setMediaType (ActivityResultContracts .PickVisualMedia .VideoOnly .INSTANCE ).build ();
372
+ // Simplified media type handling
373
+ if (mediaType .equals ("video" )) {
374
+ builder .setMediaType (ActivityResultContracts .PickVisualMedia .VideoOnly .INSTANCE );
375
+ } else if (mediaType .equals ("photo" ) || cropping ) {
376
+ // Force image-only for cropping
377
+ builder .setMediaType (ActivityResultContracts .PickVisualMedia .ImageOnly .INSTANCE );
382
378
} else {
383
- request = builder .setMediaType (ActivityResultContracts .PickVisualMedia .ImageAndVideo .INSTANCE ).build ();
384
- }
379
+ builder .setMediaType (ActivityResultContracts .PickVisualMedia .ImageAndVideo .INSTANCE );
385
380
}
386
381
387
382
Intent intent ;
388
-
389
383
if (multiple ) {
390
- intent = new ActivityResultContracts .PickMultipleVisualMedia ().createIntent (activity , request );
384
+ intent = new ActivityResultContracts .PickMultipleVisualMedia ().createIntent (activity , builder . build () );
391
385
} else {
392
- intent = new ActivityResultContracts .PickVisualMedia ().createIntent (activity , request );
386
+ intent = new ActivityResultContracts .PickVisualMedia ().createIntent (activity , builder . build () );
393
387
}
394
388
395
389
activity .startActivityForResult (intent , IMAGE_PICKER_REQUEST );
@@ -515,15 +509,16 @@ private void getAsyncSelection(final Activity activity, Uri uri, boolean isCamer
515
509
resultCollector .notifySuccess (getImage (activity , path ));
516
510
}
517
511
518
- private Bitmap validateVideo (String path ) throws Exception {
512
+ private Bitmap validateVideo (Uri uri ) throws Exception {
519
513
MediaMetadataRetriever retriever = new MediaMetadataRetriever ();
520
- retriever .setDataSource (path );
514
+ retriever .setDataSource (getCurrentActivity (), uri );
521
515
Bitmap bmp = retriever .getFrameAtTime ();
522
516
523
517
if (bmp == null ) {
524
518
throw new Exception ("Cannot retrieve video data" );
525
519
}
526
520
521
+ retriever .release ();
527
522
return bmp ;
528
523
}
529
524
@@ -540,7 +535,7 @@ private static Long getVideoDuration(String path) {
540
535
}
541
536
542
537
private void getVideo (final Activity activity , final String path , final String mime ) throws Exception {
543
- validateVideo (path );
538
+ validateVideo (Uri . parse ( path ) );
544
539
final String compressedVideoPath = getTmpDir (activity ) + "/" + UUID .randomUUID ().toString () + ".mp4" ;
545
540
546
541
new Thread (new Runnable () {
@@ -550,21 +545,24 @@ public void run() {
550
545
@ Override
551
546
public void invoke (Object ... args ) {
552
547
String videoPath = (String ) args [0 ];
553
-
554
548
try {
555
- Bitmap bmp = validateVideo (videoPath );
556
- long modificationDate = new File (videoPath ).lastModified ();
549
+ File file = new File (videoPath );
550
+ Uri videoUri = Uri .fromFile (file );
551
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever ();
552
+ retriever .setDataSource (activity , videoUri );
553
+ Bitmap bmp = retriever .getFrameAtTime ();
557
554
long duration = getVideoDuration (videoPath );
558
555
559
556
WritableMap video = new WritableNativeMap ();
560
557
video .putInt ("width" , bmp .getWidth ());
561
558
video .putInt ("height" , bmp .getHeight ());
562
559
video .putString ("mime" , mime );
563
- video .putInt ("size" , (int ) new File ( videoPath ) .length ());
560
+ video .putInt ("size" , (int ) file .length ());
564
561
video .putInt ("duration" , (int ) duration );
565
562
video .putString ("path" , "file://" + videoPath );
566
- video .putString ("modificationDate" , String .valueOf (modificationDate ));
563
+ video .putString ("modificationDate" , String .valueOf (file . lastModified () ));
567
564
565
+ retriever .release ();
568
566
resultCollector .notifySuccess (video );
569
567
} catch (Exception e ) {
570
568
resultCollector .notifyProblem (E_NO_IMAGE_DATA_FOUND , e );
@@ -596,6 +594,11 @@ private String resolveRealPath(Activity activity, Uri uri, boolean isCamera) thr
596
594
}
597
595
598
596
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
597
+ // For videos, get the real path but don't copy the file
598
+ String mimeType = activity .getContentResolver ().getType (uri );
599
+ if (mimeType != null && mimeType .startsWith ("video/" )) {
600
+ return RealPathUtil .getRealPathFromURI (activity , uri );
601
+ }
599
602
600
603
String externalCacheDirPath = Uri .fromFile (activity .getExternalCacheDir ()).getPath ();
601
604
String externalFilesDirPath = Uri .fromFile (activity .getExternalFilesDir (null )).getPath ();
@@ -873,7 +876,12 @@ private void croppingResult(Activity activity, final int requestCode, final int
873
876
if (resultUri != null ) {
874
877
try {
875
878
if (width > 0 && height > 0 ) {
876
- File resized = compression .resize (this .reactContext , resultUri .getPath (), width , height , width , height , 100 );
879
+ File resized = null ;
880
+ try {
881
+ resized = compression .resize (this .reactContext , resultUri .getPath (), width , height , width , height , 100 );
882
+ } catch (OutOfMemoryError ex ) {
883
+ resultCollector .notifyProblem (E_LOW_MEMORY_ERROR , ex .getMessage ());
884
+ }
877
885
resultUri = Uri .fromFile (resized );
878
886
}
879
887
0 commit comments