Configuration options

The Bugsnag client object has many configuration options that can be set to customize the content of events and sessions and how they are sent.

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.

Setting configuration options

Most configuration options can be set in your App Manifest (AndroidManifest.xml):

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

With your settings in the app manifest file, Bugsnag can simply be started using:

Bugsnag.start(this);
Bugsnag.start(this)

Alternatively, configuration options can be specified in code by creating a Configuration object and passing it into Bugsnag.start:

Configuration config = Configuration.load(this);
config.setAppVersion("1.0.0-alpha");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.appVersion = "1.0.0-alpha"
Bugsnag.start(this, config)

Configuration.load uses your app manifest to set initial configuration values, allowing you to augment and override the values before they are used to start Bugsnag. You can use the Configuration constructor to avoid using the manifest file.

To set different configuration values based on build variants or product flavors, see Customizing by build setting.

Available options

addMetadata

Set diagnostic metadata that you want to send with all captured events – see Customizing Error Reports for more information.

Configuration config = Configuration.load(this);
config.addMetadata("account", "name", "Acme Co.");
config.addMetadata("basket", new HashMap<String, Object>() {{
  put("delivery", "express");
  put("sale", "spring");
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addMetadata("account", "name", "Acme Co.")
config.addMetadata("basket", hashMapOf(
  "delivery" to "express",
  "sale" to "spring"
))
Bugsnag.start(this, config)

addOnBreadcrumb

Add callbacks to modify or discard breadcrumbs before they are recorded — see Customizing Breadcrumbs for more information.

Configuration config = Configuration.load(this);
config.addOnBreadcrumb(new OnBreadcrumbCallback() {
    @Override
    public boolean onBreadcrumb(@NonNull Breadcrumb breadcrumb) {
        if (breadcrumb.getMessage().equals("Noisy breadcrumb")) {
            return false; // ignore the breadcrumb
        } else {
            return true; // capture the breadcrumb
        }
    }
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addOnBreadcrumb(OnBreadcrumbCallback { breadcrumb ->
    if (breadcrumb.message == "Noisy breadcrumb") {
        false // ignore the breadcrumb
    } else {
        true // capture the breadcrumb
    }
}
Bugsnag.start(this, config)

addOnError

Add callbacks to modify or discard error events before they are sent to Bugsnag — see Customizing Error Reports for more information.

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)

addOnSession

Add callbacks to modify or discard sessions before they are sent to Bugsnag — see Managing Sessions for more information.

Configuration config = Configuration.load(this);
config.addOnSession(new OnSessionCallback() {
    @Override
    public boolean onSession(Session session) {
        String userId = getMyUserIdentifier(); // a custom user resolver
        session.setUser(userId, null, null);
        return true; // Return false to discard
    }
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addOnSession(OnSessionCallback { session ->
    val userId = getMyUserIdentifier() // a custom user resolver
    session.setUser(userId, null, null)
    true // Return false to discard
}
Bugsnag.start(this, config)

apiKey

The API key used for events sent to Bugsnag:

Configuration config = Configuration.load(this);
config.setApiKey("your-other-api-key-here");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.apiKey = "your-other-api-key-here"
Bugsnag.start(this, config)

Or in the app manifest:

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

appType

If your app’s codebase contains different entry-points/processes, but reports to a single Bugsnag project, you might want to add information denoting the type of process the error came from.

This information can be used in the dashboard to filter errors and to determine whether an error is limited to a subset of appTypes.

Configuration config = Configuration.load(this);
config.setAppType("lite");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.appType = "lite"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.APP_TYPE"
             android:value="lite"/>
</application>

appVersion

The version of the application. This is really useful for finding out when errors are introduced and fixed. Additionally Bugsnag can re-open closed errors if a later version of the app has a regression.

We’ll automatically set the version from the versionName field in your app manifest file. If you’d like to override this you can set appVersion on Configuration:

Configuration config = Configuration.load(this);
config.setAppVersion("1.0.0-alpha");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.appVersion = "1.0.0-alpha"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.APP_VERSION"
             android:value="1.0.0-alpha"/>
</application>

autoDetectErrors

If you want to disable automatic detection of all errors, you can set autoDetectErrors to false:

Configuration config = Configuration.load(this);
config.setAutoDetectErrors(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.autoDetectErrors = false
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.AUTO_DETECT_ERRORS"
             android:value="false"/>
</application>

Setting autoDetectErrors to false will disable all automatic errors, regardless of the error types enabled by enabledErrorTypes.

autoTrackSessions

By default, Bugsnag will automatically capture and report session information from your application.

To disable automatic session capturing:

Configuration config = Configuration.load(this);
config.setAutoTrackSessions(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.autoTrackSessions = false
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.AUTO_TRACK_SESSIONS"
             android:value="false"/>
</application>

If you want control over what is deemed a session, you can switch off automatic session tracking with the autoTrackSessions option, and manage the session lifecycle using startSession, pauseSession and resumeSession on the Bugsnag client.

clearMetadata

Clears diagnostic metadata from being sent in subsequent events – see Customizing Error Reports for more information.

Configuration config = Configuration.load(this);
config.clearMetadata("account");
// or
config.clearMetadata("account", "name");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.clearMetadata("account")
// or
config.clearMetadata("account", "name")
Bugsnag.start(this, config)

context

Set a “context” that you want to send with all captured events – see Setting context for more information.

Configuration config = Configuration.load(this);
config.setContext("SecondTutorialStep");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.context = "SecondTutorialStep"
Bugsnag.start(this, config)

delivery

The Delivery implementation used to make network calls to the Bugsnag Error Reporting and Sessions API.

This may be useful if you have requirements such as certificate pinning and rotation, which are not supported by the default implementation.

Configuration config = Configuration.load(this);
config.setDelivery(new CertPinnedDelivery());
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.delivery = CertPinnedDelivery()
Bugsnag.start(this, config)

To provide custom delivery functionality, create a class which implements the Delivery interface. Please note that request bodies must match the structure specified in the Error Reporting and Sessions API documentation.

You can use the return type from the deliver functions to control the strategy for retrying the tranmission at a later date. If DeliveryStatus.UNDELIVERED is returned, the notifier will automatically cache the payload and trigger delivery later on. Otherwise, if either DeliveryStatus.DELIVERED or DeliveryStatus.FAILURE is returned the notifier will removed any cached payload and no further delivery will be attempted.

For example, if the device has no network connectivity, it may make sense to store the report and send it later:

if (!hasNetworkConnection) {
    return DeliveryStatus.UNDELIVERED;
}
if (!hasNetworkConnection) {
    return DeliveryStatus.UNDELIVERED
}

Custom Delivery Example

A full example of a custom Delivery which uses certificate pinning is provided below.

Pinning certificates with OkHttp3

/**
 * A custom API client which uses Square's OkHttp3 Library to pin certificates.
 */
class CertPinnedApiClient implements Delivery {

    OkHttpClient okHttpClient;

    // The public key hash(es) for your cert
    // can be found by following OkHttp3 instructions:
    // https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
    CertPinnedApiClient() {
        String hash1 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="
        String hash2 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="

        CertificatePinner certificatePinner = new CertificatePinner.Builder()
            .add("mywebsite.com", hash1) // expires in 2019
            .add("mywebsite.com", hash2) // expires in 2020
            .build();

        okHttpClient = new OkHttpClient.Builder()
            .certificatePinner(certificatePinner)
            .build();
    }

    String getJsonBody(EventPayload payload) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            JsonStream jsonStream = new JsonStream(new PrintWriter(baos));
            payload.toStream(jsonStream);
            jsonStream.flush();
            return baos.toString("UTF-8");
        } catch (IOException e) {
            throw new RuntimeException("Failed to generate request", e);
        }
    }

    @Override
    public void deliver(EventPayload payload, DeliveryParams deliveryParams) {
        try {
            MediaType mediaType = MediaType.parse("application/json");
            Request request = new Request.Builder()
                .headers(Headers.of(deliveryParams.getHeaders())) // add error API headers
                .url(deliveryParams.getEndpoint()) // use error API endpoint
                .post(RequestBody.create(mediaType, getJsonBody(payload)))
                .build();
            Response response = okHttpClient.newCall(request).execute();
            response.isSuccessful() ? return DeliveryStatus.DELIVERED : DeliveryStatus.FAILURE;
        } catch (IOException e) {
            return DeliveryStatus.UNDELIVERED;
        }
    }

    @Override
    public void deliver(SessionPayload payload, DeliveryParams deliveryParams) {
        // implement as per event payload
    }
}
/**
 * A custom API client which uses Square's OkHttp3 Library to pin certificates.
 */
class CertPinnedApiClient : Delivery {

    var okHttpClient: OkHttpClient

    // The public key hash(es) for your cert
    // can be found by following OkHttp3 instructions:
    // https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
    init {
        val hash1 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="
        val hash2 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="

        val certificatePinner = CertificatePinner.Builder()
            .add("mywebsite.com", hash1) // expires in 2019
            .add("mywebsite.com", hash2) // expires in 2020
            .build()

        okHttpClient = OkHttpClient.Builder()
            .certificatePinner(certificatePinner)
            .build()
    }

    fun getJsonBody(payload: EventPayload): String {
        try {
            val baos = ByteArrayOutputStream()
            val jsonStream = JsonStream(PrintWriter(baos))
            report.toStream(jsonStream)
            jsonStream.flush()
            return baos.toString("UTF-8")
        } catch (e: IOException) {
            throw RuntimeException("Failed to generate request", e)
        }
    }

    override fun deliver(payload: EventPayload, deliveryParams: DeliveryParams) {
        try {
            val mediaType = MediaType.parse("application/json")
            val request = Request.Builder()
                .headers(Headers.of(deliveryParams.headers)) // add error API headers
                .url(deliveryParams.endpoint) // use error API endpoint
                .post(RequestBody.create(mediaType, getJsonBody(payload)))
                .build()
            val response = okHttpClient.newCall(request).execute()
            response.isSuccessful() ? return DeliveryStatus.DELIVERED : DeliveryStatus.FAILURE;
        } catch (e: IOException) {
            return DeliveryStatus.UNDELIVERED
        }
    }

    override fun deliver(payload: SessionPayload, deliveryParams: DeliveryParams) {
        // implement as per event payload
    }
}

discardClasses

Allows you to specify the fully-qualified name of error classes that will be discarded before being sent to Bugsnag if they are detected. The notifier performs an exact match against the canonical class name.

Configuration config = Configuration.load(this);
config.setDiscardClasses(new HashSet<String>() {{
    add("java.net.UnknownHostException")
    add("com.example.Custom")
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.discardClasses = setOf("java.net.UnknownHostException", "com.example.Custom")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.DISCARD_CLASSES"
             android:value="com.domain.ClassName,com.domain.SecondClassName"/>
</application>

enabledBreadcrumbTypes

By default Bugsnag will automatically add breadcrumbs for common application events such as activity lifecycle events and system intents. To configure which of these are enabled and sent to Bugsnag, set the enabledBreadcrumbTypes option:

Configuration config = Configuration.load(this);
config.setEnabledBreadcrumbTypes(new HashSet<String>() {{
    add(BreadcrumbType.NAVIGATION)
    add(BreadcrumbType.REQUEST)
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledBreadcrumbTypes = setOf(BreadcrumbType.NAVIGATION, BreadcrumbType.REQUEST)
Bugsnag.start(this, config)

Automatically captured breadcrumbs can be disabled by providing an empty set in enabledBreadcrumbTypes.

Configuration config = Configuration.load(this);
config.setEnabledBreadcrumbTypes(new HashSet<String>());
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledBreadcrumbTypes = emptySet()
Bugsnag.start(this, config)

The following breadcrumb types can be enabled:

Captured errors

Error breadcrumbs (BreadcrumbType.ERROR) are left when an error event is sent to the Bugsnag API.

Navigation breadcrumbs (BreadcrumbType.NAVIGATION) are left for Activity Lifecycle events to track the user’s journey in the app.

State changes

State breadcrumbs (BreadcrumbType.STATE) are left for system broadcast events. For example: battery warnings, airplane mode, etc. See Automatically Captured Data for more information.

User interaction

User breadcrumbs (BreadcrumbType.USER) are left when the user performs certain system operations. See Automatically Captured Data for more information.

enabledErrorTypes

Bugsnag will automatically detect different types of error in your application. If you wish to control exactly which types are enabled, set enabledErrorTypes:

Configuration config = Configuration.load(this);
config.getEnabledErrorTypes().setAnrs(true);
config.getEnabledErrorTypes().setNdkCrashes(true);
config.getEnabledErrorTypes().setUnhandledExceptions(true);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledErrorTypes.anrs = true
config.enabledErrorTypes.ndkCrashes = true
config.enabledErrorTypes.unhandledExceptions = true
Bugsnag.start(this, config)

Setting autoDetectErrors to false will disable all automatic errors, regardless of the error types enabled by enabledErrorTypes.

enabledReleaseStages

By default, Bugsnag will be notified of events that happen in any releaseStage. If you would like to change which release stages notify Bugsnag you can set enabledReleaseStages:

Configuration config = Configuration.load(this);
config.setEnabledReleaseStages(new HashSet<String>() {{
    add("production")
    add("development")
    add("testing")
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledReleaseStages = setOf("production", "development", "testing")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.ENABLED_RELEASE_STAGES"
             android:value="production,development,testing"/>
</application>

endpoints

By default we will send error reports to notify.bugsnag.com and sessions to sessions.bugsnag.com.

If you are using Bugsnag On-premise you’ll need to set these to your Event Server and Session Server endpoints. If the notify endpoint is set but the sessions endpoint is not, session tracking will be disabled automatically to avoid leaking session information outside of your server configuration, and a warning will be logged.

To set the endpoints:

Configuration config = Configuration.load(this);
config.setEndpoints(new EndpointConfiguration("https://notify.example.com", "https://sessions.example.com"));
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.endpoints = EndpointConfiguration("https://notify.example.com", "https://sessions.example.com")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.ENDPOINT_NOTIFY"
             android:value="https://notify.bugsnag.com"/>
  <meta-data android:name="com.bugsnag.android.ENDPOINT_SESSIONS"
             android:value="https://sessions.bugsnag.com"/>
</application>

launchCrashThresholdMs

Sets the threshold in milliseconds for an uncaught error to be considered as a crash on launch. If a crash is detected on launch, Bugsnag will attempt to send the event synchronously. By default, this value is set at 5,000ms. Setting the value to 0 will disable this behaviour.

Configuration config = Configuration.load(this);
config.setLaunchCrashThresholdMs(10000);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.launchCrashThresholdMs = 10000
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.LAUNCH_CRASH_THRESHOLD_MS"
             android:value="10000"/>
</application>

logger

By default, the notifier’s log messages will be logged using the android.util.Log with a Bugsnag tag unless the release stage is “production”.

To override this behavior, an alternative instance can be provided that implements the com.bugsnag.android.Logger interface:

Configuration config = Configuration.load(this);
config.setLogger(new Logger() {
    void e(String msg) {
        // error logging code
    }
    void e(String msg, Throwable throwable) {
        // error logging code
    }
    // ... warning, info and debug
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.logger = object: Logger {
    override fun e(msg: String) {
        // error logging code
    }
    override fun e(msg: String, throwable: Throwable) {
        // error logging code
    }
    // ... warning, info and debug
}
Bugsnag.start(this, config)

maxBreadcrumbs

Sets the maximum number of breadcrumbs which will be stored. Once the threshold is reached, the oldest breadcrumbs will be deleted.

By default, 25 breadcrumbs are stored; this can be amended up to a maximum of 100.

Configuration config = Configuration.load(this);
config.setMaxBreadcrumbs(50);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.maxBreadcrumbs = 50
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.MAX_BREADCRUMBS"
             android:value="50"/>
</application>

persistUser

Set whether or not Bugsnag should persist user information between application sessions.

Configuration config = Configuration.load(this);
config.setPersistUser(true);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.persistUser = true
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.PERSIST_USER"
             android:value="true"/>
</application>

If enabled then any user information set will be re-used until the user information is removed manually by calling Bugsnag.setUser with null arguments.

projectPackages

Sets which package names Bugsnag should consider as a part of the running application. We mark stacktrace lines as in-project if they originate from any of these packages and this allows us to improve the visual display of the stacktrace on the dashboard.

Configuration config = Configuration.load(this);
config.setProjectPackages(new HashSet<String>() {{
    add("com.company.package1")
    add("com.company.package2")
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.projectPackages = setOf("com.company.package1", "com.company.package2")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.PROJECT_PACKAGES"
             android:value="com.company.package1,com.company.package2"/>
</application>

By default, projectPackages is set to be the package you called Bugsnag.start from.

redactedKeys

Sets which values should be removed from any Metadata objects before sending them to Bugsnag. Use this if you want to ensure you don’t send sensitive data such as passwords, and credit card numbers to our servers. Any keys which contain these strings will be filtered.

Configuration config = Configuration.load(this);
config.setRedactedKeys(new HashSet<String>() {{
    add("password")
    add("credit_card_number")
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.redactedKeys = setOf("password", "credit_card_number")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.REDACTED_KEYS"
             android:value="password,credit_card_number"/>
</application>

By default, redactedKeys is set to "password"

releaseStage

If you would like to distinguish between errors that happen in different stages of the application release process (development, production, etc) you can set the releaseStage that is reported to Bugsnag.

This is automatically configured by the notifier to be “production”, unless the app is built with debug enabled in which case it will be set to “development”. If you wish to override this, you can do so by setting the releaseStage property manually:

Configuration config = Configuration.load(this);
config.setReleaseStage("testing");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.releaseStage = "testing"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.RELEASE_STAGE"
             android:value="testing"/>
</application>

If you are running a debug build, we’ll automatically set this to “development”, otherwise it is set to “production”.

You can control whether events are sent for specific release stages using the enabledReleaseStages option.

sendThreads

Controls whether we should capture and serialize the state of all threads at the time of an exception.

By default sendThreads is set to Thread.ThreadSendPolicy.ALWAYS. This can be set to Thread.ThreadSendPolicy.NEVER to disable or Thread.ThreadSendPolicy.UNHANDLED_ONLY to only do so for unhandled errors.

Configuration config = Configuration.load(this);
config.setSendThreads(Thread.ThreadSendPolicy.ALWAYS);
// alternatively: config.setSendThreads(Thread.ThreadSendPolicy.UNHANDLED_ONLY);
//            or: config.setSendThreads(Thread.ThreadSendPolicy.NEVER);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.sendThreads = Thread.ThreadSendPolicy.ALWAYS
// alternatively: config.sendThreads = Thread.ThreadSendPolicy.UNHANDLED_ONLY
//            or: config.sendThreads = Thread.ThreadSendPolicy.NEVER
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.SEND_THREADS"
             android:value="ALWAYS"/>
  <!-- alternatively: android:value="UNHANDLED_ONLY" -->
  <!--            or: android:value="NEVER"          -->
</application>

setUser

Set global user data that you want to send with all captured events – see Adding user data for more information.

Configuration config = Configuration.load(this);
config.setUser("3", "bugs.nag@bugsnag.com", "Bugs Nag");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.setUser("3", "bugs.nag@bugsnag.com", "Bugs Nag")
Bugsnag.start(this, config)

versionCode

We’ll automatically pull your versionCode from the versionCode field in your app manifest file. If you’d like to override this you can set versionCode in Configuration:

Configuration config = Configuration.load(this);
config.setVersionCode(55);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.versionCode = 55
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.VERSION_CODE"
             android:value="55"/>
</application>

Customizing by build setting

Manifest placeholders

Bugsnag can be set up to use different configuration values for different build variants, by using manifest placeholders in your app’s build.gradle script.

android {
    defaultConfig {
        manifestPlaceholders = [
            bugsnagAppType: "lite"
        ]
    }
    productFlavors {
        pro {
            manifestPlaceholders = [
                // override defaultConfig values here
                bugsnagAppType: "pro"
            ]
        }
    }
}

For all the values you wish to configure, provide a meta-data element at the bottom of your app manifest file (AndroidManifest.xml):

<application>
    <meta-data android:name="com.bugsnag.android.APP_TYPE" android:value="${bugsnagAppType}"/>
</application>

Using Resource values

Gradle resource values allow you to share custom fields and values between build files and app code. For example, to set API key in your build configuration, set a resource value in your Gradle file:

def bugsnag_api_key = project.hasProperty("api-key")
 ? project.property("api-key") : "your-api-key-here"

buildTypes {
    release {
        resValue("string", "bugsnag_api_key", "${bugsnag_api_key}")
    }
}

To load the value automatically when Bugsnag starts, set a placeholder in your app manifest for the value:

<application ...>
    <meta-data android:name="com.bugsnag.android.API_KEY"
     android:value="@string/bugsnag_api_key"/>
</application>

Properties can also be loaded at runtime if needed (though not required if placeholders are set in app manifest):

Configuration config = new Configuration(getString(R.string.bugsnag_api_key));
Bugsnag.start(this, config);
val config = Configuration(getString(R.string.bugsnag_api_key))
Bugsnag.start(this, config)