On this page:
Once you have instrumented your Android application with the Android SDK, you can also use the APIs exposed by the SDK to customize the data for your app that appears in the Controller UI.
Because the agent stores data about events in a local buffer before reporting the information, you are recommended to use the APIs with discretion.
Android SDK Documentation
For the complete SDK API documentation, see the latest JavaDocs or the previous versions listed below:
Collect Additional Types of Data
Instrumentation class has additional methods to allow you to extend the kinds of application data you can collect and aggregate using Mobile RUM. There are six basic kinds of extensions that you can create:
- Info points - how often a single method is invoked, and how long it takes to run
- Custom timers - any arbitrary sequence of events within your code timed, even spanning multiple methods
- Custom metrics - any integer-based data you wish to collect
- User data - any string key/value pair you think might be useful
- Breadcrumbs - context for a crash
- User interactions - capture when users press buttons, click on lists, and select text
When you have set up info points, custom timers, custom metrics, and/or user data, the Mobile Agent packages that data in a mobile beacon. Normally, the beacon is transmitted when the instrumented app sends an HTTP request or when the app is restarted following a crash, but if custom data has been collected and neither of those events has occurred for at least 5 minutes, the custom data is sent on at that time.
Information points allow you to track how your own code is running. You can see how often a method is invoked, how long it takes to run, and if an exception is thrown. The simplest way to set up an information point is to use the
@InfoPoint annotation. For example:
You can also do this manually, using the
CallTracker interface. For example, to collect information on your
downloadImage method, you could use code similar to this:
This information appears in the Custom Data view of the Controller UI.
Custom timers allow you to time any arbitrary sequence of events within your code, even spanning multiple methods, by using
stopTime(String) can be called from different threads. Calling
startTimer again with the same name value resets a named timer.
This information appears in the Custom Data view of the Controller UI.
Any integer-based data can be passed to the agent. The first parameter to the
reportMetric call is the name you want the metric to appear under in the Controller UI. The metric name should only contain alphanumeric characters and spaces. Illegal characters are replaced by their ASCII hex value.
For example, to track the number of times your users click the checkout button in your UI, you could use code similar to this.
This information appears in the Custom Data view of the Controller UI.
You can set any string key/value pair you think might be useful. The first parameter to the
setUserData call is the key you want to use, which must be unique across your application. The second is the value you want to be assigned to the key.
This information is available in Network Request Analyze and is added to any crash snapshots that may be taken. Keys and values are limited to 2048 characters each.
You can also set user data with values of other types (Long, Boolean, Double, Date) using the following methods:
Breadcrumbs allow you to situate a crash in the context of your user's experience. Set a breadcrumb when something interesting happens. If your application crashes at some point in the future, the breadcrumb will be displayed along with the crash report.
There are two ways of leaving breadcrumbs:
Using this method means that breadcrumbs are reported in crash reports only.
mode is either:
breadcrumb is over 2048 characters, it is truncated. If it is empty, no breadcrumb is recorded. Each crash report displays the most recent 99 breadcrumbs.
Add a Crash Reporting Callback
You may want to make crash report information that Mobile RUM collects available to other parts of your code, for example, to Google Analytics, if you are using it. To enable passing on summary crash information, you can set up a crash report runtime callback. To get a callback when the Android Agent detects and then reports a crash, you need to implement the following interface in your code:
We send a Collection instead of an individual callback because there could be more than one crash, even though there typically is only one.
onCrashesReported is invoked during the next initialization of the agent after a crash has occurred.
This callback is invoked on your app's UI thread, so any work should be done on a separate work thread.
CrashReportSummary has the following properties:
If you are sending the information to another analytics tool, such as Google Analytics, it is best to include all three properties:
exceptionMessage are useful for a quick identification of what the crash is, but for more detailed information,
crashId can be used to look up the crash in the AppDynamics Controller UI.
For example, to print the crash information to Android's logger, you could implement a
CrashReportCallback class like this:
You set your callback as using the AgentConfiguration object:
Your callback is invoked after a crash, during the next initialization, on the main thread. For more information, see latest JavaDocs for the complete Android SDK API.
Report Errors and Exceptions
You can report exceptions using the method
reportError from the
Instrumentation class. Reported exceptions will appear in session details.
You can also set one of the severity levels below for an issue. With the severity level, you can filter errors in the Code Issues Dashboard or Code Issues Analyze.
The example below uses the API to report possible exceptions and setting the severity level to
ErrorSeverityLevel.CRITICAL (critical) when writing to a file.
Configure Hybrid Support
Runtime Configuration for Hybrid Support
The injection occurs during the creation of a new WKWebView. So, if a WKWebView is created when this flag is set to
false, that particular WKWebView won't be instrumented even if the flag is subsequently set to
The collection and reporting of Ajax calls are disabled by default. To enable the injection and the collection and reporting of Ajax calls, pass
true to the method
jsAgentEnabled in the instrumentation configuration as shown below.
Programmatically Control Sessions
By default, a mobile session ends after a period of user inactivity. For example, when a user opens your application, the session begins and only ends after the user stops using the app for a set period of time. When the user begins to use the application again, a new session begins.
Instead of having a period of inactivity to define the duration of a session, however, you can use the following API to programmatically control when sessions begin and end:
When you call the method
startNextSession from the
Instrumentation class, the current session ends and a new session begins. The API enables you to define and frame your sessions so that they align more closely with business goals and expected user flows. For example, you could use the API to define a session that tracks a purchase of a product or registers a new user.
Excessive use of this API will cause sessions to be throttled (excessive use is >10 calls per minute per Android Agent, but is subject to change). When not using the API, sessions will fall back to the default of ending after a period of user inactivity.
Example of a Programmatically Controlled Session
In the code example below, the current session ends and a new one begins when the check out is made.
Use a Custom HTTP Library
The Android Agent automatically detects network requests when the underlying implementation is handled by any one of the supported network libraries. To have the Android Agent detect requests from a custom library, add request tracking code to your application manually, using the
Supported Network Libraries
The libraries below cover the great majority of Android network requests. In some cases, however, mobile applications use custom HTTP libraries.
To set headers to allow correlation with server-side processing, use the
Add Request Tracking
To add request tracking manually, you use an
HttpRequestTracker object to tell the agent when the request begins and when it ends and to report fields of the response to the agent.
Tracking a request
To begin tracking an HTTP request, use an instance of the following interface.
You must initialize the agent using the
start method before using this interface.
Given a request snippet like this:
Adding the tracker could look something like this:
Enable Server-Side Correlation
To enable correlation between your request and server-side processing, add specific headers to outgoing requests that the server-side agent can detect.
This is done automatically for standard HTTP libraries.
- Call the
generatemethod and set the generated headers before sending a request to the backend.
- Report back the response headers, using data from the
Override the Request/Response Content-Length
You can generally obtain the content lengths of the network request and response by passing the headers with
If for some reason this does not work for your custom HTTP tracking—for example, the network library doesn't populate those fields until its being transmitted—then you can still report the request and response content lengths using
HttpRequestTracker.withRequestContentLength(Long length) and
For example, suppose you want to track a request that has a byte array of content. You could report the request content length by passing the size of the byte array as shown below.
Use the AgentConfiguration Object to Customize the Agent
To customize the behavior of the agent itself, you pass the
AgentConfiguration object to the
Instrumentation.start method. The
AgentConfiguration object allows you to do these things:
- Point to an on-premises EUM Server
- Enable logging
- Custom set the application name, useful if you deploy essentially the same app binary with different package names to different geographic areas. This ensures that all the data ends up being processed under the same name.
- Ignore HTTP requests internal to your application that are not used for network requests
- Configure the agent to use your custom HTTP library to send its beacons
The syntax looks like the following:
* The default URL of the EUM server is External Access Locations.
See the latest JavaDocs for more information.
Configure the Agent to Use Custom HTTP Library
The Android Agent uses HTTP to deliver its beacons. To have the agent use your custom HTTP library for this purpose, do the following.
Implement a class that extends the following abstract class:
This interface is loosely based on
Implement a version of the
CollectorChannelFactoryinterface, which looks like this:
The implementation of
newCollectorChannelshould return a new instance of your implementation of
Capture User Interactions
You can enable the Android Agent to track certain user interactions. Once user interactions have been captured, you can sort sessions by UI event and view the UI event in the timeline of the session waterfall.
You can capture when users do one or all of the following:
- press buttons
- select a text field
- click on a list item
Security and Privacy Concerns
The interaction capture mode is disabled by default for security and privacy reasons as user interactions may contain sensitive information. Moreover, this potential security and privacy issue may be compounded if you enable both the capturing of UI interactions and screenshots.
Enable User Interaction Capture Mode
To enable user interaction capture mode, pass the capture mode to the method
withInteractionCaptureMode() from an
AgentConfiguration object. The instrumentation code example below configures the Android Agent to capture all the supported types of user interactions.
You can also configure the Android Agent to only capture one type of user interaction:
Configure and Take Screenshots
Mobile screenshots are enabled by default in the Android Agent. You can configure the Controller UI to automatically take screenshots or use the Android SDK to manually take a screenshot as shown below:
For example, you might want to take a screenshot after you load a UI element to view how it's displayed to customers:
You can disable screenshots from the Controller UI or with the Android SDK. To disable screenshots with the Android SDK, use the method
withScreenshotsEnabled(false) from the
AgentConfiguration class as shown below.
You can also use the Android SDK to block screenshots from being taken during the execution of code block. This just temporarily blocks screenshots from being taken until you unblock screenshots. This enables you to stop taking screenshots in situations where users are entering personal data, such as on login and account screens.
You use the methods
Instrumentation.unblockScreenshots() to block and unblock screenshots. If screenshots are disabled through
AgentConfiguration.Builder.withScreenshotsEnabled(true) or through the Controller UI, these methods have no effect. You can call
Instrumentation.screenshotsBlocked() to check if screenshots are being blocked.
Transform URLs for Network Requests
When your application makes network requests, you may not want to report URLs containing sensitive information to the EUM Server. You can instead transform the network request URL before reporting it or ignore it altogether.
To do so:
- Implement a network request callback that modifies or ignores specific URLs.
- Register the network request callback in the initialization code.
Implement the Network Request Callback
The callback that modifies or ignore specific URLs is an implementation of the interface below. The method
onNetworkRequest is synchronous, so it is recommended that you return from the function quickly.
onNetworkRequest method, in general, should follow the steps below to transform URLs:
- Identify specific URLs using techniques such as regex or pattern matching.
- Modify the
urlproperty of the
- Assign a valid URL to the
urlproperty. (Modifying other properties of the
HttpRequestTrackerobject will be ignored.)
The first step is optional as you could choose to transform the URLs of all network requests.
In general, however, you would want to identify and transform URLs that contain sensitive information as implied in the example below.
onNetworkRequest method returns
false, the beacon is dropped. The general process for ignoring beacons is as follows:
Identify specific URLs using techniques such as regex or pattern matching.
You could theoretically ignore all network requests with the following implementation of
In general, you would identify network requests that you didn't want to monitor and return
false to ignore the network request as implied by this example.
Register the Network Request Callback
After implementing the callback, you register it in the initialization code as shown below. When the Android Agent is ready to create a network request beacon, it will first call the callback with an
Enable Logging and Set Logging Level
You use the method
withLoggingLevel of the class
AgentConfiguration to enable logging and set the logging level. You can set logging to one of the following levels:
Use verbose logging only for troubleshooting and be sure to disable for production.