saket / telephoto

Building blocks for designing media experiences in Compose UI
https://saket.github.io/telephoto/
Apache License 2.0
869 stars 28 forks source link

Fatal Exception: java.io.FileNotFoundException: No content provider: url #90

Open adechanterac opened 1 week ago

adechanterac commented 1 week ago

Hello,

We are using telphoto lib to pinch photo loaded from and url but we are experiencing random crash Here is the stacktrace :

Fatal Exception: java.io.FileNotFoundException: No content provider: https://myurl.com/p2258493/k$b6f7c00b3bc2b1be0ec109f999fedccd/1200x1200/image.jpg at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1675) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1505) at android.content.ContentResolver.openInputStream(ContentResolver.java:1189) at me.saket.telephoto.subsamplingimage.UriImageSource.peek(SubSamplingImageSource.kt:190) at me.saket.telephoto.zoomable.coil.SubSamplingEligibilityKt.canBeSubSampled(subSamplingEligibility.kt:47) at me.saket.telephoto.zoomable.coil.SubSamplingEligibilityKt.access$canBeSubSampled(subSamplingEligibility.kt:1) at me.saket.telephoto.zoomable.coil.SubSamplingEligibilityKt$canBeSubSampled$2.invokeSuspend(subSamplingEligibility.kt:27) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104) at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:111) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:811) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:715) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:702)

And here is our implementation :

ZoomableAsyncImage(
            contentScale = ContentScale.Inside,
            state = imageState,
            modifier = Modifier
                .align(Alignment.Center)
                .fillMaxSize()
                .offset(y = dimensionResource(id = R.dimen.main_image_offset))
                .graphicsLayer(scaleX = scale, scaleY = scale),
            model = ImageRequest.Builder(context)
                .data(imageUrl)
                .listener(
                    remember {
                        object : ImageRequest.Listener {
                            override fun onSuccess(request: ImageRequest, result: SuccessResult) {
                                val imageIntrinsicHeight = result.drawable.intrinsicHeight
                                val imageIntrinsicWidth = result.drawable.intrinsicWidth

                                val ratio = getImageRatioFromScreen(
                                    configuration,
                                    imageIntrinsicHeight,
                                    imageIntrinsicWidth,
                                    screenSize
                                )
                                val scalingDensityDp = density.density

                                minScale =
                                    (minImageWidth.value / imageIntrinsicWidth) * ratio * scalingDensityDp

                                minImageHeight =
                                    ((minScale * imageIntrinsicHeight) / (ratio * scalingDensityDp)).dp

                                maxScale = if (isPortrait) {
                                    (parentHeight / imageIntrinsicHeight) * ratio
                                } else {
                                    (parentWidth / imageIntrinsicWidth) * ratio
                                }

                                scale = minScale
                            }

                            override fun onStart(request: ImageRequest) {
                                scale = 1.0f
                            }
                        }
                    }
                )
                .size(MAX_IMAGE_SIZE)
                .build(),
            contentDescription = stringResource(id = R.string.photo_zoom_description),
        )

Here is our thought :

We do not get why we are expecting URI (but not at the url format) and loading resource from a content provider as we are loading it from an URL ? It happens randomly even if we retry it with the image url that causes the crash.

coil: 2.1.0 telefoto: 0.11.2

Thanks for the response

saket commented 1 week ago

Could this be related to https://github.com/saket/telephoto/issues/50?

adechanterac commented 1 week ago

We guess so, do you need any extra info that would help to solve this issue ?

necatisozer commented 1 week ago

@saket same here.