Ilya Gazman
Ilya Gazman

Reputation: 32271

How to load IconCompat with AdaptiveBitmap using Glide

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

Upvotes: 3

Views: 681

Answers (1)

Vahe Gharibyan
Vahe Gharibyan

Reputation: 5693

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")))
    }
}

Upvotes: 2

Related Questions