Closed DarrenMiddleton closed 2 years ago
Same is happening for me.
After reviewing the documents changes in Android 13, I see nothing announced that might cause the problem. This appears to be a bug in Android 13.
In ActivityThread.java:4524 (inside handleCreateService) there is a call to xxxxx.toString() when xxxx is null, thereby causing a crash. Unfortunately Android 13 source is not available. If I look at the latest version of that ActivityThread.java the lines don't match up:
However, I do see a number of string concatenations that would cause a toString() call like this: Slog.v(TAG, "Creating service " + data.info.name);
Could data.info.name be unexpectedly null?
This should come from the android:name element of the XML declaration of the BeaconService, which is declared in the library AndroidManifest.xml file as:
<service android:enabled="true"
android:exported="false"
android:isolatedProcess="false"
android:label="beacon"
android:name=".service.BeaconService"
/>
But maybe something in Android 13 causes this to become null later on?
You might try two things:
Check your merged manifest after a build and see if this service declaration has a proper name like android:name="org.altbeacon.beacon.service.BeaconService"
. You should find that in build/intermediates/merged_manifests/debug/AndroidManifest.xml
. If it does not have a name declaration this could be the problem, and the next option might help.
You could try making your own service entry in your app's AndroidManifest.xml to override this declaration and force the service to have a name. You could do something like this:
<service android:name="org.altbeacon.beacon.service.BeaconService"
android:exported="false"
android:isolatedProcess="false"
android:label="beacon"
android:name="org.altbeacon.beacon.service.BeaconService"
tools:node="replace">
</service>
I have the same issue. I checked the merged manifest and I do have android:name="org.altbeacon.beacon.service.BeaconService"
.
@FabienWitick can you please share your full merged manifest
@DarrenMiddleton , did you try the suggestion you posted? I wouldn't think the android:isolatedProcess="true"
would be helpful -- I would think that would break the library's ability to send scan results via the library APIs.
Here is my full merged manifest : `<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myzee.witick.debug" android:versionCode="73" android:versionName="3.3.1" >
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="30" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.BLUETOOTH"
android:required="false" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:required="false" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.VIBRATE" />
<!-- Don't require camera, as this requires a rear camera. This allows it to work on the Nexus 7 -->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" /> <!-- TODO replace above two with next line after Android 4.2 -->
<!-- <uses-feature android:name="android.hardware.camera.any"/> -->
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.flash"
android:required="false" />
<uses-feature
android:name="android.hardware.screen.landscape"
android:required="false" />
<uses-feature
android:name="android.hardware.wifi"
android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Required by older versions of Google Play services to create IID tokens -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:name="com.myzee.witick.AppSingleton"
android:allowBackup="false"
android:appComponentFactory="androidx.core.app.CoreComponentFactory"
android:debuggable="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.mixpanel.android.MPConfig.EventsEndpoint"
android:value="https://api-eu.mixpanel.com/track" />
<meta-data
android:name="com.mixpanel.android.MPConfig.PeopleEndpoint"
android:value="https://api-eu.mixpanel.com/engage" />
<meta-data
android:name="com.mixpanel.android.MPConfig.GroupsEndpoint"
android:value="https://api-eu.mixpanel.com/groups" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@mipmap/ic_notif" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorPrimary" />
<activity
android:name="com.myzee.witick.features.account.paymentMethods.PaymentMethodsActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.landing.LandingActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.register.RegisterActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="com.myzee.witick.features.authentication.AuthenticationActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="com.myzee.witick.features.V3MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="com.myzee.witick.launcher.LauncherActivity"
android:screenOrientation="portrait"
android:theme="@style/SplashTheme.LightStatusBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.myzee.witick.features.bluetooth.EnableBluetoothActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.payment.scellius.ScelliusActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.location.LocationActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.MainActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.information.UserInfoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.information.EditEmailActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="com.myzee.witick.features.account.information.EditPasswordActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="com.myzee.witick.features.account.history.HistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.history.PurchaseHistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.history.ValidationHistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.help.HelpActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.about.AboutActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.help.HelpQuestionActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.common.WebActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.myzee.witick.features.account.code.CodeActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="com.myzee.witick.features.payment.stripe.StripeActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<!-- [START firebase_service] -->
<service
android:name="com.myzee.witick.firebase.MessagingService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- [END firebase_service] -->
<activity
android:name="com.stripe.android.view.AddPaymentMethodActivity"
android:theme="@style/StripeDefaultTheme" />
<activity
android:name="com.stripe.android.view.PaymentMethodsActivity"
android:theme="@style/StripeDefaultTheme" />
<activity
android:name="com.stripe.android.view.PaymentFlowActivity"
android:theme="@style/StripeDefaultTheme" />
<activity
android:name="com.stripe.android.view.PaymentAuthWebViewActivity"
android:theme="@style/StripeDefaultTheme"
android:windowSoftInputMode="adjustResize" />
<activity
android:name="com.stripe.android.view.PaymentRelayActivity"
android:theme="@style/StripeDefaultTheme" />
<activity
android:name="com.stripe.android.view.Stripe3ds2CompletionActivity"
android:theme="@style/StripeDefaultTheme" />
<activity
android:name="com.stripe.android.paymentsheet.PaymentSheetActivity"
android:screenOrientation="portrait"
android:theme="@style/StripePaymentSheetDefaultTheme" />
<activity
android:name="com.stripe.android.paymentsheet.PaymentOptionsActivity"
android:screenOrientation="portrait"
android:theme="@style/StripePaymentSheetDefaultTheme" />
<activity
android:name="com.stripe.android.googlepay.StripeGooglePayActivity"
android:screenOrientation="portrait"
android:theme="@style/StripeGooglePayDefaultTheme" />
<activity
android:name="com.stripe.android.stripe3ds2.views.ChallengeActivity"
android:theme="@style/Stripe3DS2Theme" />
<activity
android:name="com.stripe.android.stripe3ds2.views.ChallengeProgressActivity"
android:theme="@style/Stripe3DS2Theme" />
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:clearTaskOnLaunch="true"
android:screenOrientation="sensorLandscape"
android:stateNotNeeded="true"
android:theme="@style/zxing_CaptureTheme"
android:windowSoftInputMode="stateAlwaysHidden" />
<receiver
android:name="org.altbeacon.beacon.startup.StartupBroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<service
android:name="org.altbeacon.beacon.service.BeaconService"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false"
android:label="beacon" />
<service
android:name="org.altbeacon.beacon.BeaconIntentProcessor"
android:enabled="true"
android:exported="false" />
<service
android:name="org.altbeacon.beacon.service.ScanJob"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" >
<meta-data
android:name="immediateScanJobId"
android:value="208352939" />
<meta-data
android:name="periodicScanJobId"
android:value="208352940" />
</service>
<service
android:name="org.altbeacon.bluetooth.BluetoothTestJob"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" >
<meta-data
android:name="jobId"
android:value="1799803768" />
</service>
<service
android:name="com.google.firebase.components.ComponentDiscoveryService"
android:directBootAware="true"
android:exported="false" >
<meta-data
android:name="com.google.firebase.components:com.google.firebase.remoteconfig.RemoteConfigRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.crashlytics.CrashlyticsRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.analytics.connector.internal.AnalyticsConnectorRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.abt.component.AbtRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
</service>
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>
<!--
FirebaseMessagingService performs security checks at runtime,
but set to not exported to explicitly avoid allowing another app to call it.
-->
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:directBootAware="true"
android:exported="false" >
<intent-filter android:priority="-500" >
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!--
The Mixpanel library will automatically attempt to show available in
app notifications every time a new Activity is displayed. To disable this behavior,
add the following line. The default value for this option is set to true.
-->
<!--
<meta-data android:name="com.mixpanel.android.MPConfig.AutoShowMixpanelUpdates"
android:value="false" />
-->
<!--
Set this option to true if you wish for in-app notifications to be displayed without
being tracked by Mixpanel. This is useful for testing the integration with your Android app.
The default value is false.
-->
<!--
<meta-data android:name="com.mixpanel.android.MPConfig.TestMode"
android:value="true" />
-->
<!--
Set the following option to true if you wish to see the debug output from the Mixpanel Android
library. This may be useful in determining when track calls go out or in-app notifications
are fetched. The default value is false.
-->
<!--
<meta-data android:name="com.mixpanel.android.MPConfig.EnableDebugLogging"
android:value="true" />
-->
<!--
This activity allows your application to show Mixpanel takeover in-app notifications.
If you only wish to show mini in-app notifications, you do not need to declare this Activity.
You may also specify a different theme to better fit the look and feel of your application.
-->
<!--
<activity android:name="com.mixpanel.android.takeoverinapp.TakeoverInAppActivity"
android:theme="@style/com_mixpanel_android_TakeoverInAppActivityTheme" />
-->
<!-- This service will allow your application to register for and receive Mixpanel push notifications. -->
<!--
<service
android:name="com.mixpanel.android.mpmetrics.MixpanelFCMMessagingService"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
-->
<!-- This activity will allow your application to make tracking calls to the MixpanelAPI for notification interactions -->
<activity android:name="com.mixpanel.android.mpmetrics.MixpanelNotificationRouteActivity" >
</activity>
<receiver android:name="com.mixpanel.android.mpmetrics.MixpanelPushNotificationDismissedReceiver" >
</receiver> <!-- The activities will be merged into the manifest of the hosting app. -->
<activity
android:name="com.google.android.play.core.common.PlayCoreDialogWrapperActivity"
android:exported="false"
android:stateNotNeeded="true"
android:theme="@style/Theme.PlayCore.Transparent" /> <!-- Needs to be explicitly declared on P+ -->
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<activity
android:name="com.google.android.gms.common.api.GoogleApiActivity"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="com.myzee.witick.debug.firebaseinitprovider"
android:directBootAware="true"
android:exported="false"
android:initOrder="100" />
<receiver
android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
android:enabled="true"
android:exported="false" >
</receiver>
<service
android:name="com.google.android.gms.measurement.AppMeasurementService"
android:enabled="true"
android:exported="false" />
<service
android:name="com.google.android.gms.measurement.AppMeasurementJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<service
android:name="androidx.room.MultiInstanceInvalidationService"
android:directBootAware="true"
android:exported="false" /> <!-- Start the Service if applicable on boot -->
<receiver android:name="com.instacart.library.truetime.BootCompletedBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery"
android:exported="false" >
<meta-data
android:name="backend:com.google.android.datatransport.cct.CctBackendFactory"
android:value="cct" />
</service>
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="com.myzee.witick.debug.lifecycle-process"
android:exported="false"
android:multiprocess="true" />
<service
android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
<receiver
android:name="com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"
android:exported="false" />
</application>
`
I am experiencing the same thing.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference at org.altbeacon.beacon.service.BeaconService.getManifestMetadataValue(BeaconService.java:284) at org.altbeacon.beacon.service.BeaconService.onCreate(BeaconService.java:228) at android.app.ActivityThread.handleCreateService(ActivityThread.java:4512) at android.app.ActivityThread.-$$Nest$mhandleCreateService(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2160) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7892) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
After checking the library code and debugging process, I figured that longScanForcingEnabled
is missing from the BeaconService metadata. This is what produce the NullPointerException.
If I put <meta-data android:name="longScanForcingEnabled" android:value="false" />
in the manifest for this service, everything works fine.
@tonynguyen0523 and @FabienWitick, please note that what you two describe has a different stack trace than the one in the issue that opened this question, so I am not certain it is the same issue.
@DarrenMiddleton, can you please try this same workaround to see if it solves the problem for your stack trace as well? Just add this to your app's AndroidManifest.xml:
<service android:name="org.altbeacon.beacon.service.BeaconService"
tools:node="replace">
<meta-data android:name="longScanForcingEnabled" android:value="true"/>
</service>
Run the app, and report back whether your crash goes away.
@davidgyoung I think this is the same stack trace. The stack posted by @tonynguyen0523 is the cause of the RuntimeException
posted by @DarrenMiddleton. I personally have the exact same stack trace on crashlytics.
Here's a candidate fix: #1095. I am putting this into a beta release now, 2.19.5-beta7. If anyone on this thread with an Android 13 install handy can try that library version and confirm if the crash goes away, I would appreciate it. The fix looks pretty straightforward. It will take about an hour for the beta release to show up on Maven central.
2.19.5-beta7 is now available on Maven Central.
Just tried 2.19.5-beta7, it seems to work for me. Thank you for this new build @davidgyoung. Do you think we can use this version for production? Or do we stick to this fix?
OK, thanks for the confirmation, @FabienWitick. I will merge this in and it will be included in the next non-beta release as well.
When I start ranging for Bluetooth devices using the altbeacon library I get the following crash.
java.lang.RuntimeException: Unable to create service org.altbeacon.beacon.service.BeaconService: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference at android.app.ActivityThread.handleCreateService(ActivityThread.java:4524) at android.app.ActivityThread.-$$Nest$mhandleCreateService(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2153) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7850) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
It happens on all Android devices I have tested that are running Android 13. The altbeacon library version is 2.19.