Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Paul Woitaschek edited this page · 43 revisions


This is ACRA's Advanced Usage Guide. You need to set up your project before using all the features described here.

If you have any question or comment regarding ACRA, post a message on the Discussion Group.


Integrating as a dependency with Maven or Gradle

ACRA is available on Maven central and can, as such, easily be integrated as a dependency of your project using the usual dependency management of your favorite build system.




dependencies {
    ... your other dependencies...
    compile 'ch.acra:acra:4.6.2'

User Interaction

The default behavior of ACRA is to send crash reports silently. From the application user point of view, the app has crashed with the usual "Force Close" dialog, and that's all. Though, a report has been sent without the user being aware of it.

Depending on the state of your application and your concern of your users data plan usage and private data handling, you might prefer notifying them that a crash report has been sent, or even ask him the authorization to send one... and why not ask him to describe what he was doing during the crash.

ACRA offers all these options, and allows you to customize your application crash reporting notifications.

In addition to a silent mode, 3 notification modes are available:

  • display a simple Toast with the text of your choice:

Toast Notification

  • display a status bar notification, then offering the user a dialog asking him to send the report or not, with an optional comment field:

Status bar ticker Status bar notification Dialog

  • since 4.3.0b1 - display the same dialog on application restart, without requiring a notification

Enabling user notification only requires you to add parameters to the @ReportsCrashes annotation and some string values to your resources.

Toast notification

                mode = ReportingInteractionMode.TOAST,
                forceCloseDialogAfterToast = false, // optional, default false
                resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {

In your strings.xml :

<string name="crash_toast_text">Ooooops ! I crashed, but a report has been sent to my developer to help fix the issue !</string>

The forceCloseDialogAfterToast option allows you to choose to display the Android native Force Close Dialog. Default is false to avoid warning users twice about a single issue, but your opinion about this may differ so the choice is yours.


Since 4.3.0b1

The DIALOG mode was introduced in ACRA 4.3, aimed at replacing the NOTIFICATION mode as it is more user friendly.

                mode = ReportingInteractionMode.DIALOG,
                resToastText = R.string.crash_toast_text, // optional, displayed as soon as the crash occurs, before collecting data which can take a few seconds
                resDialogText = R.string.crash_dialog_text,
                resDialogIcon = android.R.drawable.ic_dialog_info, //optional. default is a warning sign
                resDialogTitle = R.string.crash_dialog_title, // optional. default is your application name
                resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, // optional. When defined, adds a user text field input with this text resource as a label
                resDialogEmailPrompt = R.string.crash_user_email_label, // optional. When defined, adds a user email text entry with this text resource as label. The email address will be populated from SharedPreferences and will be provided as an ACRA field if configured.
                resDialogOkToast = R.string.crash_dialog_ok_toast // optional. displays a Toast message when the user accepts to send a report.
public class MyApplication extends Application {

In your strings.xml:

<string name="crash_toast_text">Ooooops ! I crashed, but a report has been sent to my developer to help fix the issue !</string>

<string name="crash_dialog_title">CrashTest has crashed</string>
<string name="crash_dialog_text">An unexpected error occurred forcing the
    application to stop. Please help us fix this by sending us error data,
    all you have to do is click OK.</string>
<string name="crash_dialog_comment_prompt">You might add your comments about the problem below:</string>
<string name="crash_dialog_ok_toast">Thank you !</string>

In your AndroidManifest.xml:

<application ...>


    <activity android:name="org.acra.CrashReportDialog"
        android:finishOnTaskLaunch="true" />



In your res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
  <style name="Theme.Dialog" parent="@android:style/Theme.Dialog" />

In your res/values-v14/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
  <style name="Theme.Dialog" parent="@android:style/Theme.DeviceDefault.Dialog" />

Status bar notification

This is a legacy feature, as Dialog mode is generally preferred. However, if you really want to use it, in addition to the changes in the DIALOG section, add the following values.

@ReportsCrashes(// Enter values from DIALOG section of wiki here!
                resNotifTickerText = R.string.crash_notif_ticker_text,
                resNotifTitle = R.string.crash_notif_title,
                resNotifText = R.string.crash_notif_text,
                resNotifIcon = android.R.drawable.stat_notify_error // optional. default is a warning sign
public class MyApplication extends Application {

In your strings.xml:

<!--Strings from Dialog section of wiki go here!-->
<string name="crash_notif_ticker_text">Unexpected error, please send a report...</string>
<string name="crash_notif_title">CrashTest has crashed...</string>
<string name="crash_notif_text">Please click here to help fix the issue.</string>

Reports destination

The default destination for reports is (was) a Google Docs Form, storing data in a Google Docs Spreadsheet. This storage had some great advantages:

Unfortunately, we have been asked by Google to stop making our users automatically post data to Google Forms just before the 'refresh' of this great tool published a few months ago. The current GoogleFormSender is working only on 'Legacy Forms'which can't be created anymore in Google Drive.

Please read the following notice for more details..

We are still providing the GoogleFormSender in ACRA 4.5.x but please note that this will be the last release including this reports storage solution. We won't provide any other sender for the 'refreshed' Google Forms either.

The following sections details the other possible destinations for your crash reports: custom script, email, third-party backend, or any other destination you can imagine (if you implement the sender). And you can even send reports to multiple destinations.

Sending reports to your own self-hosted script

Just use the formUri parameter of the @ReportsCrashes annotation in your Application class :

@ReportsCrashes(formKey = "", // will not be used
                formUri = "",
                formUriBasicAuthLogin = "yourlogin", // optional
                formUriBasicAuthPassword = "y0uRpa$$w0rd", // optional
                mode = ReportingInteractionMode.TOAST,
                resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {

The formUri can be over HTTPS (even with self signed certificates) and can require a BASIC HTTP authentication (pass your login and password with formUriBasicAuthLogin and formUriBasicAuthPassword).

With the default configuration, your script will receive a POST request with report fields as POST parameters named like the ReportField enum values.

Since ACRA v4.4.0, if you are sending reports over SSL using a self-signed certificate, you need to set the option ReportsCrashes.disableSSLCertValidation to true.

POST/PUT request

Since ACRA v4.5.0, you can choose to send reports via an HTTP PUT request rather than an HTTP POST request.

Switching to PUT is done by setting the httpMethod option to org.acra.sender.HttpSender.Method.PUT.

When using a PUT request, ACRA adds automatically the Report ID at the end of the formUri. For example, with the following ACRA configuration:

@ReportsCrashes(formKey = "", // will not be used
                formUri = "",
                formUriBasicAuthLogin = "yourlogin", // optional
                formUriBasicAuthPassword = "y0uRpa$$w0rd", // optional
                httpMethod = org.acra.sender.HttpSender.Method.PUT,
                mode = ReportingInteractionMode.TOAST,
                resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {

a new report is sent to fe24835f-8117-4639-bfea-f57c77205771 is a unique report identifier generated by ACRA (REPORT_ID field).

Data encoding (FORM/JSON)

The defaults settings encode reports data key/value pairs as a form-urlencoded string.

Since ACRA v4.5.0, you have the option to send reports data encoded as a detailed JSON tree structure. You can see here 2 examples of the data generated with the default set of ReportFields.

Switching to JSON is done by setting the configuration option reportType to org.acra.sender.HttpSender.Type.JSON.

Adjusting the socket timeout

If you are experiencing timeouts when sending reports, you can adjust the socket timeout with the socketTimeout option (time in milliseconds).

Sending reports by email

For some applications, sending reports to a Google Docs Form or other Http based solutions is not an option. The problem is that they require the INTERNET permission.

For pure offline applications, users might even be frightened to grant this permission and can be suspicious about the real goal of the app or the developer.

To get crash reports without granting INTERNET permission, you can use the mailTo setting from @ReportsCrashes:

@ReportsCrashes(formKey = "", // will not be used
                mailTo = "",
                mode = ReportingInteractionMode.TOAST,
                resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {

Including a full report could be quite difficult due to the data size. Default fields included in email reports are:

  • ReportField.USER_COMMENT
  • ReportField.APP_VERSION_NAME
  • ReportField.BRAND
  • ReportField.PHONE_MODEL
  • ReportField.CUSTOM_DATA
  • ReportField.STACK_TRACE

You can override the report fields list using the customReportContent option in the @ReportsCrashes annotation:

@ReportsCrashes(formKey = "", // will not be used
                mailTo = "",
                customReportContent = { ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT },                
                mode = ReportingInteractionMode.TOAST,
                resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {

Emails are sent with an ACTION_SEND intent. This means that the following steps are required for the application user before any report is sent:

  • pick preferred email client (if no default app set)
  • review & actually send the email

Implementing your own sender

Since ACRA v4.0, you can implement your own report sender:

public class YourOwnSender implements ReportSender {

    public YourOwnSender(... your params ...){
        // initialize your sender with needed parameters

    public void send(CrashReportData report) throws ReportSenderException {
        // Iterate over the CrashReportData instance and do whatever
        // you need with each pair of ReportField key / String value

Three ReportSender implementations are already available:

  • GoogleFormSender: (ACRA's default when formKey) send reports to a Google Form through HTTP POST requests with specific parameters naming.
  • HttpSender: (default when formUri is set) send reports to a server-side component located at a configurable URI via formUri. Reports can be sent via PUT or POST request and as FORM or JSON encoded data.
  • EmailIntentSender: keeps only a selected set of fields and puts them in an Intent to be send by another application.

Once your sender created, you have to declare it to ACRA. This is done in your Application class, in the onCreate() method, right after the ACRA.init() call:

    public void onCreate() {
        YourOwnSender yourSender = new YourOwnSender(whatever, parameters, needed);

For advanced usage, there is a full set of available methods to manage the list of active ReportSenders:

  • setReportSender(ReportSender): sets a new sender as the single active sender
  • addReportSender(ReportSender): adds a new sender to the list of active senders, without removing all previous active senders
  • removeReportSender(ReportSender): removes a specific instance of a sender
  • removeReportSenders(Class): removes all active instances of a specific ReportSender implementation
  • removeAllReportSenders(): clears the list of active ReportSenders

Customizing the Content of the Reports

ACRA provides lots of data about the device and the state of your application. There are some options to let you add even more data to help debugging.

Adding your own custom variables or traces in crash reports ("Breadcrumbs")

To help you track some specific issue, you can add custom data to reports.

Simply use the following method when certain events happen in your code :

ACRA.getErrorReporter().putCustomData("myKey", "myValue");

All your custom data (key/value pairs) will be added in the report column CUSTOM just before the crash (stack trace). Each key/value pair will be shown on one line. Note that each key is a set that can only be used once, without duplicates. So if you re-use the same key for a different value, then the old value will be deleted and replaced with the new value.

If you want the report to show "Breadcrumbs" to indicate which events happened in time order, just before a crash, then you need to track events using unique keys. Here's an example:

public static void trackBreadcrumb(String event) {
    ACRA.getErrorReporter().putCustomData("Event at " + System.currentTimeMillis(), event);

protected void onCreate(Bundle savedInstanceState) {

You can also use getCustomData("myVariable") and removeCustomData("myVariable") to get/remove data from the custom data map.

Adding logcat, eventlog or radiolog extracts to reports

You can enable adding a logcat extract to your reports by simply adding the READ_LOGS permission:

<manifest ...>
    <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>

The default behavior is to include the result of the following command:

    adb logcat -t 200 -v time

This results to 200 lines of logcat with date, invocation time, priority/tag, and PID of the originating process.

If this is not what you want, you can change this with your own command line using the logcatArguments in the @ReportsCrashes annotation. For example, if you prefer using:

    adb logcat -t 100 -v long ActivityManager:I MyApp:D *:S

then add this to you {@ReportsCrashes} config:

    logcatArguments = { "-t", "100", "-v", "long", "ActivityManager:I", "MyApp:D", "*:S" }

As you can see, you just have to split your command line arguments to a String array on each white space.

Note: you can find further information about how to use logcat here, logcat (used in the backend by ACRA) will be able to filter by tag, that you will need to keep constant in your application.

Note for experts: even if the -t XXX argument is only available since android 2.2, you can use it safely as ACRA emulates it for older devices.

In addition to the main default buffer, ACRA can retrieve the 2 other alternative buffers event and radio. If these data are of any use for you, you have to activate their collection:

  • add EVENTSLOG and RADIOLOG fields to the CrashReports-Template.csv file before creating your spreadsheet
  • copy the content of your new csv template and paste it in the @ReportsCrashes.customReportContent parameter.

Note: System logs may contain private data logged by other applications like user email address, calendar events, contacts data... You should consider [#Enable/disable_system_logs adding a user preference item to let your user choose to include system logs or not].

Warning: collecting long system logs might take quite some time and induce a latency right after your application crash. Include them only if you know how to analyze them and avoid collecting more than 100 lines.

Final note: READ_LOG permission is not granted to third-party apps anymore since Android 4.1 (JellyBean). Starting with this version, logcat provides only traces from your own app, without requiring a permission. JellyBean logcat logs are retrieved by ACRA starting with version 4.3.0b2

Adding your own log file extracts to reports

Since 4.3.0b1

If you chose to log your debug traces to an independent file (using for example android-logging-log4j, slf4j or logback-android), ACRA can get the latest lines from this file and send them in your reports.

Include the field APPLICATION_LOG in your customReportContent and spreadsheet template then configure it with:

  • @ReportsCrashes(applicationLogFile = "applog.log") to define the path/name of the log file
  • @ReportsCrashes(applicationLogFileLines = 150) to set the number of latest lines you want to be retrieved (default is 100).

Adding DropBoxManager events to your reports

DropBoxManager has been introduced in android API level 8 (2.2 - FroYo). This is a new logging system focused on persisting long chunks of text or data for debugging purposes. There is a Q&A on StackOverflow explaining the usage of this system.

As it is a rarely used feature, you need to enable it by including the field DROPBOX in your customReportContent.

You need the READ_LOGS permission to collect these data, add it to your manifest with:

<manifest ...>
    <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>

Note: READ_LOG permission is not granted to third-party apps anymore since Android 4.1 (JellyBean). Starting with this version, logcat provides only traces from your own app, without requiring a permission. JellyBean logcat logs are retrieved by ACRA starting with version 4.3.0b2

A list of DropBox tags has been built by searching for DropBoxManager usage in android source code. All these system tagged events can be retrieved if you set @ReportsCrashes.includeDropBoxSystemTags to true on your Application class:

  • system_app_anr
  • system_app_wtf
  • system_app_crash
  • system_server_anr
  • system_server_wtf
  • system_server_crash
  • data_app_strictmode

You can add your own dropbox tags using @ReportsCrashes.additionalDropBoxTags(), and set the max age in minutes for events to be retrieved using @ReportsCrashes.dropboxCollectionMinutes().

@ReportsCrashes { formKey="xxxxxxxxxxxx",
    inlcudeDropBoxSystemTags = true, // default is false
    additionalDropBoxTags = {"your_own_tag", "another_additional_tag"},
    dropboxCollectionMinutes = 10 // default is 5

Warning: collecting DropBox events might take quite some time and induce a latency right after your application crash. Increase the dropBoxCollectionMinutes only if you know what you are doing.

Adding the Device Unique ID to your reports

In some circumstances, tracking exactly which identified devices throw which report can be necessary. ACRA will include your users Device ID (IMEI for GSM and the MEID or ESN for CDMA phones) if you add the following permission to your application manifest:

<manifest ...>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

Note: This unique device ID is considered as private data as it could let you track users behaviors... You should consider adding a user preference item to let your user choose to include this device id or not.

Choosing which fields to be included in reports

You can change the default set of fields included in your reports using @ReportsCrashes(customReportContent = { array of ReportField }). For example:

import static ReportField.*;

@ReportsCrashes(formKey = "xxxxxxxxxxxxxxxx", 
                customReportContent = { APP_VERSION, ANDROID_VERSION, PHONE_MODEL, CUSTOM_DATA, STACK_TRACE, LOGCAT },                
                mode = ReportingInteractionMode.TOAST,
                resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {

If using GoogleDoc Forms as a backend, your spreadsheet has to be created with the same columns. One easy way to recreate it is to copy/paste the list of fields (without the array braces) in a new text file with .csv extension and import it in GoogleDocs.

Limiting your reports to what you really want and really use can help avoiding performance issues when collecting reports data. Only fields which are set in customReportContent are actually processed.

Adding custom SharedPreferences names

The system default SharedPreferences for your application are automatically collected in the SHARED_PREFERENCES field.

If your app contains multiple SharedPreferences files, or if you are using a non-default name, you can add them by providing their names with:


Note: your shared preferences file name is set when you declare your SharedPreference class intances

context.getSharedPreferences("My file name to be used in acra", Context.MODE_PRIVATE);

Exclude SharedPreferences keys

Since 4.3.0b1

If your SharedPreferences contain private data that you don't want to be transmitted in reports, you can define exclusion rules using Regular Expressions provided in the excludeMatchingSharedPreferencesKeys configuration item.

Every key matching any of these regular expressions will be excluded from reports.


Exclude Settings keys

Since 4.5.0

Similarly to SharedPreferences, you may want to exclude some keys from the various settings fields collected by ACRA.

The configuration item to use is excludeMatchingSettingsKeys.

Letting your users control ACRA

Some ACRA behaviors can be configured by your application users through the use of SharedPreferences items:

  • enable/disable ACRA
  • enable/disable system logs
  • enable/disable including DeviceID
  • set an email address to be added to reports
  • enable/disable auto accept reports

You can store any ACRA SharedPreferences separately from your application SharedPreferences. To do so use the following @ReportsCrashes parameters:

  • sharedPreferencesName: Name of the SharedPreferences that will host the various acra.* preferences.
  • sharedPreferencesMode: The mode that you need for the SharedPreference file creation: Context.MODE_PRIVATE, Context.MODE_WORLD_READABLE or Context.MODE_WORLD_WRITEABLE.

Enable/disable ACRA

Add to your preferences xml file a CheckBoxPreference (checking it disables ACRA) :

<CheckBoxPreference android:key="acra.disable"

Or if you prefer the opposite (checking it to enable ACRA):

<CheckBoxPreference android:key="acra.enable"

Then add to your strings.xml files the 3 corresponding string resources.

Enable/disable system logs

Including logcat extracts in reports is a great tool for developers, but it can lead to privacy issues as some other applications might log private data like user account names, opened URLs, calendar events...

Giving your users a way to control the inclusion of logcat data make them understand that you care about their privacy. This can be done with the inclusion of the following CheckBoxPreference:

 <CheckBoxPreference android:key="acra.syslog.enable"

Of course you have to define the matching strings in your strings.xml files.

Enable/disable including DeviceID

If you added the READ_PHONE_STATE permission to your application but want to let your user be able to disable the inclusion of their Device ID in crash reports, you can include the following CheckBoxPreference:

 <CheckBoxPreference android:key="acra.deviceid.enable"

Don't forget to add the required strings in your strings.xml files.

Set an email address to be added to reports

Some users might be willing to help debugging your app. You can ask them to input an email address that will be included in every report to allow you contact them:

 <EditTextPreference android:key=""

Enable/disable auto accept reports

While in NOTIFICATION or DIALOG mode, you can allow your users to choose to auto-accept sending all reports. This is like letting them switch from NOTIFICATION/DIALOG mode to TOAST mode.

 <CheckBoxPreference android:key="acra.alwaysaccept"

Sending reports for caught exceptions or for unexpected application state without any exception

As a good programmer, your code is full of try/catch statements, and sometimes an interesting (unexpected) exception might be caught in one of these.

You could also want your application to send a report without any Exception thrown, just because you know that your application is in an unexpected state.

Both of these needs can be covered by this :


You can provide any caught or custom Exception, or even null if you don't have any to provide.

If you need to add silent trace reports whatever notification mode you configured for your application, you can also use:


Dynamic Configuration

Since 4.3.0b1

Every @ReportsCrashes parameter can also be set on runtime. This was needed since ADT 17 where Android Library Projects could not be used with ACRA due to their resources identifiers not being final fields anymore. Some advanced developers also needed to adjust ACRA parameters depending on user choices or when enablig special debug modes.

The method ACRA.getConfig() returns an ACRAConfiguration object which provides a setter for each @ReportsCrashes configuration item.

You can even use ACRA.getNewDefaultConfig(Application) to create a new configuration object initialized with default values + values set in your annotation parameters, modify some values, keep the object in memory for later use, and set it to ACRA.setConfig(ACRAConfiguration) when needed.

Catching Application Not Responding errors (ANR)

ACRA has no integrated system to monitor your app and send reports when it's not responding.

There is an interesting approach provided by Salomon Brys on Github. Its watchdog thread tries to execute a small code every 5 seconds and throws an exception if it failed. This exception will be reported by ACRA.

Catching Native Code errors

ACRA does not catch errors occurring in native code. We currently don't know any stable solution to catch native errors with ACRA.

Something went wrong with that request. Please try again.