How to set bitmap in proto tile android

75 views Asked by At

I want to set a bitmap in android proto tile for wear. We can set the image using Image Builder class. But i do not find any method in proto tile to set the bitmap image in android. I am using below wear tile libraries. Thanks!!

    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.3.0-beta01"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.1.0-beta01"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.1.0-beta01"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.1.0-beta01"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.3.0-beta01"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.3.0-beta01"
}```
1

There are 1 answers

0
dect On

On tiles you can set either a andorid resource id or a image byte array. In your case, if the image is dynamic (is not set as a internal resource) you need to convert it to byte array and then set it.

(I recommend for you to convert the image to byte array outside the tile service, in the editor activity for example, to save resources and battery)

I got a code for converting drawable into byte array, in case u want:

private byte[] toByteArray(Drawable d) {
    try {
        final Bitmap b = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);

        final Canvas canvas = new Canvas(b);

        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());

        d.draw(canvas);

        final ByteArrayOutputStream stream = new ByteArrayOutputStream();

        b.compress(Bitmap.CompressFormat.PNG, 100, stream);

        return stream.toByteArray();
     } catch (Exception e) {
         return null;
     }
}

To convert the byte[] to string you can:

pricate String byteArrayToString(ByteArrayOutputStream s) {
     return Base64.getEncoder().encodeToString(s.toByteArray());
}

private byte[] stringToByteArray(String s) {
     return s == null ? new byte[0] : Base64.getDecoder().decode(s);
}

Then you can set it on tile in the "onResourcesRequest":

@NonNull
@Override
protected ListenableFuture<ResourceBuilders.Resources> onResourcesRequest(@NonNull RequestBuilders.ResourcesRequest requestParams) {
    final ResourceBuilders.Resources.Builder resources = new ResourceBuilders.Resources.Builder();

//Your code to get the byte array

resources.addIdToImageMapping(
    ID,
    new ResourceBuilders.ImageResource.Builder()
    .setInlineResource(
         new ResourceBuilders.InlineImageResource.Builder()
         .setData(
         //BYTE ARRAY HERE <<
        ).setFormat(ResourceBuilders.IMAGE_FORMAT_UNDEFINED) //This is required unless you know the format, I recommend leaving this way
        .setHeightPx(SIZE * 2) //2 for better quality 
        .setWidthPx(SIZES * 2) //2 for better quality
        .build()
    ).build()
);

     return Futures.immediateFuture(resources.setVersion(VERSION).build());
}

Then you set the image using its ID...

Edit: The libraries I use

    implementation "androidx.wear.tiles:tiles:1.1.0"
    implementation "androidx.wear.tiles:tiles-material:1.1.0"
    implementation "androidx.concurrent:concurrent-futures:1.1.0"
    implementation "com.google.guava:guava:31.0.1-android"