Skip to content
Merged
Next Next commit
fix: deliver system breadcrumbs in the main thread on Android
  • Loading branch information
jpnurmi committed Nov 5, 2025
commit 2012e84090b14b3d61d8ae242d424e0d8d2427e6
3 changes: 3 additions & 0 deletions src/Sentry.Bindings.Android/Transforms/Metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@
</method>
</add-node>

<!-- Remove problematic deprecated methods in the IScopes interface -->
<remove-node path="/api/package[@name='io.sentry']/interface[@name='IScopes']/method[@deprecated]" />

<!--
TODO: If we need this, figure out how to multi-target or late bind.
This API uses FrameMetrics, which requires Android >= 24.0. We currently target Android >= 21.0 which is the minimum supported by MAUI.
Expand Down
12 changes: 6 additions & 6 deletions src/Sentry/Platforms/Android/AndroidDiagnosticLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ namespace Sentry.Android;

internal class AndroidDiagnosticLogger : JavaObject, JavaSdk.ILogger
{
private readonly IDiagnosticLogger _logger;
private readonly IDiagnosticLogger? _logger;

public AndroidDiagnosticLogger(IDiagnosticLogger logger) => _logger = logger;
public AndroidDiagnosticLogger(IDiagnosticLogger? logger) => _logger = logger;

public void Log(JavaSdk.SentryLevel level, string message, JavaObject[]? args) =>
_logger.Log(level.ToSentryLevel(), "Android: " + FormatJavaString(message, args));
_logger?.Log(level.ToSentryLevel(), "Android: " + FormatJavaString(message, args));

public void Log(JavaSdk.SentryLevel level, string message, Throwable? throwable) =>
_logger.Log(level.ToSentryLevel(), "Android: " + message, throwable);
_logger?.Log(level.ToSentryLevel(), "Android: " + message, throwable);

public void Log(JavaSdk.SentryLevel level, Throwable? throwable, string message, params JavaObject[]? args) =>
_logger.Log(level.ToSentryLevel(), "Android: " + FormatJavaString(message, args), throwable);
_logger?.Log(level.ToSentryLevel(), "Android: " + FormatJavaString(message, args), throwable);

public bool IsEnabled(JavaSdk.SentryLevel? level) =>
level != null && _logger.IsEnabled(level.ToSentryLevel());
level != null && _logger != null && _logger.IsEnabled(level.ToSentryLevel());

private static string FormatJavaString(string s, JavaObject[]? args) =>
args is null ? s : JavaString.Format(s, args);
Expand Down
2 changes: 2 additions & 0 deletions src/Sentry/Platforms/Android/Sentry.Android.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<Using Include="Android.Runtime" />
<Using Include="Android.Content.Context" Alias="AndroidContext" />
<Using Include="Android.OS.Build" Alias="AndroidBuild" />
<Using Include="Android.OS.Looper" Alias="AndroidLooper" />
<Using Include="Android.OS.Handler" Alias="AndroidHandler" />
<Using Include="Java.Lang.Boolean" Alias="JavaBoolean" />
<Using Include="Java.Lang.Class" Alias="JavaClass" />
<Using Include="Java.Lang.Double" Alias="JavaDouble" />
Expand Down
12 changes: 12 additions & 0 deletions src/Sentry/Platforms/Android/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using Sentry.Android.Callbacks;
using Sentry.Android.Extensions;
using Sentry.Extensibility;
using Sentry.JavaSdk;
using Sentry.JavaSdk.Android.Core;
using Sentry.JavaSdk.Android.Core.Internal.Util;

// Don't let the Sentry Android SDK auto-init, as we do that manually in SentrySdk.Init
// See https://docs.sentry.io/platforms/android/configuration/manual-init/
Expand Down Expand Up @@ -155,6 +157,16 @@ private static void InitSentryAndroidSdk(SentryOptions options)

// Don't capture managed exceptions in the native SDK, since we already capture them in the managed SDK
o.AddIgnoredExceptionForType(JavaClass.ForName("android.runtime.JavaProxyThrowable"));

// Deliver network and system event breadcrumbs in the main thread
// See https://github.com/getsentry/sentry-dotnet/issues/3828
var networkLogger = new AndroidDiagnosticLogger(options.DiagnosticLogger);
var buildInfoProvider = new BuildInfoProvider(networkLogger);
var timeProvider = AndroidCurrentDateProvider.Instance!;
var mainHandler = new AndroidHandler(AndroidLooper.MainLooper!);
o.ConnectionStatusProvider =
new AndroidConnectionStatusProvider(AppContext, o, buildInfoProvider, timeProvider, mainHandler).JavaCast<IConnectionStatusProvider>();
o.AddIntegration(new SystemEventsBreadcrumbsIntegration(AppContext, mainHandler).JavaCast<JavaSdk.IIntegration>());
Comment thread
jpnurmi marked this conversation as resolved.
Comment thread
jpnurmi marked this conversation as resolved.
Comment thread
jpnurmi marked this conversation as resolved.
});

// Now initialize the Android SDK (with a logger only if we're debugging)
Expand Down