Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting Unable to decode stream: java.io.FileNotFoundException if crop is false #25

Closed
ASKabanets opened this issue May 14, 2021 · 16 comments · Fixed by #26
Closed

Getting Unable to decode stream: java.io.FileNotFoundException if crop is false #25

ASKabanets opened this issue May 14, 2021 · 16 comments · Fixed by #26
Assignees
Labels
bug Something isn't working

Comments

@ASKabanets
Copy link

ASKabanets commented May 14, 2021

Hi! Thanks for the library!

Checked sample app.
Getting BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /document/image:197117: open failed: ENOENT (No such file or directory) if don't add crop()

ImagePicker.with(this)
//                .crop()
//                .cropOval()
                .maxResultSize(512, 512, true)
                .createIntentFromDialog { profileLauncher.launch(it) }
@Drjacky Drjacky self-assigned this May 14, 2021
@Drjacky Drjacky added the question Further information is requested label May 14, 2021
@Drjacky
Copy link
Owner

Drjacky commented May 14, 2021

@ASKabanets What library version you use and which Android API you tests on?
I've used v2.1.8 on API 29 and API 30 and it works.

@ASKabanets
Copy link
Author

I've just downloaded this sample project, launched it on my OnePlus 5 (Android 10) and tried to get image from gallery or camera. It works great, but when crop is false I got FileNotFoundException.
Then I've created empty project (empty screen just with one button) and added ImagePicker as a dependency. Used the same piece of code as in the sample project - same: when crop is false it throws exception

@Drjacky
Copy link
Owner

Drjacky commented May 15, 2021

Could you attach your sample project here?

@ASKabanets
Copy link
Author

https://drive.google.com/file/d/1TO5VLXkkVM_bUwk9qBR9co2Zk4ml8V3O/view?usp=sharing

@Drjacky
Copy link
Owner

Drjacky commented May 15, 2021

@ASKabanets You're right. The error is in logcat but, the app works and you could easily use the uri and pass it to your Image Loader library.

I'll fix that false-positive exception. Thanks!

@Drjacky Drjacky added bug Something isn't working and removed question Further information is requested labels May 15, 2021
@ASKabanets
Copy link
Author

ASKabanets commented May 16, 2021

It works (when crop is false) if you use uri to set an image. If you use file path it doesn't work ( ImagePicker.getFilePath(activityResult.data) when crop is false)

@Drjacky
Copy link
Owner

Drjacky commented May 16, 2021

@ASKabanets Please use Uri. I'm gonna update the sample app and the Readme.

@Drjacky Drjacky linked a pull request May 16, 2021 that will close this issue
@GuilhE
Copy link

GuilhE commented Sep 17, 2021

I'm having the same problem with this setup:

ImagePicker
     .with(activity)
     .maxResultSize(maxWidth, maxHeight, true)
     .createIntentFromDialog { intentLauncher.invoke(it) }

I can have a path:

private val imageLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
       if (it.resultCode == Activity.RESULT_OK) {
           uploadImage(ImagePicker.getFilePath(it.data)!!)
       } else {...}
}

But:

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.io.FileNotFoundException: /external_files/Android/data/com.myapp/files/DCIM/Camera/IMG_20210917_143936745.jpg: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:575)
at java.io.FileInputStream.(FileInputStream.java:160)
at okio.Okio__JvmOkioKt.source(JvmOkio.kt:181)
at okio.Okio.source(Unknown Source:1)
at okhttp3.RequestBody$Companion$asRequestBody$1.writeTo(RequestBody.kt:167)
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.kt:157)
at okhttp3.MultipartBody.writeTo(MultipartBody.kt:93)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:202)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:567)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:273)
at libcore.io.ForwardingOs.open(ForwardingOs.java:567)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7728)
at libcore.io.IoBridge.open(IoBridge.java:561)
at java.io.FileInputStream.(FileInputStream.java:160) 
at okio.Okio__JvmOkioKt.source(JvmOkio.kt:181) 
at okio.Okio.source(Unknown Source:1) 
at okhttp3.RequestBody$Companion$asRequestBody$1.writeTo(RequestBody.kt:167) 
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.kt:157) 
at okhttp3.MultipartBody.writeTo(MultipartBody.kt:93) 
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:202) 
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) 
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) 
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:920) 

ps: if I switch to my implementation I don't have this problem (but then I have with API versions that you fixed)

Any hint @Drjacky ?

@GuilhE
Copy link

GuilhE commented Sep 17, 2021

This is the path I get using my version: /data/user/0/com.myapp/files/temp.JPEG 🤔

