Dhaval2404/ImagePicker

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

Andrew0000 opened this issue · 2 comments

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

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.

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