From 897c58298a863e1e99a6bac9f4d7b46ad8289d30 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 5 Mar 2025 14:47:00 +0100 Subject: [PATCH 1/2] hook into lifecycles --- package-dev/Runtime/SentryInitialization.cs | 72 +++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/package-dev/Runtime/SentryInitialization.cs b/package-dev/Runtime/SentryInitialization.cs index 918cc2165..82f90bed9 100644 --- a/package-dev/Runtime/SentryInitialization.cs +++ b/package-dev/Runtime/SentryInitialization.cs @@ -55,6 +55,8 @@ public static class SentryInitialization #endif public static void Init() { + RegisterAndroidCallbacks(); + var unityInfo = new SentryUnityInfo(); // Loading the options invokes the ScriptableOption`Configure` callback. Users can disable the SDK via code. var options = ScriptableSentryUnityOptions.LoadSentryUnityOptions(unityInfo); @@ -81,6 +83,76 @@ public static void Init() } } + private static void RegisterAndroidCallbacks() + { +#if UNITY_ANDROID && !UNITY_EDITOR + try + { +using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) +using (var activity = unityPlayer.GetStatic("currentActivity")) +using (var application = activity.Call("getApplication")) +{ + AndroidJavaProxy lifecycleCallbacks = new AndroidLifecycleCallbacks(); + + // Properly register the callbacks with the application + application.Call("registerActivityLifecycleCallbacks", lifecycleCallbacks); + + Debug.Log("Android lifecycle callbacks registered successfully"); +} + } + catch (Exception ex) + { + Debug.LogError($"Error setting up Android lifecycle callbacks: {ex}"); + } +#endif + } + + private class AndroidLifecycleCallbacks : AndroidJavaProxy + { + public AndroidLifecycleCallbacks() : base("android.app.Application$ActivityLifecycleCallbacks") { } + + // Called when the activity is paused - app going to background + public void onActivityPaused(AndroidJavaObject activity) + { + Debug.Log("Android: Application moved to background (onActivityPaused)"); + // You can add your background transition handling here + } + + // Called when the activity is resumed - app coming to foreground + public void onActivityResumed(AndroidJavaObject activity) + { + Debug.Log("Android: Application moved to foreground (onActivityResumed)"); + // You can add your foreground transition handling here + } + + // The following methods are required to implement the interface + // but may not be needed for your background detection + public void onActivityCreated(AndroidJavaObject activity, AndroidJavaObject savedInstanceState) + { + Debug.Log("Android: Activity created"); + } + + public void onActivityStarted(AndroidJavaObject activity) + { + Debug.Log("Android: Activity started"); + } + + public void onActivityStopped(AndroidJavaObject activity) + { + Debug.Log("Android: Activity stopped"); + } + + public void onActivitySaveInstanceState(AndroidJavaObject activity, AndroidJavaObject outState) + { + // No action needed + } + + public void onActivityDestroyed(AndroidJavaObject activity) + { + Debug.Log("Android: Activity destroyed"); + } + } + private static void SetupNativeSdk(SentryUnityOptions options, SentryUnityInfo unityInfo) { try From 8a4a1c9cf7add86b512a7a5e9a4db2729ca2bded Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 5 Mar 2025 14:54:54 +0100 Subject: [PATCH 2/2] . --- package-dev/Runtime/SentryInitialization.cs | 74 ++++++++------------- 1 file changed, 28 insertions(+), 46 deletions(-) diff --git a/package-dev/Runtime/SentryInitialization.cs b/package-dev/Runtime/SentryInitialization.cs index 82f90bed9..5620c45aa 100644 --- a/package-dev/Runtime/SentryInitialization.cs +++ b/package-dev/Runtime/SentryInitialization.cs @@ -15,6 +15,7 @@ #endif using System; +using JetBrains.Annotations; using Sentry.Extensibility; #if UNITY_2020_3_OR_NEWER using System.Buffers; @@ -55,13 +56,14 @@ public static class SentryInitialization #endif public static void Init() { - RegisterAndroidCallbacks(); - var unityInfo = new SentryUnityInfo(); // Loading the options invokes the ScriptableOption`Configure` callback. Users can disable the SDK via code. var options = ScriptableSentryUnityOptions.LoadSentryUnityOptions(unityInfo); if (options != null && options.ShouldInitializeSdk()) { + // Register LifeCycle Callbacks so the SDK is aware of the app losing focus during startup + RegisterAndroidCallbacks(options.DiagnosticLogger); + // Certain integrations require access to preprocessor directives so we provide them as `.cs` and // compile them with the game instead of precompiling them with the rest of the SDK. // i.e. SceneManagerAPI requires UNITY_2020_3_OR_NEWER @@ -83,74 +85,54 @@ public static void Init() } } - private static void RegisterAndroidCallbacks() + private static void RegisterAndroidCallbacks([CanBeNull] IDiagnosticLogger logger) { #if UNITY_ANDROID && !UNITY_EDITOR + logger?.LogError("Registering Android LifeCycleCallbacks."); + try { -using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) -using (var activity = unityPlayer.GetStatic("currentActivity")) -using (var application = activity.Call("getApplication")) -{ - AndroidJavaProxy lifecycleCallbacks = new AndroidLifecycleCallbacks(); - - // Properly register the callbacks with the application - application.Call("registerActivityLifecycleCallbacks", lifecycleCallbacks); + using var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + using var activity = unityPlayer.GetStatic("currentActivity"); + using var application = activity.Call("getApplication"); + AndroidJavaProxy lifecycleCallbacks = new AndroidLifecycleCallbacks(logger); - Debug.Log("Android lifecycle callbacks registered successfully"); -} + application.Call("registerActivityLifecycleCallbacks", lifecycleCallbacks); } catch (Exception ex) { - Debug.LogError($"Error setting up Android lifecycle callbacks: {ex}"); + logger?.LogError("Failed to register Android LifeCycleCallbacks."); } #endif } private class AndroidLifecycleCallbacks : AndroidJavaProxy { - public AndroidLifecycleCallbacks() : base("android.app.Application$ActivityLifecycleCallbacks") { } + [CanBeNull] private IDiagnosticLogger _logger; - // Called when the activity is paused - app going to background - public void onActivityPaused(AndroidJavaObject activity) - { - Debug.Log("Android: Application moved to background (onActivityPaused)"); - // You can add your background transition handling here - } - - // Called when the activity is resumed - app coming to foreground - public void onActivityResumed(AndroidJavaObject activity) + public AndroidLifecycleCallbacks([CanBeNull] IDiagnosticLogger logger) : base( + "android.app.Application$ActivityLifecycleCallbacks") { - Debug.Log("Android: Application moved to foreground (onActivityResumed)"); - // You can add your foreground transition handling here + _logger = logger; } - // The following methods are required to implement the interface - // but may not be needed for your background detection - public void onActivityCreated(AndroidJavaObject activity, AndroidJavaObject savedInstanceState) - { - Debug.Log("Android: Activity created"); - } - - public void onActivityStarted(AndroidJavaObject activity) - { - Debug.Log("Android: Activity started"); - } - - public void onActivityStopped(AndroidJavaObject activity) + // App going to background + public void onActivityPaused(AndroidJavaObject activity) { - Debug.Log("Android: Activity stopped"); + _logger?.LogInfo("Application move to background. Pausing session."); } - public void onActivitySaveInstanceState(AndroidJavaObject activity, AndroidJavaObject outState) + // App coming to foreground + public void onActivityResumed(AndroidJavaObject activity) { - // No action needed + _logger?.LogInfo("Application move to foreground. Resuming session."); } - public void onActivityDestroyed(AndroidJavaObject activity) - { - Debug.Log("Android: Activity destroyed"); - } + public void onActivityCreated(AndroidJavaObject activity, AndroidJavaObject savedInstanceState) { } + public void onActivityStarted(AndroidJavaObject activity) { } + public void onActivityStopped(AndroidJavaObject activity) { } + public void onActivitySaveInstanceState(AndroidJavaObject activity, AndroidJavaObject outState) { } + public void onActivityDestroyed(AndroidJavaObject activity) { } } private static void SetupNativeSdk(SentryUnityOptions options, SentryUnityInfo unityInfo)