When apps crash, they generate logs containing information related to where the issues causing the crash occurred. Looking at these logs is a great place to start your effort toward diagnosing and fixing the crash.
To show you what I mean, I’m going to walk you through a root cause analysis after a crash in an example app called Short Code Manager. Short Code Manager is an Android app I built for this post. It’s supposed to do the following:
- Let users store short USSD codes like *123#
- Have a user interface (UI) enabling the app user to dial shortcodes directly from the app
Our Short Code Manager app is based on an app I built and published two years ago. The issue we’ll be diagnosing occurred in an early release of this app. For some users, the app crashed whenever they attempted to dial USSD codes from the app. I’m going to walk you through how I diagnosed and fixed this issue using crash logs.
Prerequisites
Before we get started, make sure you have the following so you can follow along:
- A recent version of the Android Studio IDE and Android SDK installed. You can get Android Studio for Windows, Mac, or Linux from the official download page. Android SDK will auto-install the first time you launch Android Studio.
- An Android device or emulator to run our example app. You can set up an emulator on Android Studio via the AVD Manager.
Source code for the example app is available here.
Getting the Crash Log
First, let’s walk through the four steps you need to follow to get the crash log after the app crashes. I’ll use Android Studio and run the example app on a physical Android phone. You can use an emulator as an alternative if you don’t have an Android phone.
1. Enable USB Debugging on Device
To enable communication between ADB and a physical Android device, we’ll need to turn Developer options on and enable USB debugging. The UI for doing this varies on different devices from different original equipment manufacturers (OEMs). To enable USB debugging on my Redmi device, which is running a recent build of the MIUI, I did the following:
- Opened settings and went to About phone
- Tapped on Build number (MIUI version on my device) multiple times until I got a message reading “You are now a developer”
- Went back to the main settings UI, selected Additional settings, and looked for Developer options—in Developer options, you can turn on USB debugging

If you’re going to run the app on an emulator, you can skip the above step. Also, run a Google search for something like “Enable USB debugging on Samsung device” if you’re using a Samsung phone. Replace the Samsung part with the actual name of your device manufacturer to get more device-specific instructions on how to enable USB debugging.
2. Install the App via Android Studio and ADB
Since we now have USB debugging enabled, Android Studio should be able to detect the Android device connected to our computer via a standard USB cable. If you’re connecting a device for the first time, a prompt might show up on your Android device requesting permission to let ADB connect. Make sure you accept the request.

Check “Always allow from this computer” to prevent the dialog box from appearing in the future.
Make sure your device or emulator is selected on the Android Studio device drop-down menu, and then hit the green play button to install the app like you usually do during debugging.

3. Producing the Crash
Now let’s crash our example app. After the app is installed and running, add some shortcodes using the app UI. Once some codes have been created and saved, let’s try to dial one of the codes. Originally, the app crashed only under certain circumstances, but for this post, I tweaked it so it crashes on the first try. This way, we can get the crash log message instantly. Of course, in real-life/production apps, crashes aren’t as easy to duplicate, but we’ll talk about this later.
To dial a code, we hit the phone icon next to the code on the app UI.

Afterward, our app crashes with a message like “Smart Code has stopped working…” and force closes.

4. Investigating the Crash
With our device connected via USB before the crash, Android Studio’s Logcat feature will display information about our app and the crash.
To switch to Logcat view on Android Studio, click on the Logcat label in the bottom tool window.

Below is the report from Logcat just after the crash occurred:

The Logcat window allows you to search and filter logs. Changing log level to Error will help trim things down so it’s easier to find the critical issue that caused the app to crash. The Logcat window also shows the current device and app (using the package name). You might also want to make sure you’re reading logs for the correct device and app.
The following info from the log trace gives some idea about why our app crashed:
java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxx cmp=com.android.server.telecom/.components.UserCallActivity }
Looking at the trace, you can see where the error occurred in our app, including the class and the line of code. From this, we know generally what happened and where we need to focus to start working on a fix.
5. Fixing the Crash
Fortunately, the log entry included enough information, so we were able to pinpoint which part of our code was in execution just before the crash. Creating event messages like this is key to being able to quickly identify what’s happening. If you’re interested in some best practices on creating event messages, check out the article on JSON logging.
Logcat shows our app crashed due to a security exception. In Android, before apps can use some OS features and services like the camera, phone calls, internet, and read/write storage, the app needs to request permission and the user must grant access.
Our example app requires permission to make phone calls (android.permission.CALL_PHONE), but the app currently doesn’t validate the permission has been granted. All I have is a method to kickstart the phone call. Not explicitly verifying the user has granted the required permission may lead to crashes on some devices and Android versions (Android 6.0 in our test).
To fix this issue, the app needs to verify users on the affected OS version have granted the necessary permissions before running the code to start a phone call. This can be done with an if statement or however else you prefer.
Frustration-free log management. (It’s a thing.)
Aggregate, organize, and manage your logs with PapertrailCrashing Is Inevitable. Burning Is Optional
By running the app on a device connected to Android Studio via ADB, we were able to view crash logs on Logcat. We then used the information from Logcat to isolate the issue with our app. Logcat also reports the class, method, and line of code associated with the crash. Thanks to this, we were able to quickly find the issue, understand what happened, and implement a fix.
Our example here is a simple case. In real-life/production apps, diagnosing issues is much more complex. Logcat is great for testing preproduction code. In production, however, the application may:
- be installed on hundreds, thousands, or even more devices;
- be installed on devices with various configurations (e.g., multiple Android versions);
- include user-specific logic to generate behavior for different users based on their account and user-generated content;
- or include integrations with external services or other applications.
In these cases, simply collecting and view the logs is challenging.
As a developer—especially an app developer—you know you can’t afford to release a buggy app. The best way to avoid issues is to catch them before your app goes live. Unfortunately, you can only test on a limited number of devices, and users are likely to interact with your apps in ways you can’t predict.
This means you need to actively monitor event logs to catch issues early. To avoid uninstalls or—worse—bad ratings, it’s important to catch and diagnose app crashes fast so you can work on getting a fix out to users quickly. A cloud-based logging service like SolarWinds® Papertrail™ can help in preproduction testing and in monitoring and troubleshooting production apps.
Papertrail bring logs from multiple services and applications together and lets you search them from a single UI. For crash logs, the tail feature in Papertrail is one I use frequently. It lets me livestream logs (like a tail -f ) and search and filter them as they’re written. If you’re interested in seeing this for yourself, sign up for a free trial of Papertrail .
This post was written by Pius Aboyi. Pius is a mobile and web developer with over four years of experience building for the Android platform. He writes code in Java, Kotlin, and PHP. He loves writing about tech and creating how-to tutorials for developers.