Kamel-Media / Kamel

Kotlin asynchronous media loading and caching library for Compose.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for Content scheme URIs for Android

yuroyami opened this issue · comments

Content URIs (android.net.Uri) do not work on Android (tested on Android 13). I also tried to convert android.net.Uri to a string then back to java.net.Uri, that doesn't work either. I believe this has not been implemented yet, probably because Content URIs require Context.

Typically, the Content URI is used to retrieve a bitmap like this (which as you can see, uses a Context) :

context, imageUri ->
val bitmap: Bitmap
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    val source = ImageDecoder.createSource(context.contentResolver, imageUri)
    bitmap = ImageDecoder.decodeBitmap(source)
} else {
    bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, imageUri)
}

I haven't dived into Kamel's source code, so I know little to none about how everything is implemented. However, in Compose multiplatform, the API exposes a ImageBitmap which is platform-agnostic. On Android side, we can use Bitmap.asimageBitmap() extension function to convert an Android's Bitmap into Compose ImageBitmap.

In androidMain, we can also retrieve a Context using LocalContext.current.

In a Compose multiplatform app, I encountered the use-case where i have to use a KamelImage to show data from an Uri, but that Uri can either be an Uri that points to a Content scheme URI if I am on Android, or a remote URI if I am on iOS.

Sounds like it could be a good feature to add. I don't really have time to look into this atm, but if you want to do a pr, context is now injected into kamel-core here. Or LocalContext.current possibly could be used as well...

I believe it could be implemented as a new type of fetcher: Fetcher<android.net.Uri>. For example this is the HttpFetcher.

Basically Fetcher<android.net.Uri> just specifies a data source type android.net.Uri in this case and fetches bytes bytes from it.

Also, fyi Fetcher is an interface you can implement in your own app and add to your own KamelConfig without having to make a PR here. But if you do implement it and want to share, please do. PR's are always welcome!

In some cases on android your could probably just accomplish this as well with a mapper... if you can actually get a real file path from android.net.Uri ... but I know in many cases android's Storage Access Framework (which is difficult to say the least) prevents you from doing anything but reading the bytes. In which case a Fetcher would be the way to go.

Hey @luca992, I think this one would be doable with mappers too once we address #70 since android.net.Uri could either be a local file or a remote uri too, just as NSURL on #71 .

Hey @luca992, I think this one would be doable with mappers too once we address #70 since android.net.Uri could either be a local file or a remote uri too, just as NSURL on #71 .

Yup for sure