Add BugSnag to your Android apps to automatically capture and report crashes.
The BugSnag Android integration detects and reports crashes from uncaught Java or Kotlin exceptions, C signal handlers, and C++ exceptions, as well as ANRs. The integration supports Android API level 14+ and NDK revision 12b and above.
This documentation is for version 4 of the BugSnag Android notifier. We recommend upgrading to the latest release using our Upgrade guide. Documentation for the current release can be found here.
Add the following dependency to your Project Gradle Settings, <project_dir>/build.gradle
:
buildscript {
dependencies {
// ...
classpath "com.bugsnag:bugsnag-android-gradle-plugin:4.+"
}
}
Add the following dependencies to your Module Gradle Settings, usually found at <project_dir>/app/build.gradle
:
apply plugin: "com.android.application"
apply plugin: "com.bugsnag.android.gradle"
dependencies {
// ...
implementation "com.bugsnag:bugsnag-android:4.+"
}
The BugSnag Gradle plugin (installed above) automatically handles deobfuscating file and method names. See the Android mapping guide for more details.
Configure your API key in the <application>
tag of your App Manifest file.
You can find your integration API key immediately after creating a new project from your BugSnag dashboard, or your project’s Settings page.
<application ...>
<meta-data android:name="com.bugsnag.android.API_KEY"
android:value="your-api-key-here"/>
</application>
Initialize BugSnag in the onCreate
callback of your Application subclass:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
Bugsnag.init(this);
}
}
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
Bugsnag.init(this)
}
}
If you’re creating a custom Application
class for the first time, make sure to specify the subclass name in your AndroidManifest.xml
:
<application
android:name=".MyApp">
</application>
If your supported minimum SDK version includes API 17 or lower, load the BugSnag library before any libraries which link to it:
public class MyApp extends Application {
static {
System.loadLibrary("bugsnag-ndk");
// ... (other libraries)
}
// ...
}
class MyApp : Application() {
init {
System.loadLibrary("bugsnag-ndk")
// ... (other libraries)
}
// ...
}
If your app listens for the android.intent.action.BOOT_COMPLETED
broadcast, you will need to start BugSnag in a separate thread, as having both in the same thread can in some cases lead to ANRs. This has been resolved in v6.0.0 of bugsnag-android
, due to changes to foreground tracking.
If you’d like to configure BugSnag further, check out the Configuration options reference.
After completing installation and basic configuration, unhandled exceptions from Java or Kotlin will be automatically reported to your BugSnag dashboard.
When the main thread of an Android app is blocked for too long, it appears unresponsive and the Android OS creates an Application Not Responding (ANR) error, presenting the user with a dialog option to force quit the app.
<application ...>
<meta-data android:name="com.bugsnag.android.API_KEY"
android:value="your-api-key-here"/>
<meta-data android:name="com.bugsnag.android.DETECT_ANRS"
android:value="true"/>
</application>
The Android Native Development Kit (NDK) is a toolset which lets you implement parts of your app in native code, using languages such as C and C++. Many third party libraries also include native code, even if your app does not do so directly.
To detect and report crashes from C and C++ code, enable NDK crash detection when configuring BugSnag:
<application ...>
<meta-data android:name="com.bugsnag.android.API_KEY"
android:value="your-api-key-here"/>
<meta-data android:name="com.bugsnag.android.DETECT_NDK_CRASHES"
android:value="true"/>
</application>
If you don’t require NDK error reporting you can exclude the bugsnag-plugin-android-ndk
module to reduce the size of your app.
The Native API is a collection of C and C++ helpers which allow you to report handled errors, leave breadcrumbs, and set user information. User information and breadcrumbs will be attached to all subsequent error reports from Java, Kotlin, and C/C++.
To use the Native API, update your CMakeLists.txt
file to link the BugSnag library:
add_library(lib_bugsnag SHARED IMPORTED)
# This directory is created automatically by the BugSnag Gradle plugin
set(BUGSNAG_LIB_DIR
${CMAKE_SOURCE_DIR}/build/intermediates/bugsnag-libs)
set(BUGSNAG_INCLUDE_DIR ${BUGSNAG_LIB_DIR}/assets/include)
set_target_properties(lib_bugsnag PROPERTIES IMPORTED_LOCATION
${BUGSNAG_LIB_DIR}/jni/${ANDROID_ABI}/libbugsnag-ndk.so)
# Insert your target name:
target_include_directories(your-native-lib PRIVATE ${BUGSNAG_INCLUDE_DIR})
target_link_libraries(your-native-lib lib_bugsnag)
If you are using an older version of Android Gradle Plugin, you should instead add the following to CMakeLists.txt
:
add_library(lib_bugsnag SHARED IMPORTED)
set(BUGSNAG_VERSION 1.0.1)
set(BUGSNAG_DIR ${CMAKE_SOURCE_DIR}/build/intermediates/exploded-aar/com.bugsnag/bugsnag-android/${BUGSNAG_VERSION})
set_target_properties(lib_bugsnag PROPERTIES
IMPORTED_LOCATION ${BUGSNAG_DIR}/jni/${ANDROID_ABI}/libbugsnag-ndk.so)
target_include_directories(your-native-lib PRIVATE ${BUGSNAG_DIR}/assets/include) # Insert your target name
target_link_libraries(your-native-lib lib_bugsnag) # Insert your target name
Once complete, you can invoke BugSnag functions for reporting handled errors, leaving breadcrumbs, and setting user information. More information is provided in the sections below.
If you would like to send handled exceptions to BugSnag, you can pass any Throwable
object to the Bugsnag.notify
method.
When reporting errors from C or C++ code, invoke bugsnag_notify_env
with a title, description and severity.
try {
// Some potentially crashy code
} catch (Throwable exception) {
Bugsnag.notify(exception);
}
try {
// Some potentially crashy code
} catch (e: Throwable) {
Bugsnag.notify(e)
}
if (strlen(username) == 0) {
// report failure to BugSnag
bugsnag_notify_env(env, "Invalidation Error",
"No name specified", BSG_SEVERITY_WARN);
}
It can often be helpful to adjust the severity or attach custom diagnostics to handled exceptions. For more information, see Reporting handled errors.
BugSnag will automatically capture and attach the following diagnostic data to every error report:
It can often be helpful to attach application-specific diagnostic data to error reports. This can be accomplished by setting a callback which will be invoked before any reports are sent to BugSnag:
Bugsnag.beforeNotify(new BeforeNotify() {
@Override
public boolean run(Error error) {
// Attach customer information to every error report
error.addToTab("account", "name", "Acme Co.");
error.addToTab("account", "paying_customer", true);
return true;
}
});
Bugsnag.beforeNotify { error ->
// Attach customer information to every error report
error.addToTab("account", "name", "Acme Co.")
error.addToTab("account", "paying_customer", true)
true
}
Pre-delivery callbacks are not available to the Native C/C++ API and are not run when a C/C++ crash occurs.
For more information, see customizing error reports.
In order to correlate errors with customer reports, or to see a list of users who experienced each error, it is helpful to capture and display user information. BugSnag includes helpers attaching an identifier, email address, and name to reports which will be searchable in the dashboard:
Bugsnag.setUser("123456", "james@acme.co", "James Smith")
Bugsnag.setUser("123456", "james@acme.co", "James Smith");
bugsnag_set_user_env(env, "123456", "james@acme.co", "James Smith");
BugSnag tracks the number of “sessions” that happen within your application. This allows you to compare stability scores between releases and helps you to understand the quality of your releases.
Sessions are captured and reported by default. This behavior can be disabled using the setAutoCaptureSessions
configuration option.
BugSnag will automatically report a session each time an Activity is in the “Started” state, 30 seconds after all Activities have remained in the “Stopped” state.
If you want control over what is deemed a session, you can switch off automatic session tracking with the setAutoCaptureSessions
option, and manage the session lifecycle using startSession()
, stopSession()
and resumeSession()
.
In order to understand what happened in your application before each crash, it can be helpful to leave short log statements that we call breadcrumbs. The last several breadcrumbs are attached to a crash to help diagnose what events lead to the error.
By default, BugSnag captures common events including:
Leaving breadcrumbs can be accomplished by calling leaveBreadcrumb
:
Bugsnag.leaveBreadcrumb("Preference updated", BreadcrumbType.STATE, new HashMap<String, String>() {{
put("from", "moka");
put("to", "french press");
}});
Bugsnag.leaveBreadcrumb("Preference updated", BreadcrumbType.STATE, hashMapOf(
"from" to "moka",
"to" to "french press"
))
if (useFrenchPress) {
sprintf(message, "Updated pref: %s", "french press");
bugsnag_leave_breadcrumb_env(env, message, BSG_CRUMB_STATE);
}
For more information and examples for how custom breadcrumbs can be integrated, see Customizing breadcrumbs.
bugsnag-android
, the library
powering BugSnag for Android, on GitHub