javaandroidwear-oswear-os-tiles

Android Wear Tile JavaBinder Exception


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?


Solution

  • 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.