Unity-Android-Bluetooth-Low-Energy icon indicating copy to clipboard operation
Unity-Android-Bluetooth-Low-Energy copied to clipboard

Crash on Android with Unity6

Open MarkoRitter opened this issue 1 year ago • 11 comments

As soon as I use the Package Manager to pull from this repo, a newly built app crashes on startup on the Quest 3.

logcat.txt

As soon as I remove the package and rebuild, it works again.

I suspected that it has something to do with the AndroidManifest.xml, but that is not the case - it does not change while this package is included.

edit: The workaround was to toggle from the Unity6 default of GameActivity to Activity in Project Settings -> Player. It consequently needs an aligned activity in the main AndroidManifest.xml

image

        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>

MarkoRitter avatar Dec 06 '24 06:12 MarkoRitter

Have you added Bluetooth permissions to your Android manifest? There is a Bluetooth setup wizard that should open after you've installed the package to help you with that.

Also please let us know what Android SDK version you are building with.

paulhayes avatar Dec 07 '24 11:12 paulhayes

I have tested on the Quest 3 earlier this year. But it might be worth taking a second look. The cause of the error seems to be

2024/12/06 19:20:48.868 18939 18939 Error AndroidRuntime java.lang.NoSuchFieldError: No static field view_tree_on_back_pressed_dispatcher_owner of type I in class Landroidx/activity/R$id; or its superclasses (declaration of 'androidx.activity.R$id' appears in /data/app/~~aUP8wr8kOd8DLKeQHij0kg==/hitlabnz.ritter.ant-ahILRfpzzBMdouA68W-IRA==/base.apk)

Which doesn't look related to the library, but I'm wondering if there's something that we've missed.

I can borrow a Quest 3 in January. Will test then.

paulhayes avatar Dec 07 '24 11:12 paulhayes

Hi Paul,

thanks for looking into it.

I am using Unity Version 6000.0.26f1, building for Android 12L (API Level 32).

My custom Main Manifest looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />

    <uses-permission android:name="com.oculus.permission.EYE_TRACKING"/>
    <uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="true"/>
  
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
    <uses-feature android:name="android.hardware.bluetooth" android:required="true" />

  <application>
      <activity
          android:name="com.unity3d.player.UnityPlayerGameActivity"
          android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
          android:enabled="true"
          android:exported="true"
          android:hardwareAccelerated="false"
          android:launchMode="singleTask"
          android:resizeableActivity="true"
          android:screenOrientation="fullUser"
          android:theme="@style/BaseUnityGameActivityTheme" >
        <intent-filter>
          <category android:name="android.intent.category.LAUNCHER" />
          <action android:name="android.intent.action.MAIN" />
          <category android:name="com.oculus.intent.category.VR" />
        </intent-filter>

        <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        <meta-data android:name="android.app.lib_name" android:value="game" />
        <meta-data android:name="WindowManagerPreference:FreeformWindowSize" android:value="@string/FreeformWindowSize_maximize" />
        <meta-data android:name="WindowManagerPreference:FreeformWindowOrientation" android:value="@string/FreeformWindowOrientation_landscape" />
        <meta-data android:name="notch_support" android:value="true" />
      </activity>      
      
    </application>
</manifest>