@Drjacky
Copy link
Owner

Drjacky commented Sep 17, 2021

@GuilhE Using file path (ImagePicker.getFilePath(activityResult.data)) when the crop is false doesn't work (I'll fix it later) but, using uri works perfectly even if the crop is off:

private val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
       if (it.resultCode == Activity.RESULT_OK) {
           val uri = it.data?.data!!
           // Use the uri to load the image
       }
   }

@GuilhE
Copy link

GuilhE commented Sep 17, 2021

I've tried that, but I get exactly the same path uppon uri.path 🤔

@Drjacky
Copy link
Owner

Drjacky commented Sep 17, 2021

@GuilhE No, not .path.
This:

private val galleryLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == Activity.RESULT_OK) {
                val uri = it.data?.data!!
                mGalleryUri = uri
                imgGallery.setLocalImage(uri)
            } else parseError(it)
        }

@GuilhE
Copy link

GuilhE commented Sep 17, 2021

What's the imgGallery.setLocalImage(uri)? Ideally I've taken a photo or picked a image from the gallery, save it as a temp file under the app access scope and then retrieve the path (/data/user/0/.../files/temp.JPEG) to upload it as MultipartFormData. In the end I'll be using a File, something like this:

registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { 
     val image = ImagePicker.getFile(it.data)
     if (image?.exists() == true) {
         api.uploadPhoto(MultipartBody.Part.createFormData("image", file.name, file.asRequestBody("image/*".toMediaTypeOrNull())))
     }
}

Our implementations differ, my version:

GalleryProvider

private fun handleResult(data: Intent?) {
        val uri = data?.data
        if (uri != null) {
            val filePath: String? = FileUriUtils.getRealPath(activity, uri)
            if (!filePath.isNullOrEmpty()) {
                activity.setImage(File(filePath))
            } else {
                setError(R.string.error_failed_pick_gallery_image)
            }
        } else {
            setError(R.string.error_failed_pick_gallery_image)
        }
    }

I believe the differences in FileUriUtils could also be related 🤔 .

@GuilhE
Copy link

GuilhE commented Sep 17, 2021

I've changed my GalleryProvider to include your permissions logic, but maintaining all my previous logic. It's working now 👍🏼

@ClarkXP
Copy link

ClarkXP commented Jan 9, 2023

I'm getting same issue when try to open camera without crop() option.
Can be recreated removing crop option in pickCameraImage() function.

Unable to decode stream: java.io.FileNotFoundException: /external_files/Android/data/com.github.drjacky.imagepicker.sample/files/DCIM/Camera/IMG_20230109_103418027.jpg: open failed: ENOENT (No such file or directory)
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference at com.github.drjacky.imagepicker.provider.CompressionProvider.compressTask(CompressionProvider.kt:72) at com.github.drjacky.imagepicker.provider.CompressionProvider.access$compressTask(CompressionProvider.kt:24) at com.github.drjacky.imagepicker.provider.CompressionProvider$compress$1.invokeSuspend(CompressionProvider.kt:58) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:367) at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30) at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25) at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110) at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56) at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47) at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1) at com.github.drjacky.imagepicker.provider.CompressionProvider.compress(CompressionProvider.kt:57) at com.github.drjacky.imagepicker.ImagePickerActivity.setImage(ImagePickerActivity.kt:172) at com.github.drjacky.imagepicker.provider.CameraProvider.handleResult(CameraProvider.kt:142) at com.github.drjacky.imagepicker.ImagePickerActivity.cameraLauncher$lambda$1(ImagePickerActivity.kt:59) at com.github.drjacky.imagepicker.ImagePickerActivity.$r8$lambda$TbnVizF4DKsKWrDO5-zrgXMal9g(Unknown Source:0) at com.github.drjacky.imagepicker.ImagePickerActivity$$ExternalSyntheticLambda1.onActivityResult(Unknown Source:4) at androidx.activity.result.ActivityResultRegistry$1.onStateChanged(ActivityResultRegistry.java:149) at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360) at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271) at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313) at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151) at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134) at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:68) at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostStarted(ReportFragment.java:187) at android.app.Activity.dispatchActivityPostStarted(Activity.java:1428) at android.app.Activity.performStart(Activity.java:8254) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3789) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:210) at android.os.Looper.loop(Looper.java:299) at android.app.ActivityThread.main(ActivityThread.java:8337) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1037)

@Drjacky
Copy link
Owner

Drjacky commented Jan 13, 2023

@ClarkXP Please create a new issue with the all necessary information

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants