Legacy Android integration guide

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.

Installation

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

Showing full stacktraces

The BugSnag Gradle plugin (installed above) automatically handles deobfuscating file and method names. See the Android mapping guide for more details.

Basic configuration

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 the BugSnag client

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>

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 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.

Further configuration

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

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.

<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>

Reporting NDK errors

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.

Native API configuration

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)
Note: CMake rules differ for versions of Android Gradle Plugin < 3

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.

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 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);
}

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:

  • A full stacktrace
  • Application information (package name, app name, version)
  • Application state (time in foreground, active screen, memory usage)
  • Device information (manufacturer, brand, model, total memory)
  • Screen information (density, dpi, resolution, orientation)
  • System information (android version, locale, rooted state)
  • Battery status (battery level, charging state)
  • Network status (network type, network state)

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:

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.

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 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");

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 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().

Logging breadcrumbs

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.

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

Attaching custom breadcrumbs

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.

Next steps