I have successfully implemented Firebase Crash Reporting, but I need to disable the service when the app is running undo the \'debug\' Build Variant, in order to avoid non-r
public class MyApp extends Application {
public static boolean isDebuggable;
public void onCreate() {
super.onCreate();
isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
FirebaseCrash.setCrashCollectionEnabled(!isDebuggable);
}
}
in my Application class, onCreate()
if (BuildConfig.DEBUG) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
Log.wtf("Alert", paramThrowable.getMessage(), paramThrowable);
System.exit(2); //Prevents the service/app from freezing
}
});
}
It works because it takes the oldHandler, which includes the Firebase one
final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();
out of the processing path
As has been said before - there is no official way to do this. But the worst workaround for me as mentioned @mark-d is to reset DefaultUncaughtExceptionHandler
(https://stackoverflow.com/a/39322734/4245651).
But if you just call System.exit(2)
as was suggested - the app will be instantly closed on exception, without any dialog message and hard getting debug logs. If this is important to you, there is a way to restore default handler:
if (BuildConfig.DEBUG) {
final Thread.UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler();
if (currentHandler.getClass().getPackage().getName()
.startsWith("com.google.firebase")) {
final Thread.UncaughtExceptionHandler defaultHandler =
getPrivateFieldByType(currentHandler, Thread.UncaughtExceptionHandler.class);
Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
}
}
Where
public static <T> T getPrivateFieldByType(Object obj, Class<T> fieldType) {
if (obj != null && fieldType != null) {
for (Field field : obj.getClass().getDeclaredFields()) {
if (field.getType().isAssignableFrom(fieldType)) {
boolean accessible = field.isAccessible();
if (!accessible) field.setAccessible(true);
T value = null;
try {
//noinspection unchecked
value = (T) field.get(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!accessible) field.setAccessible(false);
return value;
}
}
}
return null;
}
First you will have to create debug
and release
build variants and then set a variable with boolean value. Then you will need to get that value from your java file which extends application
i.e from where you enable Fabric
crash reporting.
A code example is given below.
In your app's build.gradle
file, add the following lines to create 2 build variants debug
and release
and then add a variable with boolean value.
defaultConfig {
buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'true'
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix 'DEBUG'
buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'false'
}
release {
minifyEnabled false
}
}
Then when you are trying to add Fabric
crash reporting check the value for ENABLE_ANALYTICS
public class Test extends Application {
private GoogleAnalytics googleAnalytics;
private static Tracker tracker;
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.ENABLE_ANALYTICS)
Fabric.with(this, new Crashlytics());
}
}
You can see the value for ENABLE_ANALYTICS
by ctrl
+ click on the value. Hope this helps.