Sentry Options cache directory is ignored in .NET MAUI Android, causing crash in LOCKED_BOOT_COMPLETED BroadcastReceiver
See original GitHub issuePackage
Sentry.Maui
.NET Version
7.0.0
OS
Android
SDK Version
3.23.1
Steps to Reproduce
Starting from a new MAUI project:
- In Platforms -> Android, create a Broadcast receiver with an intent filter that takes ActionBootCompleted and ActionLockedBootCompleted that logs in the OnReceive method override.
- Add the “android.permission.RECEIVE_BOOT_COMPLETED” permission to the Android manifest.
- Install the Sentry.Maui Nuget package and initialise it with UseSentry in MauiProgram.cs. In the options configuration, give Sentry a valid DSN and use the following snippet to get the device encrypted storage cache directory.
#if ANDROID
var deviceContext = Platform.AppContext.CreateDeviceProtectedStorageContext();
o.CacheDirectoryPath = deviceContext?.CacheDir?.AbsolutePath;
Log.Debug("com.torutek.tankermonitor", $"Using {o.CacheDirectoryPath} as cache directory");
#endif
- Install the app on a phone or simulator that has a screen lock.
- Restart that device and look in logcat to see the crash.
Expected Result
When a BroadcastReceiver that is Direct Boot Aware starts on locked boot of an Android device, it is expected that the action in the OnReceive method of the receiver is able to run.
Actual Result
Even though the cache path is changed, Sentry still tries to open Credential Encrypted Storage from the locked state, causing an exception and app crash. Note line 3 of the crash. Logs and crash:
2022-11-17 08:41:18.813 1585-1585/com.torutek.tankermonitor D/com.torutek.tankermonitor: Using /data/user_de/0/com.torutek.tankermonitor/cache as cache directory
2022-11-17 08:41:19.051 1585-1585/com.torutek.tankermonitor E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.torutek.tankermonitor, PID: 1585
android.runtime.JavaProxyThrowable: System.IO.IOException: Required key not available : '/data/user/0/com.torutek.tankermonitor/cache'
at System.IO.FileSystem.CreateParentsAndDirectory(String fullPath, UnixFileMode unixCreateMode)
at System.IO.FileSystem.CreateDirectory(String fullPath, UnixFileMode unixCreateMode)
at System.IO.FileSystem.CreateDirectory(String fullPath)
at System.IO.Directory.CreateDirectory(String path)
at Sentry.Internal.FileSystem.CreateDirectory(String path)
at Sentry.Internal.Http.CachingTransport.Initialize(Boolean startWorker)
at Sentry.Internal.Http.CachingTransport.Create(ITransport innerTransport, SentryOptions options, Boolean startWorker, Boolean failStorage)
at Sentry.Internal.SdkComposer.CreateTransport()
at Sentry.Internal.SdkComposer.CreateBackgroundWorker()
at Sentry.SentryClient..ctor(SentryOptions options, IBackgroundWorker worker, RandomValuesFactory randomValuesFactory)
at Sentry.SentryClient..ctor(SentryOptions options, RandomValuesFactory randomValuesFactory)
at Sentry.Internal.Hub..ctor(SentryOptions options, ISentryClient client, ISessionManager sessionManager, ISystemClock clock, IInternalScopeManager scopeManager, RandomValuesFactory randomValuesFactory)
at Sentry.SentrySdk.InitHub(SentryOptions options)
at Sentry.SentrySdk.Init(SentryOptions options)
at Sentry.Maui.Internal.SentryMauiInitializer.Initialize(IServiceProvider services)
at Microsoft.Maui.Hosting.MauiAppBuilder.Build()
at TankerMonitor.Mobile.MauiProgram.CreateMauiApp()
at TankerMonitor.Mobile.MainApplication.CreateMauiApp()
at Microsoft.Maui.MauiApplication.OnCreate()
at Android.App.Application.n_OnCreate(IntPtr jnienv, IntPtr native__this)
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz)
at crc6488302ad6e9e4df1a.MauiApplication.n_onCreate(Native Method)
at crc6488302ad6e9e4df1a.MauiApplication.onCreate(MauiApplication.java:28)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1266)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6779)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2132)
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)
Issue Analytics
- State:
- Created 10 months ago
- Comments:6 (4 by maintainers)
Top Results From Across the Web
Error monitoring for .NET MAUI with Sentry - YouTube
Do you know when your apps are crashing before your users do? What if the crash wasn't caused by your own code, but...
Read more >Monitor Your Mobile App Health with Sentry and .NET MAUI
Once your app is released to the public it's hard to get any information from your users about crashes and other unforeseen behavior....
Read more >Multi-platform App UI (MAUI)
Easy MAUI integration by calling UseSentry on your MauiAppBuilder; All the features of our main .NET SDK, for your managed code; Native crash...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hi Matt, thanks for getting back to me so fast. Your summary looks correct.
Specifically, Credential Encrypted Storage is not accessible when the first booted and is setup with a screen lock. My broadcast has to be marked as
DirectBootAware
to get theLOCKED_BOOT_COMPLETED
broadcast in the first place.Either of these fixes works for me. The cleanest and simplest option could be to add a
UseDeviceEncryptedStorage
orDirectBootAware
property toSentryOptions.Android
which uses the cache directory from Device Encrypted Storage.To reiterate, this looks like:
The cache directory path option issue is fixed with the latest 3.24.0 release.
If you have any further issues with direct boot, please add them to #2057. Thanks. 😄