ACRA (Automated Crash Reporting for Android)

Abhishek Srivastava
7 min readAug 10, 2020

--

One truth about developing a mobile application is there are so many constraints, for example, a hardware limitation (CPU, RAM, Battery, etc). If your code design is not good enough, prepare to say hi to the most critical problem on earth: “Crash”. According to a study, it shows that:

Application Crashing is the most complained problem from mobile app user.

and moreover

If application crashes 3 times in a row, about half of users will remove it from their phone.

Crash Tracking System, which lets developers collect every single detail of crash directly from the user’s device, has been invented to take care of this issue especially. The most two popular Crash Tracking System to date are Crashlytics and Parse Crash Reporting, which are both totally-free service. Developers could integrate any of them into their app without charge. Whenever application crashes, the whole stack trace will be sent to the backend which allows developers to fix every critical problem in the easiest manner. With this method, you would be able to deliver a Crash-Free Application in a very short time.

However, those data are collected in the service provider’s server which may raise some concern for a big company about user data privacy.

So … is there any crash tracking system that allows us to set up our own server? Of course, there is! And it is actually quite easy to set up one. Here we go Application Crash Reporting on Android (ACRA), a library enabling Android Application to automatically post their crash reports to our own server.

Introducing ACRA

ACRA has been around since 2010, originally on Google Code, and now on GitHub. It comes in the form of a library that you add to your app, with code that will get control when an unhandled exception occurs inside your app. There, ACRA carefully will collect information about the crash (e.g., the stack trace) and the environment (e.g., what version of Android the app was running on). ACRA can then deliver that information to you by any number of means, plus optionally provide feedback to the user about the crash itself. Since you control what ACRA collects and you control where ACRA sends the data, you can minimize how much information gets into the hands of third parties. The cost is an inconvenience, as either you have to:

  • Fuss with managing your own server for receiving the crashes.
  • Use a third-party service for that server, reducing some of the privacy.
  • Use options that are clunky for everyone involved, such as the user sending emails containing crash reports.

Why Android error reporting matters

So, what happens when an Android app crashes or becomes non-responsive? Well, the “Force Close” dialog pops up, letting the user know that something’s gone wrong. If the app was downloaded through Google Play, the user will be prompted to report the crash by sending a detailed Android crash report (including time, phone model, Android version, stack trace, etc.) that you (the developer) can view in the Developer’s Console, allowing you to address the culprit bug.

This all sounds very nice — but there’s a major problem with Android’s default error reporting: users tend not to use it, leaving developers clueless as to the state of their apps.

This all sounds very nice — but there’s a major problem with using Android’s default error reporting: users tend not to take action when their apps crash; in fact, the majority choose not to send in Android error reports. How then, can you, as a conscientious developer, gain reliable insights into your app’s crashes and failings?

How to use ACRA in Android Code:-

First, if want to use ACRA then must use one of them from below dependency as you want to add in a Maven Project or Gradle Project.

Installation

Maven

<dependency> 
<groupId>ch.acra</groupId>
<artifactId>acra</artifactId>
<version>4.9.2</version>
<type>aar</type>
</dependency>

Gradle

compile 'ch.acra:acra:4.9.2'

After Adding dependency you have to create or Modify Application class like below

ACRAHandler

The Application subclass that you create needs two items to configure ACRA: 1. A @ReportsCrashes annotation, providing the actual ACRA configuration itself.

2. A call to ACRA.init() from onCreate(), to initialize the ACRA crash detection subsystem and have it use the annotation to configure what to do when crashes occur.


@ReportsCrashes(
formUri = "https://backend-of-your-choice.com/",
reportType = REPORT_TYPES(JSON/FORM),
httpMethod = HTTP_METHOD(POST/PUT),
formUriBasicAuthLogin = "AUTH_USERNAME",
formUriBasicAuthPassword = "AUTH_PASSWORD,
customReportContent = {
ReportField.USER_APP_START_DATE,
ReportField.USER_CRASH_DATE,
ReportField.APP_VERSION_CODE,
ReportField.APP_VERSION_NAME,
ReportField.ANDROID_VERSION,
ReportField.DEVICE_ID,
ReportField.BUILD,
ReportField.BRAND,
ReportField.DEVICE_FEATURES,
ReportField.PACKAGE_NAME,
ReportField.REPORT_ID,
ReportField.STACK_TRACE,
},
mode = NOTIFICATION_TYPE(TOAST,DIALOG,NOTIFICATION)
resToastText = R.string.crash_text_toast)
public class ACRAHandler extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
final ACRAConfiguration config = new ConfigurationBuilder(this) .build(); // Initialise ACRA
ACRA.init(this, config);
}
}

