diff --git a/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java b/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java index 6f35b5e..36b2350 100644 --- a/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java +++ b/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java @@ -59,6 +59,7 @@ public final class CustomActivityOnCrash { //Extras passed to the error activity private static final String EXTRA_CONFIG = "cat.ereza.customactivityoncrash.EXTRA_CONFIG"; + private static final String EXTRA_CUSTOM_CRASH_DATA = "cat.ereza.customactivityoncrash.EXTRA_CUSTOM_CRASH_DATA"; private static final String EXTRA_STACK_TRACE = "cat.ereza.customactivityoncrash.EXTRA_STACK_TRACE"; private static final String EXTRA_ACTIVITY_LOG = "cat.ereza.customactivityoncrash.EXTRA_ACTIVITY_LOG"; @@ -153,6 +154,11 @@ public static void install(@Nullable final Context context) { } intent.putExtra(EXTRA_STACK_TRACE, stackTraceString); + CustomCrashDataCollector collector = config.getCustomCrashDataCollector(); + if (collector != null) { + intent.putExtra(EXTRA_CUSTOM_CRASH_DATA, collector.onCrash(intent)); + } + if (config.isTrackActivities()) { StringBuilder activityLogStringBuilder = new StringBuilder(); while (!activityLog.isEmpty()) { @@ -277,6 +283,17 @@ public static String getStackTraceFromIntent(@NonNull Intent intent) { return intent.getStringExtra(CustomActivityOnCrash.EXTRA_STACK_TRACE); } + /** + * Given an Intent, returns the custom collector trace extra from it. + * + * @param intent The Intent. Must not be null. + * @return The custom collector trace, or null if not provided. + */ + @Nullable + public static String getCustomCrashDataFromIntent(@NonNull Intent intent) { + return intent.getStringExtra(CustomActivityOnCrash.EXTRA_CUSTOM_CRASH_DATA); + } + /** * Given an Intent, returns the config extra from it. * @@ -348,6 +365,13 @@ public static String getAllErrorDetailsFromIntent(@NonNull Context context, @Non errorDetails += "\nUser actions: \n"; errorDetails += activityLog; } + + String customTrace = getCustomCrashDataFromIntent(intent); + if (customTrace != null) { + errorDetails += "\nCustom trace: \n"; + errorDetails += customTrace; + } + return errorDetails; } @@ -729,4 +753,11 @@ public interface EventListener extends Serializable { void onCloseAppFromErrorActivity(); } + + /** + * Interface to be called to register a custom crash data collector + */ + public interface CustomCrashDataCollector extends Serializable { + String onCrash(Intent intent); + } } diff --git a/library/src/main/java/cat/ereza/customactivityoncrash/config/CaocConfig.java b/library/src/main/java/cat/ereza/customactivityoncrash/config/CaocConfig.java index 164d945..c3bbd01 100644 --- a/library/src/main/java/cat/ereza/customactivityoncrash/config/CaocConfig.java +++ b/library/src/main/java/cat/ereza/customactivityoncrash/config/CaocConfig.java @@ -51,6 +51,7 @@ public class CaocConfig implements Serializable { private Integer errorDrawable = null; private Class errorActivityClass = null; private Class restartActivityClass = null; + private CustomActivityOnCrash.CustomCrashDataCollector customCrashDataCollector = null; private CustomActivityOnCrash.EventListener eventListener = null; @BackgroundMode @@ -129,6 +130,15 @@ public void setErrorActivityClass(@Nullable Class errorActiv this.errorActivityClass = errorActivityClass; } + @Nullable + public CustomActivityOnCrash.CustomCrashDataCollector getCustomCrashDataCollector() { + return customCrashDataCollector; + } + + public void setCustomCrashDataCollector(@Nullable CustomActivityOnCrash.CustomCrashDataCollector collector) { + this.customCrashDataCollector = collector; + } + @Nullable public Class getRestartActivityClass() { return restartActivityClass; @@ -165,6 +175,7 @@ public static Builder create() { config.minTimeBetweenCrashesMs = currentConfig.minTimeBetweenCrashesMs; config.errorDrawable = currentConfig.errorDrawable; config.errorActivityClass = currentConfig.errorActivityClass; + config.customCrashDataCollector = currentConfig.customCrashDataCollector; config.restartActivityClass = currentConfig.restartActivityClass; config.eventListener = currentConfig.eventListener; @@ -284,6 +295,23 @@ public Builder errorActivity(@Nullable Class errorActivityCl return this; } + /** + * Sets the custom error data collector class to launch when a crash occurs. + * If null, the default error activity will be used. + * + * @param collector The data collector. + * @throws IllegalArgumentException if the collector is an inner or anonymous class + */ + @NonNull + public Builder customCrashDataCollector(@Nullable CustomActivityOnCrash.CustomCrashDataCollector collector) { + if (collector != null && collector.getClass().getEnclosingClass() != null && !Modifier.isStatic(collector.getClass().getModifiers())) { + throw new IllegalArgumentException("The event listener cannot be an inner or anonymous class, because it will need to be serialized. Change it to a class of its own, or make it a static inner class."); + } else { + config.customCrashDataCollector = collector; + } + return this; + } + /** * Sets the main activity class that the error activity must launch when a crash occurs. * If not set or set to null, the default launch activity will be used.