Dhaval2404 / ImagePicker

📸Image Picker for Android, Pick an image from Gallery or Capture a new image with Camera
Apache License 2.0
1.52k stars 339 forks source link

Wrong extension detection in FileUtil.getImageExtension(). OneDrive can't be used. #326

Open Andrew0000 opened 1 year ago

Andrew0000 commented 1 year ago

Summary

In case of gallery picking from cloud providers like GoogleDrive and OneDrive, FileUtil.getImageExtension() function detects wrong extensions. And it leads to an error in file creation in FileUtil.getImageFile(fileDir = mFileDir, extension = extension) in case of OneDrive (+ probably wrong file creation in case of GoogleDrive). It detects always jpg for GoogleDrive and something like com/Item/RID/C8BD%21119/Property/?RefreshOption=AutoRefresh&RefreshTimeOut=15000&CostAttributionKey=11-21-1 for OneDrive.

The stack of error:

java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
at java.io.File.createNewFile(File.java:1008)
at com.github.dhaval2404.imagepicker.util.FileUtil.getImageFile(FileUtil.kt:51)

// It invokes val extension = FileUtil.getImageExtension(uri)
at com.github.dhaval2404.imagepicker.provider.CropProvider.cropImage(CropProvider.kt:105) 

at com.github.dhaval2404.imagepicker.provider.CropProvider.startIntent(CropProvider.kt:95)
at com.github.dhaval2404.imagepicker.ImagePickerActivity.setImage(ImagePickerActivity.kt:128)
at com.github.dhaval2404.imagepicker.provider.GalleryProvider.handleResult(GalleryProvider.kt:75)
at com.github.dhaval2404.imagepicker.provider.GalleryProvider.onActivityResult(GalleryProvider.kt:61)
at com.github.dhaval2404.imagepicker.ImagePickerActivity.onActivityResult(ImagePickerActivity.kt:110)
at android.app.Activity.dispatchActivityResult(Activity.java:8516)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5188)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5236)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2187)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8057)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

Example of uri from OneDrive (modified a bit for security reason): content://com.microsoft.skydrive.content.StorageAccessProvider/document/content%3A%2F%2Fcom.microsoft.skydrive.content.metadata%2FDrive%2FRID%acc_name%2FItem%2FRID%2FC8%3FRefreshOption%3DAutoRefresh%26RefreshTimeOut%3D15000%26CostAttributionKey%3D11-21-1

Example of uri from GoogleDrive (modified a bit for security reason): content://com.google.android.apps.docs.storage/document/acc%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D

From the user perspective it leads to a toast: Failed to crop image and impossibility to pick an image from OneDrive.

Code to reproduce

Common code, nothing special.

Android version

Tested on android 11, but probably all versions are affected.

Impacted devices

Probably all android devices are affected.

Installation method

Gradle

SDK version

2.1

Andrew0000 commented 1 year ago

I suppose it can be fixed in the following ways: a) If uri has a content:// scheme - then FileUtil.getImageExtension() should use another extension detection algorithm

val mime = contentResolver.getType(uri)
val ext = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime)

b) Or maybe MediaStore.Images.Media.DISPLAY_NAME can be used.

Note: I haven't tested these approaches.

Andrew0000 commented 1 year ago

FYI: I made my own library, it works there: https://github.com/Andrew0000/ImagePickerPlus