This checks out, the wizard reports 4 green checkmarks. When digging into ..\Library\Bee\Android\Prj\IL2CPP\Gradle\launcher\build\intermediates\merged_manifest\debug\processDebugMainManifest it merges it into this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="hitlabnz.ritter.ant"
    android:installLocation="preferExternal"
    android:versionCode="1"
    android:versionName="0.1.0" >

    <uses-sdk
        android:minSdkVersion="32"
        android:targetSdkVersion="35" />

    <supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:xlargeScreens="true" />

    <supports-gl-texture android:name="GL_KHR_texture_compression_astc_ldr" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="android.permission.BLUETOOTH"
        android:maxSdkVersion="30" />
    <uses-permission
        android:name="android.permission.BLUETOOTH_ADMIN"
        android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission
        android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation" />
    <uses-permission android:name="com.oculus.permission.EYE_TRACKING" />

    <uses-feature
        android:name="com.oculus.feature.PASSTHROUGH"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.bluetooth"
        android:required="true" />
    <uses-feature android:glEsVersion="0x00030000" />
    <uses-feature
        android:name="android.hardware.vulkan.version"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen.multitouch"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen.multitouch.distinct"
        android:required="false" />

    <uses-permission android:name="com.oculus.permission.HAND_TRACKING" />

    <uses-feature
        android:name="oculus.software.handtracking"
        android:required="false" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-feature
        android:name="android.hardware.vr.headtracking"
        android:required="true"
        android:version="1" />
    <uses-feature
        android:name="oculus.software.eye_tracking"
        android:required="true" />

    <permission
        android:name="hitlabnz.ritter.ant.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
        android:protectionLevel="signature" />

    <uses-permission android:name="hitlabnz.ritter.ant.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" />

    <application
        android:appComponentFactory="androidx.core.app.CoreComponentFactory"
        android:debuggable="true"
        android:enableOnBackInvokedCallback="false"
        android:extractNativeLibs="true"
        android:icon="@mipmap/app_icon"
        android:label="@string/app_name" >
        <meta-data
            android:name="unity.splash-mode"
            android:value="0" />
        <meta-data
            android:name="unity.splash-enable"
            android:value="True" />
        <meta-data
            android:name="unity.launch-fullscreen"
            android:value="True" />
        <meta-data
            android:name="unity.render-outside-safearea"
            android:value="True" />
        <meta-data
            android:name="notch.config"
            android:value="portrait|landscape" />
        <meta-data
            android:name="unity.auto-report-fully-drawn"
            android:value="true" />
        <meta-data
            android:name="unity.auto-set-game-state"
            android:value="true" />
        <meta-data
            android:name="unity.strip-engine-code"
            android:value="true" />

        <activity
            android:name="com.unity3d.player.UnityPlayerGameActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
            android:enabled="true"
            android:exported="true"
            android:hardwareAccelerated="false"
            android:launchMode="singleTask"
            android:resizeableActivity="true"
            android:screenOrientation="fullUser"
            android:theme="@style/BaseUnityGameActivityTheme" >
            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="com.oculus.intent.category.VR" />

                <action android:name="android.intent.action.MAIN" />
            </intent-filter>

            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
            <meta-data
                android:name="android.app.lib_name"
                android:value="game" />
            <meta-data
                android:name="WindowManagerPreference:FreeformWindowSize"
                android:value="@string/FreeformWindowSize_maximize" />
            <meta-data
                android:name="WindowManagerPreference:FreeformWindowOrientation"
                android:value="@string/FreeformWindowOrientation_landscape" />
            <meta-data
                android:name="notch_support"
                android:value="true" />
            <meta-data
                android:name="WindowManagerPreference:FreeformWindowSize"
                android:value="@string/FreeformWindowSize_maximize" />
            <meta-data
                android:name="WindowManagerPreference:FreeformWindowOrientation"
                android:value="@string/FreeformWindowOrientation_landscape" />
            <meta-data
                android:name="notch_support"
                android:value="true" />
            <meta-data
                android:name="com.oculus.vr.focusaware"
                android:value="true" />
        </activity>

        <meta-data
            android:name="com.oculus.supportedDevices"
            android:value="eureka" />

        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="hitlabnz.ritter.ant.androidx-startup"
            android:exported="false" >
            <meta-data
                android:name="androidx.emoji2.text.EmojiCompatInitializer"
                android:value="androidx.startup" />
            <meta-data
                android:name="androidx.lifecycle.ProcessLifecycleInitializer"
                android:value="androidx.startup" />
        </provider>
    </application>

</manifest>

The resulting manifest is identical, when I build with or without the BLE package.

If I build it without inclusion of the BLE package, it shows my passthrough AR app correctly. If I build it with the package, it crashes on startup, with the aforementioned exception:

java.lang.NoSuchFieldError: No static field view_tree_on_back_pressed_dispatcher_owner of type I in class Landroidx/activity/R$id; or its superclasses (declaration of 'androidx.activity.R$id' appears in /data/app/~~aUP8wr8kOd8DLKeQHij0kg==/hitlabnz.ritter.ant-ahILRfpzzBMdouA68W-IRA==/base.apk)
2024/12/06 19:20:48.868 18939 18939 Error AndroidRuntime 	at androidx.activity.ViewTreeOnBackPressedDispatcherOwner.set(ViewTreeOnBackPressedDispatcherOwner.kt:38)
2024/12/06 19:20:48.868 18939 18939 Error AndroidRuntime 	at androidx.appcompat.app.AppCompatActivity.initViewTreeOwners(AppCompatActivity.java:224)
2024/12/06 19:20:48.868 18939 18939 Error AndroidRuntime 	at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:202)
2024/12/06 19:20:48.868 18939 18939 Error AndroidRuntime 	at com.google.androidgamesdk.GameActivity.onCreateSurfaceView(GameActivity.java:274)
2024/12/06 19:20:48.868 18939 18939 Error AndroidRuntime 	at com.unity3d.player.UnityPlayerGameActivity.onCreateSurfaceView(UnityPlayerGameActivity.java:57)

