Android integration guide

Add BugSnag to your Android apps to automatically capture and report crashes and performance data.

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.

New to BugSnag? Create an account

Looking for performance monitoring? See our performance guide

Installation

Add the BugSnag Gradle plugin dependency to your Project Gradle Settings in <project_dir>/build.gradle:

buildscript {
    dependencies {
        // ...
        classpath "com.bugsnag:bugsnag-android-gradle-plugin:8.+"
    }
}

Since v7.x of bugsnag-android-gradle-plugin, our major version number matches the version of Android Gradle plugin that it supports. If you are using version 3.4.x - 4.x in your project, use version 5.+ of our plugin.

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:6.+"
}

The latest available version of bugsnag-android is v6.2.0.

Basic configuration

This documentation is for version 5+ of the BugSnag Android notifier. If you are using older versions, we recommend upgrading to the latest release using our Upgrade guide. Documentation for the previous release can be found on our legacy pages.

Configure your API key in the <application> tag of your App Manifest file (usually in src/main/AndroidManifest.xml):

<application ...>
  <meta-data android:name="com.bugsnag.android.API_KEY"
             android:value="your-api-key-here"/>
</application>

You can find your API key in Project Settings from your BugSnag dashboard.

Initialize BugSnag in the onCreate callback of your Application subclass:

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Bugsnag.start(this);
    }
}
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Bugsnag.start(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>

Note: If your app supports Android API 17 or lower, additional setup is required

If your supported minimum SDK version includes API 17 or lower, load the BugSnag library before any libraries that link to it:

public class MyApp extends Application {
    static {
        System.loadLibrary("bugsnag-ndk");
        System.loadLibrary("bugsnag-plugin-android-anr");
        // ... (other libraries)
    }
    // ...
}
class MyApp : Application() {
    init {
        System.loadLibrary("bugsnag-ndk")
        System.loadLibrary("bugsnag-plugin-android-anr")
        // ... (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.

Capturing OkHttp network requests

If you use the OkHttp library for network requests in your app, you can install the BugsnagOkHttpPlugin to capture network requests as breadcrumbs in your error reports. For installation instructions, see our Customizing breadcrumbs guide.

Further configuration

If you’d like to configure BugSnag further, check out the Configuration options reference.

Showing full stacktraces

If you are using minification tools, such as ProGuard, DexGuard, or R8 to minify and optimize your Android app, this will cause method and class names to become obfuscated which makes debugging harder. Similarly, for applications which use the NDK, native stacktraces from C or C++ code consist of a list of addresses and numeric offsets.

In order for your stacktraces to remain readable in your dashboard, BugSnag requires that you upload you obfuscation mapping file and the symbols from any native code for each release of your app. See our Showing full stacktraces guide for information on how to set this up in your builds.

Reporting unhandled exceptions

After completing installation and basic configuration, unhandled exceptions from Java or Kotlin will be automatically reported to your BugSnag dashboard.

Reporting ANRs

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.

ANR detection is enabled by default as part of the basic configuration steps. If you wish to disable it, see the enabledErrorTypes configuration option.

Reporting NDK errors

The Android Native Development Kit (NDK) is a toolset that 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.

NDK crash detection is enabled by default as part of the basic configuration steps. If you wish to disable it, see the enabledErrorTypes configuration option.

If you don’t require NDK error reporting you can exclude the bugsnag-plugin-android-ndk module to reduce the size of your app.

For NDK errors, the event metadata and the metadata on each breadcrumb will be restricted to 128 entries and 63-character keys. Any additional data will be truncated. There is also a fixed 50 breadcrumb limit.

Native API configuration

The BugSnag NDK API is a collection of C and C++ helpers that 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 this API in your native code, first enable Prefab in your build.gradle – if it isn’t already – and add the BugSnag NDK library to your pickFirsts:

buildFeatures.prefab = true
packagingOptions.jniLibs.pickFirsts.add("**/libbugsnag-ndk.so")
buildFeatures.prefab = true
packagingOptions.jniLibs.pickFirsts += ["**/libbugsnag-ndk.so"]

Then update your CMakeLists.txt file to reference the library:

find_package(bugsnag-plugin-android-ndk REQUIRED CONFIG)

target_link_libraries(entrypoint bugsnag-plugin-android-ndk::bugsnag-ndk)
Note: Prefab support was added in v6 of the SDK. See instructions here for v5.x users.

If you are using v5.x of the SDK, you should update your CMakeLists.txt as follows:

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)

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.

Reporting handled exceptions

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 name, message and severity.

try {
    // Some potentially crashy code
} catch (Throwable e) {
    Bugsnag.notify(e);
}
try {
    // Some potentially crashy code
} catch (e: Throwable) {
    Bugsnag.notify(e)
}
if (strlen(username) == 0) {
    // report failure to Bugsnag
    bugsnag_notify_env(env, "Validation Error",
                       "No name specified", BSG_SEVERITY_WARN);
}

Adding diagnostics or adjusting severity

It can often be helpful to adjust the severity or attach custom diagnostics to handled exceptions. For more information, see Reporting handled errors.

Sending diagnostic data

Automatically captured diagnostics

BugSnag will automatically capture and attach the following diagnostic data to every error report:

  • Full stack traces for all threads.
  • App state including running time, time in foreground and active screen.
  • Build information including name, version/build and release stage.
  • Device specification including manufacturer, model, OS version, screen size/density and total memory.
  • System state including orientation, free memory, available disk space, battery level and network connectivity.

For more information see Automatically captured data.

Attaching custom diagnostics

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:

Configuration config = Configuration.load(this);
config.addOnError(new OnErrorCallback() {
    @Override
    public boolean onError(Event event) {
        event.addMetadata("account", "name", "Acme Co.");
        event.addMetadata("account", "paying_customer", true);

        // Return `false` if you'd like to stop this error being reported
        return true;
    }
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addOnError(OnErrorCallback { event ->
    event.addMetadata("account", "name", "Acme Co.")
    event.addMetadata("account", "paying_customer", true)

    // Return `false` if you'd like to stop this error being reported
    true
})
Bugsnag.start(this, config)
bool custom_on_error_callback(void *event) {
    // Attach customer information to every error report
    bugsnag_event_add_metadata_string(event, "account", "name", "Acme Co.");
    bugsnag_event_add_metadata_bool(event, "account", "paying_customer", true);

    // Return `false` if you'd like to stop this error being reported
    return true;
}
bugsnag_add_on_error(&custom_on_error_callback);

For more information, see Customizing error reports.

Identifying users

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 for attaching an identifier, email address and name to reports that will be searchable in the dashboard.

By default we will generate a unique ID and send this ID along with every error report from an individual device. If you would like to override this identifier you can set the user ID property.

Bugsnag.setUser("3", "bugs.nag@bugsnag.com", "Bugs Nag");
Bugsnag.setUser("3", "bugs.nag@bugsnag.com", "Bugs Nag")
bugsnag_set_user_env(env, "3", "bugs.nag@bugsnag.com", "Bugs Nag");

For more information, see Adding user data.

Logging breadcrumbs

In order to understand what happened in your application before each error, it can be helpful to leave short log statements that we call breadcrumbs. A configurable number of breadcrumbs are attached to each error report to help diagnose what events led to the error.

Automatically captured breadcrumbs

By default, BugSnag captures common events including:

  • Activity Lifecycle callbacks
  • Network connectivity changes
  • Bluetooth connectivity changes
  • Battery state changes
  • Device rotation
  • Media Scanner events
  • Telephony events
  • Other device metrics and more

Capturing OkHttp network requests

If you use the OkHttp library for network requests in your app, you can install the BugsnagOkHttpPlugin to capture network requests as breadcrumbs in your error reports. For installation instructions, see our Customizing breadcrumbs guide.

Leaving custom breadcrumbs

You can use the leaveBreadcrumb method to log potentially useful events in your own applications:

Bugsnag.leaveBreadcrumb("App loaded");
Bugsnag.leaveBreadcrumb("User clicked a button");
Bugsnag.leaveBreadcrumb("App loaded")
Bugsnag.leaveBreadcrumb("User clicked a button")
bugsnag_leave_breadcrumb_env(env, "App loaded", BSG_CRUMB_MANUAL);

BugSnag will keep track of the time and order of the breadcrumbs and show them on your dashboard.

Additional data can also be attached to breadcrumbs by providing the optional type and metadata parameters. For more information and examples for how custom breadcrumbs can be integrated, see Customizing breadcrumbs.

Session tracking

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 autoTrackSessions configuration option.

BugSnag will automatically report a session each time the app is launched or enters the foreground after being in the background for at least 30 seconds.

For more information about manually controlling session tracking, see Capturing sessions.

Declaring feature flags and experiments

Monitor errors as you roll out features or run experiments and A/B tests by declaring your feature flag and experiment usage in the BugSnag client. You can use the Features dashboard to identify whether these features have introduced errors into your app.

Bugsnag.addFeatureFlag("Checkout button color", "Blue");
Bugsnag.addFeatureFlag("New checkout flow");
Bugsnag.addFeatureFlag("Checkout button color", "Blue")
Bugsnag.addFeatureFlag("New checkout flow")

For more information, see Feature flags & experiments.

Identifying crashes at launch

By default BugSnag will identify crashes that occur whilst your app is launching, allowing you to prioritize fixing high-impact launch crashes.

Additionally you can use BugSnag to detect recurrent launch crashes: allowing you to take evasive action in your app, such as resetting data or turning off application features.

Follow the Identifying crashes at launch guide to configure this functionality.

Reporting app exit information

From Android 11 (API 30), the Android OS provides information of an application process’s death in the ApplicationExitInfo API. This can be particularly useful for diagnosing native (NDK) crashes and ANR events.

Follow the Reporting exit info guide to install and configure our plugin to include this information with your events.

Next steps