1

I am trying to add a Wear OS tile to my app. I am not previewing my tile in an activity since it is already possible to add custom tiles. But whenever I slide to my tile, I get this exception and the tile only displays the label of my tile, provided inside the manifest.

E/JavaBinder: *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
    java.lang.BootstrapMethodError: Exception from call site #29 bootstrap method
        at androidx.wear.tiles.TileEnterEventData.<clinit>(TileEnterEventData.java:32)
        at androidx.wear.tiles.TileProvider$Stub.onTransact(TileProvider.java:197)
        at android.os.Binder.execTransact(Binder.java:731)
     Caused by: java.lang.ClassCastException: Bootstrap method returned null
        at androidx.wear.tiles.TileEnterEventData.<clinit>(TileEnterEventData.java:32) 
        at androidx.wear.tiles.TileProvider$Stub.onTransact(TileProvider.java:197) 
        at android.os.Binder.execTransact(Binder.java:731) 
E/AndroidRuntime: FATAL EXCEPTION: Binder:16030_2
    Process: com.pezcraft.myapplication, PID: 16030
    java.lang.BootstrapMethodError: Exception from call site #29 bootstrap method
        at androidx.wear.tiles.TileEnterEventData.<clinit>(TileEnterEventData.java:32)
        at androidx.wear.tiles.TileProvider$Stub.onTransact(TileProvider.java:197)
        at android.os.Binder.execTransact(Binder.java:731)
     Caused by: java.lang.ClassCastException: Bootstrap method returned null
        at androidx.wear.tiles.TileEnterEventData.<clinit>(TileEnterEventData.java:32) 
        at androidx.wear.tiles.TileProvider$Stub.onTransact(TileProvider.java:197) 
        at android.os.Binder.execTransact(Binder.java:731) 

My Manifest looks like this...

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pezcraft.heartrateonstream">

    <uses-permission android:name="android.permission.BODY_SENSORS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <uses-feature android:name="android.hardware.type.watch" />
    <uses-feature android:name="android.hardware.sensor.heartrate" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar"
        android:allowBackup="false">

        <meta-data
            android:name="com.google.android.wearable.standalone"
            android:value="false" />

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:taskAffinity=""
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".HeartRateTileService"
            android:exported="true"
            android:label="@string/tile_label"
            android:description="@string/tile_description"
            android:icon="@drawable/ic_heart"
            android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
            <intent-filter>
                <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
            </intent-filter>

            <meta-data
                android:name="androidx.wear.tiles.PREVIEW"
                android:resource="@drawable/ic_heart" />
        </service>

    </application>
</manifest>

My TileService...

public class HeartRateTileService extends TileService {
    private static final String RESOURCES_VERSION = "1";

    @NonNull
    @Override
    protected ListenableFuture<TileBuilders.Tile> onTileRequest(
            @NonNull RequestBuilders.TileRequest requestParams
    ) {
        return Futures.immediateFuture(new TileBuilders.Tile.Builder()
                .setResourcesVersion(RESOURCES_VERSION)
                .setFreshnessIntervalMillis(1000)
                .setTimeline(new TimelineBuilders.Timeline.Builder()
                        .addTimelineEntry(new TimelineBuilders.TimelineEntry.Builder()
                                .setLayout(new LayoutElementBuilders.Layout.Builder()
                                        .setRoot(
                                                layout()
                                        ).build()
                                ).build()
                        ).build()
                ).build()
        );
    }

    private LayoutElementBuilders.LayoutElement layout() {
        return new LayoutElementBuilders.Row.Builder()
                .setWidth(wrap())
                .setHeight(expand())
                .setVerticalAlignment(LayoutElementBuilders.VERTICAL_ALIGN_BOTTOM)
                .addContent(new LayoutElementBuilders.Text.Builder()
                        .setText("Hello world")
                        .build()
                ).build();
    }

    @NonNull
    @Override
    protected ListenableFuture<ResourceBuilders.Resources> onResourcesRequest(
            @NonNull RequestBuilders.ResourcesRequest requestParams
    ) {
        return Futures.immediateFuture(new ResourceBuilders.Resources.Builder()
                .setVersion(RESOURCES_VERSION)
                .build()
        );
    }

}

What am I doing wrong?

TofferJ
  • 4,678
  • 1
  • 37
  • 49
Pezcraft
  • 270
  • 3
  • 15
  • This tile works perfectly fine for me. Do you get any exceptions in logcat? – Yuri Schimke Nov 05 '21 at 08:52
  • BTW 1 second is below the minimum refresh limit of 60 seconds. – Yuri Schimke Nov 05 '21 at 08:53
  • Previewing it in an activity can still be beneficial. It makes it easier to debug and fix issues like the one above. It will give you a more helpful stacktrace that pinpoints where the issue is. – TofferJ Nov 05 '21 at 15:47
  • @YuriSchimke I created a new project now and added the tile. I got the same issue. I used the first 2 code examples from https://developer.android.com/training/articles/wear-tiles (Manifest and the MyTileService) and of course, build.gradle. Do I need Wear OS 3 or something? – Pezcraft Nov 05 '21 at 15:52
  • Worth trying with API 31 for sure, but it shouldn't. I'd scan logcat for any earlier errors, it looks like you are seeing the error on the sysui process, and not the the application hosting the tile. – Yuri Schimke Nov 05 '21 at 16:11

1 Answers1

0

I solved my problem using this question... java.lang.BootstrapMethodError: Exception from call site #4 bootstrap method ,when initializing Retrofit

I added this to my build.gradle

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

I don't know why I need it, but it works now. Maybe someone can give more explanation for this solution.

Pezcraft
  • 270
  • 3
  • 15