I share both resulting apk in case you want to look deeper into error logs and sideload the app: APK: Plain and BLE please note that while they look similar, their contents do differ. The plain one will show the app correctly (a grey box in the room) while the ble one crashes.

MarkoRitter avatar Dec 08 '24 01:12 MarkoRitter

Out of curiosity, I created a new project with the mobile 2d template. Same Unity version, same SDK version as above. It runs correctly when deployed onto my Google Pixel 7 Pro.

However, when I add the git repo as a package the app crashes on startup, same error as on the quest 3:

0001/01/01 00:00:00.000 -1 -1 Info  --------- beginning of crash
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime FATAL EXCEPTION: main
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime Process: hitlabnz.ritter.pixeltest, PID: 15744
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime java.lang.NoSuchFieldError: No static field view_tree_on_back_pressed_dispatcher_owner of type I in class Landroidx/activity/R$id; or its superclasses (declaration of 'androidx.activity.R$id' appears in /data/app/~~TPxaw2mWSYj_FyN5bvZ0DA==/hitlabnz.ritter.pixeltest-fMgtOQ1krvFja1NDS18nTA==/base.apk)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at androidx.activity.ViewTreeOnBackPressedDispatcherOwner.set(ViewTreeOnBackPressedDispatcherOwner.kt:38)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at androidx.appcompat.app.AppCompatActivity.initViewTreeOwners(AppCompatActivity.java:224)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:202)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at com.google.androidgamesdk.GameActivity.onCreateSurfaceView(GameActivity.java:274)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at com.unity3d.player.UnityPlayerGameActivity.onCreateSurfaceView(UnityPlayerGameActivity.java:57)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at com.google.androidgamesdk.GameActivity.onCreate(GameActivity.java:304)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at com.unity3d.player.UnityPlayerGameActivity.onCreate(UnityPlayerGameActivity.java:35)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.Activity.performCreate(Activity.java:9002)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.Activity.performCreate(Activity.java:8980)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1526)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4030)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4235)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:112)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:174)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:109)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:81)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2636)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.os.Handler.dispatchMessage(Handler.java:107)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.os.Looper.loopOnce(Looper.java:232)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.os.Looper.loop(Looper.java:317)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at android.app.ActivityThread.main(ActivityThread.java:8705)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at java.lang.reflect.Method.invoke(Native Method)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
2024/12/09 16:17:24.845 15744 15744 Error AndroidRuntime 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)

Just out of interest, have you ever had it running with Unity 6?

Could it have to do something with this: GameActivity?

MarkoRitter avatar Dec 09 '24 03:12 MarkoRitter

It looks like yes it's a problem with Unity 6 and the library. I don't think either of us have had time to look at Unity's latest release. I'm still working in 2021 and 2022 for my existing projects.

This is something we will have to address really soon, but no sure how many weeks it will be before we find time to take a look.

paulhayes avatar Dec 09 '24 10:12 paulhayes

I can confirm, it is the Looper that is causing havoc.

Eventually I could get the app to scan BT and connect to devices when using legacy PlayerActivity instead of the default PlayerGameActivity, which is not using Looper anymore (in favor of a concurrent process for the java lib, granting better average performance). This can be set in Settings -> Player -> Publishing Settings and needs some editing of the AndroidManifest.xml as well

So yes, this issue would require a partial rewrite of the java parts to do properly, but as long as Unity still allows legacy options, it is not as bad. Just needs an update for the documentation. Feel free to close the issue

velcrome avatar Dec 09 '24 10:12 velcrome

I'll keep the issue open, as it serves as a good reminder to update the library to support GameActivity. Thanks for the descriptive info on the issue!

Velorexe avatar Dec 09 '24 17:12 Velorexe

sure thing, I hope you find the time to update your lib. I added the solution in the first post in case someone else stumbles on the same issue

MarkoRitter avatar Dec 09 '24 22:12 MarkoRitter

Thanks for your help identifying this @MarkoRitter . Yeah we'll leave this open until there's a bullet proof solution.

paulhayes avatar Dec 10 '24 13:12 paulhayes

Has the issue with Android and Unity 6 been resolved?

mjscottinnc avatar Jun 17 '25 18:06 mjscottinnc

We've been too busy to do much on the project recently. We'd welcome some help.

paulhayes avatar Jun 17 '25 21:06 paulhayes