@ReportsCrashes has many knobs to turn and switches to flip as part of configuring how ACRA should behave. We will look at a number of them in this chapter. This simple sample configures ACRA to:

  • Format the crash data as JSON ( reportType= org.acra.sender.HttpSender.Type.JSON )
  • Send it to the server indicated by the BuildConfig.ACRA_URL value we configured in Gradle (formUri=BuildConfig.ACRA_URL)
  • Use an HTTP PUT operation to hand that JSON over to that server (httpMethod=org.acra.sender.HttpSender.Method.PUT)
  • Where AUTH_USERNAME and AUTH_PASSWORD are the credentials of your desired backends.

Note that the ACRA.init() call is inside a check of the BuildConfig.ACRA_INSTALL boolean that we set up in the Gradle build files. If a particular build type or product flavor sets ACRA_INSTALL to false, ACRA will not be enabled. For simpler projects, rather than defining your own ACRA_INSTALL-style flag, you could just use!BuildConfig.DEBUG, to only configure ACRA on release builds. While there is nothing stopping you from using ACRA in development, you may find that it interferes somewhat with how you are used to debugging your crashes.

Example manifest:-

Make sure you have internet permission to receive the report from the crashed application so AndroidManifest needs to have the following modification:-

  • Declare your application class in the application element
  • Use must have to declare internet permission to send the report by email
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<!-- etc -->>
<!-- Internet is required. READ_LOGS are to ensure that the Logcat is transmitted-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_LOGS"/> <application
android:allowBackup="true"
android:name=".ACRAHandler"<!--Activates ACRA on startup -->
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- Activities -->
</application>
</manifest>

In case if you want to send the silent report to the backend then just use the below method to achieve it.

ACRA.getErrorReporter().handleSilentException(e);

Modes of ACRA Send Report:-

When you click the Button, ACRA will send a crash report to your designated server. What the user perceives, though, varies based upon configuration.

1. Default: “Silent”

If you do not specify otherwise in your ACRA configuration, the default behavior will be “silent”. In this case, “silent” means “the user is not told that a report is being sent via ACRA”. Instead, the user sees the traditional Android crash dialog, for whatever version of Android the app is running on:

Reported Crash, Silent Mode, However, there are several options that you can use instead of “silent” mode if you so choose. One — showing a Toast — is not an especially good idea, as the user might not be looking at the screen right then and might not see the message.

Dialog

Another option is the “dialog” approach, where the user is shown a dialog-themed activity, indicating what happened and allowing the user to provide some additional information.

On the plus side, this is more transparent to the user, and the user can provide a bit more detail that might be useful to you. However, the user can also cancel out of the dialog, in which case you do not receive a crash report at all.

Notification

While the dialog mode is great, it is unsuitable for crashes that may occur in the background. You do not want to pop a dialog box up unexpectedly, as users may not appreciate the interruption.

The default “silent” mode, for crashes originating in the background, will not show a dialog. This is far more suitable for background work, but it does not let the user know that a crash occurred.

The Notification mode serves as the middle ground. When a crash occurs in the background, ACRA raises a Notification. Tapping on that Notification, in turn, brings up the same dialog that the dialog mode uses.

To use this, switch your mode to ReportingInteractionMode.NOTIFICATION in the @ReportsCrashes annotation. Then, in addition to all the dialog configuration, add three more string resource references:

  • resNotifTickerText, shown as the “ticker text” of the Notification on Android 4.4 and below
  • resNotifTitle, shown as the title of the Notification in its tile in the notification tray
  • resNotifText, shown as the text of the Notification in its tile in the notification tray

Remarks:-

For more details like Server Setup for ACRA, Please read from below link:-

Thanks for reading…

--

--

Abhishek Srivastava

Senior Software Engineer | Android | Java | Kotlin | Xamarin Native Android | Flutter | Go