How to load IconCompat with AdaptiveBitmap using Glide

599 Views Asked by At

How to leverage Glide cache for loading notification icons? Those are IconCompat used in the Person object in the MessagingStyle notifications and Shortcuts. Also, Bubbles require using both of those.

I used Glid as fallowing:

private IconCompat loadIcon(String url) throws ExecutionException, InterruptedException {
    RequestOptions requestOptions = new RequestOptions().override(ADAPTIVE_BITMAP_SIZE);
    Bitmap bitmap = Glide.with(G.app).asBitmap().apply(requestOptions).load(url).submit().get();
    return IconCompat.createWithAdaptiveBitmap(bitmap);
}

I got several questions about this solution

  • What should be the size of ADAPTIVE_BITMAP_SIZE?
  • When will the bitmap get recycled?
  • How to handle errors in loading the bitmap?
1

There are 1 best solutions below

0
Vahe Gharibyan On

Create a custom TargetWrapper for the async loading icon. The config your Glide using your TargetWrapper instance.

asyncLoadIcon("http://YOUR_URL.com"){
    val person = Person.Builder()
        .setName("John Doe")
        .setIcon(it)

    notificationManagerHelper.notify(
        person.build()
    )
}

Helper function for async loading bitmap then wrap into Icon

 private fun asyncLoadIcon(avatar: String?, block: (IconCompat?) -> Unit) {
        if (avatar.isNullOrEmpty())
            block(null)
        else {
            GlideHelper.createWithAdaptiveBitmap(requireContext(), avatar) { result ->
                if (result?.isSuccess() == true)
                    block(IconCompat.createWithAdaptiveBitmap(result.toData()))
                else block(null)
            }
        }
    }

Here is the Glide image request function with retrieving bitmap with a callback.

fun createWithAdaptiveBitmap(
    context: Context,
    url: String,
    listener: ((Result<Bitmap>?) -> Unit)
) {
    val options = RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.DATA)
        .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
        .dontTransform()

    Glide.with(context)
        .asBitmap()
        .apply(options)
        .load(url)
        .into(CustomTargetWrapper(listener))
}

CustomTargetWrapper class for async loading bitmap.

class CustomTargetWrapper(
    private val listener: ((Result<Bitmap>?) -> Unit)
) : CustomTarget<Bitmap>() {

    override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
        listener.invoke(Result.Success(resource))
    }

    override fun onLoadCleared(placeholder: Drawable?) {
        listener.invoke(null)
    }

    override fun onLoadFailed(errorDrawable: Drawable?) {
        super.onLoadFailed(errorDrawable)
        listener.invoke(Result.Error(IOException("Glide load failed")))
    }
}