# Mobile App Monitoring for Android (Kotlin) ## Introduction The ManageEngine Mobile APM Insight SDK for Android helps you monitor the performance and stability of your native Android applications on real user devices. It provides actionable insights into app behaviour and supports seamless integration with both Java and Kotlin applications. ## What the SDK monitors Gain deep insights into your application's health and performance: - **Application Crashes:** Instantly detect and analyze both fatal and non-fatal crashes with detailed diagnostics. - **ANR (Application Not Responding) Events:** Identify UI freezes and main-thread blocks that impact user experience. - **Network Request Performance:** Track API response times, failures, and latency across different network conditions. - **Custom Transactions and Logs:** Capture business-critical events for deeper troubleshooting. - **User Session Insights:** Understand how real users interact with your app and isolate issues at the session level. ## What you can achieve with the SDK Once integrated, the SDK enables you to: - **Track Business Transactions:** Measure the performance of key flows such as login, checkout, or onboarding. - **Monitor HTTP Calls Automatically:** Detect slow APIs and backend bottlenecks before they impact users. - **Capture Crashes in Real Time:** Proactively identify stability issues and resolve them faster. - **Track Screens and Fragments:** Understand screen load times and user navigation patterns. - **Tag and Track Specific Users:** Debug issues for individual users without guesswork. - **Separate Environments:** Monitor production, staging, QA, and development builds independently. - **Exclude Specific Calls or Screens:** Focus only on what matters by filtering out non-critical telemetry. - **Manually Flush Telemetry Data:** Ensure immediate transmission of performance data when needed. ## Prerequisites | Requirement | Minimum | |---|---| | Android SDK (compileSdk) | API 21 (Lollipop) or higher | | Kotlin (if applicable) | 1.8+ | | AndroidX | Required (android.useAndroidX=true in gradle.properties) | | ManageEngine Applications Manager - Mobile App monitor | An active monitor with a valid AppKey | ## Getting Started Before you can add ManageEngine APM Insight Android SDK to your Android app, you need to create a Mobile App monitor and download the configuration (**apm_config.json**) file from the Applications Manager web. - Create a new Android resource directory named **raw** inside the **res** directory (if it does not exist): **app/src/main/res/raw/** - Place the downloaded configuration file into the **raw** folder without renaming or modifying its contents: **app/src/main/res/raw/apm_config.json** - **Adding Self-Signed Server Certificate (Not recommended for production environment):** If your DEM Collector uses a self-signed (default bundled) SSL certificate, you must add the certificate to your Android project to make secure connection. To do so, copy the **apm_cert.cer** file from the DEM Collector-installed directory (**/conf/sslcerts**) and add it to the same **raw** folder: **app/src/main/res/raw/apm_cert.cer** - Add the Mobile APM SDK to your app-level **build.gradle** (or **build.gradle.kts**) file. **Groovy (build.gradle)** ```groovy dependencies { implementation "com.manageengine.apminsight:mobileapm:3.0.0" } ``` **Kotlin DSL (build.gradle.kts)** ```kotlin dependencies { implementation("com.manageengine.apminsight:mobileapm:3.0.0") } ``` - Include the repo URL in the **settings.gradle** file. ```kotlin dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://maven.zohodl.com/") content { includeGroup("com.manageengine.apminsight") } } } } ``` **Required Permissions:** Ensure the following permission is added in **AndroidManifest.xml** file: ```xml ``` ## SDK Configuration & Instrumentation ### 1. Initializing the SDK ```kotlin /** * Initializes the ME APM Insight agent. * @param context The application context. */ class MyApplication : Application() { override fun onCreate() { super.onCreate() MEAPMInsight.initMonitoring( context = this ) } } ``` **Note:** If the SDK is initialized after application startup, pass an active Activity instance as the context to ensure immediate screen and lifecycle monitoring. ### 2. Enable crash reporting The ManageEngine APM Insight SDK automatically captures all [uncaught exceptions](https://developer.android.com/reference/java/lang/Thread.UncaughtExceptionHandler). Each crash report includes the timestamp of occurrence and the complete stack trace to assist in root cause analysis. ```kotlin MEAPMInsight.enableErrorReporting() ``` ### 3. Enable ANR monitoring Detect Application Not Responding (ANR) events, situations where the main (UI) thread is blocked for too long, causing Android to show the "App isn't responding" dialog to the user. ANR monitoring must be enabled using the below API after the **initMonitoring()**. ```kotlin // Default timeout (5 seconds) MEAPMInsight.startANRWatching() // Custom timeout // Report ANR if the main thread is blocked for more than 3 seconds MEAPMInsight.startANRWatching(3000) // Stop ANR Monitoring MEAPMInsight.stopANRWatching() } ``` ### 4. Enable fragment tracking **Option 1: Enable Globally** ```kotlin MEAPMInsight.enableFragmentSupport() ``` **Option 2: Enable for specific activities only** If you want fragment tracking enabled only for certain activities, register the lifecycle callbacks manually inside those activities: ```kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportFragmentManager.registerFragmentLifecycleCallbacks( MEAPMInsightFragmentLifecycleCallbacks(), true ) } ``` ### 5. Set environment You can use the API below to set custom environment details for filtering data across various environment setups like development, debug, production, or release. ```kotlin /** *@param {String} environment Custom environment types like debug, release, or beta release. */ MEAPMInsight.setEnvironment("release") ``` ### 6. Set custom user ID Associate telemetry with a specific user. The SDK automatically hashes the user ID (SHA-256) before storing or transmitting it. By default, a unique user ID is generated by the SDK. If you want to customize user IDs, you can do so by implementing the following syntax. This comes in handy when you want to track metrics or debug issues specific to a particular user. **Important Note:** Do not pass raw Personally Identifiable Information (PII) such as email addresses, phone numbers, or real names. Use an opaque identifier like an internal user ID or UUID instead. ```kotlin /** *@param {String} userId */ MEAPMInsight.setUserId("user_12345") ``` ### 7. HTTP call tracking The SDK automatically monitors network requests performed through the following libraries without additional configuration: - `java.net.HttpURLConnection` - `javax.net.ssl.HttpsURLConnection` - `OkHttp` (when the SDK interceptor is added) ```kotlin val client = OkHttpClient.Builder() .addNetworkInterceptor(MEAPMInsightInterceptor()) .build() ``` If your application uses a custom networking layer or libraries that are not automatically monitored, you can manually track HTTP calls using the following API: ```kotlin /** * @param {String} url * The complete request URL. * * @param {String} requestMethod * The HTTP method used (e.g., GET, POST, PUT, DELETE). * * @param {long} startTime * The request start time in milliseconds. * You can obtain this using System.currentTimeMillis(). * * @param {long} loadTime * The total time taken to complete the request, measured in milliseconds. * * @param {int} responseCode * The HTTP response status code returned by the server. * * @param {String} screen * The name of the screen from which the HTTP call was initiated. */ Apm.addHttpCalls( "https://www.example.com", "GET", System.currentTimeMillis(), 526, 200, "PaymentScreen" ); ``` ### 8. Screen tracking By default, the SDK automatically captures all screens (Activities). If a screen is not detected automatically, you can manually track it using the API below: ```kotlin /** *@param {String} screenName *@param {String} orientation *@param {long} loadTime measured in millis *@param {long} startTime measured in millis */ Apm.addScreen("DetailScreen", "portrait", 50, 1642743078700) ``` ## Business-level monitoring ### 1. Transactions Start a transaction using `Apm.startTransaction("Transaction_Name")` before a long-running operation and call stop() when it completes. Transactions are: - **Thread-safe:** can be started and stopped across different threads. - **Single-use:** each transaction instance can only be started and stopped once. - **Averaged by name:** Transactions with the same name are grouped together. When the same operation runs multiple times using the same transaction name, the SDK records the average execution time across those occurrences. Use clear, consistent names to track business operations accurately. ```kotlin val transaction = Apm.startTransaction("List Articles") // Start predefined HTTP component val httpComponent = transaction.startComponent(Component.TYPE_HTTP) // Start custom component val articlesComponent = transaction.startComponent("Download Articles") // Download articles transaction.stopComponent(articlesComponent) for (article in articles) { val thumbnailComponent = transaction.startComponent("Download Thumbnail") // Download thumbnail transaction.stopComponent(thumbnailComponent) } // Stop HTTP component transaction.stopComponent(httpComponent) // Stop transaction Apm.stopTransaction(transaction) ``` ## Advanced controls ### 1. Flush data Use the API below to immediately upload the recorded telemetry data to the server instead of waiting for the next scheduled upload cycle. By default, the SDK uploads data at 60-second intervals. ```kotlin MEAPMInsight.flush() ``` ### 2. Exclude HTTP calls Specific URLs can be excluded from tracking by passing a list of those URLs to the API below. ```kotlin MEAPMInsightexcludeHttpCalls(listOf("example.com", "test.com")) ``` ### 3. Exclude screens Custom screens can be excluded from tracking by passing a list of screen names to the API below. ```kotlin MEAPMInsight.excludeScreens(listOf("customScreenName")) ``` ### 4. Stop monitoring Use the API below to stop all data collection (screens, HTTP calls, transactions, crashes, ANR detection). ```kotlin MEAPMInsight.stopMonitoring() ``` ### 5. Mask sensitive data The SDK automatically masks the values of known sensitive query parameters and headers, replacing them with ***** before any data is sent to the server. The following keys will be masked automatically: - *apikey, api_key, apitoken, api_token* - *authorization, auth, token, access_token, refresh_token, auth_token, secret, client_secret* - *username, user, email, password, passwd, pass* - *sessionid, session_id, session_token* To add custom sensitive keys, use the API below: ```kotlin MEAPMInsight.addSensitiveParams(listOf("x-custom-token", "account_id", "ssn")) ``` ### 6. ProGuard / R8 Rules If you use code obfuscation, add the following rules to your **proguard-rules.pro** file: ```proguard -keep class manageengine.mobileapm.android.apm.** { *; } -dontwarn manageengine.mobileapm.android.apm.** ```