Automated Android Crash Reports with ACRA and Cloudant
Posted On:
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 is 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 the Developer's Console, allowing you to address the culprit bug.This all sound 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 sound 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?
Introducing ACRA
ACRA stands for "Automated Crash Reporting for Android". It's a free library that lets you solve the 'manual error reporting' problem with a few lines of code. Once you've implemented the library and everything has been properly initialized, you'll be able to extract the same Android error logs as the Google default (plus a bunch of added customization options) automatically and without requiring the user to take action.Beyond that, ACRA lets you choose how you'd like to inform the user of an Android crash, with the default being silent background reporting, and alternatives including customized dialogs.
Until recently, ACRA was backed by Google Spreadsheet, which meant that you were able to receive all your reports in a single file, hosted for free on your Google Drive account. Unfortunately, Google requested that we not use this option in the future, so we're left with a couple of alternatives for sending in crash report data, some of which we will cover in this tutorial:
- Standard email (still requires user interaction).
- Custom email/HTTP client (requires extensive setup).
- Custom back-end (with options ranging from free to commercial solutions).
Setting up a Cloudant back-end
The first thing we need to do is register a Cloudant account. Of course, there's a catch: Cloudant's services are not entirely free, but according to their pricing page it's very unlikely that you'll exceed the monthly $5 limit (unless you have huge user base and a ton of bugs in your code).Once we've registered, we need to understand how things work. At a high level, our back-end will consist of two components:
- A storage database or, to be more precise, an Apache CouchDB. CouchDB stores its data in JSON format, which means that all reports sent from the Android device must match the format in order to be inserted as an entry. A database insert is a simple HTTP POST or PUT request.
- A web app (for analysis) or, to be more precise, a CouchApp. This is a simple JavaScript application that lets you run queries and display the data stored in the CouchDB instance.
Let's go ahead and replicate an empty ACRA CouchDB:
- Select the 'Replication' section in your Cloudant dashboard.
- As the source database, select 'Remote database' with http://get.acralyzer.com/distrib-acra-storage as the URL.
- As the target database, select 'New database' and name it "acra-{myapp}" (without the quotation marks). Note that the {myapp} parameter should be unique to your app, and that the database name must start with "acra-".
- Click 'Replicate'.
- Select the 'Replication' section in your Cloudant dashboard.
- As the source database, select 'Remote database' with http://get.acralyzer.com/distrib-acralyzer as the URL.
- As the target database, select 'New database' and name it "acralyzer".
- Click 'Replicate'.
The last step of the initial setup process is to add security permissions. Cloudant provides its own security layer over CouchDB with finer control on individual rights, so in order to write a report to our database we need to create a user account with write permissions:
- Select the 'Database' section in your Cloudant dashboard.
- Click the permissions section (lock icon) for the acra-{myapp} database.
- Click 'Generate API keys'.
- Write down the generated username and password (we'll use them later).
- Add write permissions for the generated username.
Visualizing Android crash reports with acralyzer
Once replicated, the acralyzer dashboard can be easily accessed by followinghttps://{myapp}.cloudant.com/acralyzer/_design/acralyzer/index.html#/dashboard
. I'll admit: it's not the prettiest analytics tool out there, but it serves its purpose.From the top menu, you can select which database you want to visualize (it is possible to host multiple databases for different apps in a single project; this will affect your usage quota) and preview the data in the main dashboard. For example, you can:
- Plot the number of reports by unit of time (hour, day, month, etc.).
- View the distribution of reports by Android-specific metrics (Android version, SDK version, app version, device, etc.).
- List all crash reports (with a detailed stack trace) or view all bugs (here, a "bug" is a group of identical reports sourced from different users).
- Preview details for a single bug and set its status as resolved (if fixed).
- Purge old or obsolete entries.
- APP_VERSION_CODE
- APP_VERSION_NAME
- ANDROID_VERSION
- PACKAGE_NAME
- REPORT_ID
- BUILD
- STACK_TRACE
Implementing ACRA in your Android project
As previously mentioned in this tutorial, implementing ACRA is very easy and just requires a few quick steps.Add dependency
First, we need to include the library as a dependency in one of the following ways:- As a .jar file in your /libs folder.
- As a maven dependency:
<dependency>
<groupId>ch.acragroupId>
<artifactId>acraartifactId>
<version>X.Y.Zversion>
dependency> - As a gradle dependency:
compile 'ch.acra:acra:X.Y.Z'
Add Application class
Next, we need to add an Android Application class to our project (or update an existing class, as there can only be one instance) and declare it in the AndroidManifest.xml: android:name=".MyApp"
android:theme="@style/AppTheme">
...
And setup ACRA there:@ReportsCrashes(
formUri = "https://{myusername}.cloudant.com/acra-{myapp}/_design/acra-storage/_update/report",
reportType = HttpSender.Type.JSON,
httpMethod = HttpSender.Method.POST,
formUriBasicAuthLogin = "GENERATED_USERNAME_WITH_WRITE_PERMISSIONS",
formUriBasicAuthPassword = "GENERATED_PASSWORD",
formKey = "", // This is required for backward compatibility but not used
customReportContent = {
ReportField.APP_VERSION_CODE,
ReportField.APP_VERSION_NAME,
ReportField.ANDROID_VERSION,
ReportField.PACKAGE_NAME,
ReportField.REPORT_ID,
ReportField.BUILD,
ReportField.STACK_TRACE
},
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.toast_crash
)
publicclassMainAppextendsApplication {
@Override
publicvoidonCreate() {
super.onCreate();
// The following line triggers the initialization of ACRA
ACRA.init(this);
}
}
That's it! Of course, you'll need to replace all the {myapp} placeholders with actual values, as well as values for formUriBasicAuthLogin
and formUriBasicAuthPassword
.As you can see from the above code snippet, we're only using the required report fields. Feel free to add any other fields that may be relevant to your application.
You can also choose to use PUT instead of POST. In that case, the
REPORT_ID
will be appended to the end of the former
as a parameter.Finally, you can also choose how the user is informed of the Android app's crash, the default being a silent background report. In our case, we choose to display a Toast message letting the user know that the crash has been reported and a bug fix should be available soon.
Need help? Here's a sample project
To see ACRA in action, I've setup the acra_examplerepo on GitHub. It features a simple app that initializes ACRA on start up and let's you crash it by pressing a button (which then triggers a null pointer exception). The crash data is sent to an example Cloudant database that can be visualized here.To view the data, log in with the following credentials:
- Username: medo
- Password: acraexample
Alternatives to ACRA
ACRA isn't the only option for automated Android error reporting. Since crashes are bound to happen, there's a big business-to-developer (B2D) market out there attempting to monetize their resolution.Crittercism, for example, is a very mature platform for crash reporting. It looks great, offers a bunch of options for data analysis, and is very easy to integrate. The only downside: price, and the free trial is fairly limited in terms of number of active users, days of data retention, and support). BugSense is a similar service.
In my opinion, however, Crashlytics is a superior solution. Until recently, Crashlytics had a freemium model (with a paid premium tier); but now (after their acquisition by Twitter), all the formerly-premium features are available for free. There are no usage costs, fees, or limits. This is the preferred means of error reporting for a lot of high profile and high ranking companies and developers, as it's very easy to use and offers powerful analytics and visualization tools. It even integrates with most popular IDEs as a plugin (e.g., Eclipse, Android Studio), so adding Crashlytics to your app is as simple as selecting a project and pressing a button. These plugins also enables you to track crash reports from your IDE without having to open up a browser.
So, why use ACRA then when there are other alternatives out there that look way better and offer more features for the same implementation effort? I'll give you two reasons.
- All these other options are closed source, proprietary software. Even with a basket full of EULAs, you can't be sure exactly how your data is gathered and handled. On the other hand, ACRA and acralyzer are open source projects hosted on GitHub that you can easily fork and tailor to your needs.
- Data mobility. Let's say you're unsatisfied with Cloudant. It's a breeze to replicate and migrate your data to another back-end. You're guaranteed that the data stays yours.
In conclusion
ACRA is a highly robust and highly customizable library that can be utilized alongside Cloudant and acralyzer to achieve free, automated crash reporting and basic analytics for your app, all for minimal implementation effort.Writing reliable Android code requires a lot of experience and foresight, but none of us are truly omniscient. Be prepared for the unexpected crashes and errors, and be ready to fix the unexpected as soon as possible. That's the kind of work that goes into great products and great user experiences.