Android SDK docs

Download the Android SDK (minSdk 21+, usable from Java and Kotlin), add it with Gradle, initialize it, and learn the auto-collected events and metrics.

Overview

App Analytics is a separate product line: launches, screens, versions, channels, crashes, ANRs and launch time have their own events and definitions — Web PV and bounce rate do not apply. Web pages embedded in the app can keep using Web Analytics.

1
Create an appAdd the app under "My apps" in the console to get an APP_KEY.
2
Add the SDKAdd the dependency from the Maven repository, or download the AAR.
3
Configure and initializeSet FMENG_APPKEY in AndroidManifest and call Fmeng.init in Application.onCreate.
4
View reportsLaunch the app once; after the installation check passes you can see the overview, crashes and launch time.

Download the SDK

Served via Cloudflare (a.t3j.com), best when most visitors are outside mainland China

Using the Maven repository is recommended (see the next section). If you cannot reach it, put the SDK AAR into app/libs/ — crash capture depends on xCrash, so manual integration needs both AARs.

Maven repository: http://a.t3j.com/maven/

The demo app includes the SDK; install it on a phone and tap the buttons to try custom events, screen changes, crashes and ANRs.

Dependency for manual integration:
groovy
// app/build.gradle — put fmeng-android-sdk-1.2.1.aar and xcrash-android-lib-3.1.0.aar into app/libs/
dependencies {
implementation fileTree(dir: "libs", include: ["*.aar"])
}

Gradle setup

Add the Fmeng Maven repository to dependencyResolutionManagement.repositories in settings.gradle; mavenCentral() is needed for xCrash:

Groovy
// settings.gradle
dependencyResolutionManagement {
repositories {
google()
mavenCentral() // xCrash
maven {
url "http://a.t3j.com/maven/"
allowInsecureProtocol = true
}
}
}
The current collection address is http: Gradle refuses http repositories by default, so allowInsecureProtocol = true is required; remove it once you switch to https.

Then add the dependency to app/build.gradle:

Groovy
// app/build.gradle
dependencies {
implementation "com.fmeng:fmeng-android-sdk:1.2.1"
}

ProGuard rules ship with the AAR (consumer rules), so nothing needs to go into proguard-rules.pro; the INTERNET and ACCESS_NETWORK_STATE permissions are merged into your AndroidManifest automatically.

Initialization

As with Umeng, the App Key and channel go under <application> in AndroidManifest.xml: FMENG_APPKEY is the APP_KEY (see "App settings - Basic info"; the "Setup code" tab fills it in for you) and FMENG_CHANNEL is the install channel (optional, used by the Versions & channels report).

xml
<!-- AndroidManifest.xml -->
<application
android:name=".MyApplication"
... >
<meta-data android:name="FMENG_APPKEY" android:value="APP_KEY" />
<!-- optional: install channel; use ${FMENG_CHANNEL} for multi-channel builds -->
<meta-data android:name="FMENG_CHANNEL" android:value="official" />
</application>

For multi-channel builds set FMENG_CHANNEL to ${FMENG_CHANNEL} and fill it per productFlavor, so each channel build carries its own channel:

Groovy
// app/build.gradle — AndroidManifest: <meta-data android:name="FMENG_CHANNEL" android:value="${FMENG_CHANNEL}" />
android {
flavorDimensions "channel"
productFlavors {
official { dimension "channel" }
huawei { dimension "channel" }
xiaomi { dimension "channel" }
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders.put("FMENG_CHANNEL", flavor.name)
}
}

Then initialize as early as possible in Application.onCreate so the SDK can measure cold starts and catch crashes during startup. The SDK reads the App Key and channel from AndroidManifest; with default options just call Fmeng.init(this).

Java
// MyApplication.java
import android.app.Application;
import com.fmeng.analytics.Fmeng;
import com.fmeng.analytics.FmengConfig;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// App Key / channel come from AndroidManifest (FMENG_APPKEY / FMENG_CHANNEL).
// Default options only: Fmeng.init(this);
Fmeng.init(this, new FmengConfig.Builder()
.debug(BuildConfig.DEBUG) // logcat output
.build());
}
}

If you have no custom Application, create one and declare it in <application android:name=".MyApplication"> of AndroidManifest.xml.

You can also skip the meta-data and pass them in code: new FmengConfig.Builder("APP_KEY").channel("huawei"). Values set in code take precedence over AndroidManifest.

Options

Options (the App Key and channel can also be set as AndroidManifest meta-data; values in code take precedence):

AttributeDefaultDescription
FMENG_APPKEY / Builder(appKey)RequiredThe APP_KEY generated when you created the app in the console.
FMENG_CHANNEL / channel(String)EmptyInstall channel (e.g. huawei, xiaomi, official), used by the Versions & channels report.
FMENG_REGION / region(String)GlobalCollection node: cn reports to the China mainland node, for apps whose users are mostly in mainland China (1.2.0+). Both nodes feed the same console.
debug(boolean)falseLog sending to logcat; pass BuildConfig.DEBUG.
crashReport(boolean)trueCapture Java and Native crashes (xCrash); sent on the next launch.
anrReport(boolean)trueCapture ANRs (App Not Responding); sent on the next launch.
autoTrackScreens(boolean)trueRecord each Activity as a screen view; use trackScreen for Fragment / Compose screens.
sessionTimeoutMillis(long)30000Returning to the foreground after this long in the background counts as a new launch (session).

Manual APIs

Business events, manual screens and signed-in users. Property values can be strings, numbers or booleans:

Java
Map<String, Object> props = new HashMap<>();
props.put("sku", "A100");
props.put("price", 199);
Fmeng.track("purchase", props); // custom event
Fmeng.trackScreen("HomeFragment"); // manual screen (Fragment / Compose)
Fmeng.setUserId("u_123"); // after sign-in; null on sign-out
Fmeng.flush(); // send queued events now
Fmeng.setEnabled(false); // stop collecting (e.g. before privacy consent)

After setEnabled(false) the SDK stops collecting and sending (e.g. before the user accepts your privacy policy); call setEnabled(true) to resume.

HTTP collection address

Since Android 9 (API 28), cleartext HTTP is blocked by default. If the collection address is http, allow cleartext traffic for its domain: create res/xml/network_security_config.xml and reference it on <application> in AndroidManifest. Skip this step for https addresses.

xml
<?xml version="1.0" encoding="utf-8"?>
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">a.t3j.com</domain>
</domain-config>
</network-security-config>
<!-- AndroidManifest.xml -->
<application
android:name=".MyApplication"
android:networkSecurityConfig="@xml/network_security_config"
... >

Auto-collected events

The SDK collects the following events automatically. Events are written to a local queue (up to 1,000), sent in gzip batches and retried with exponential backoff; crashes are written to disk synchronously and sent on the next launch.

EventFired whenKey fields
launchCold, warm and hot startslaunch_type, duration (ms)
foregroundApp returns to the foregroundSession ID
backgroundApp goes to the background (the queue is flushed immediately)Foreground duration
screen_viewAn Activity is shown, or trackScreen is calledScreen name
crash (java / native)Uncaught Java / Native exceptionType, message, stack, thread, foreground
crash (anr)Main thread blocked for more than 5 secondsMain thread stack, foreground

Every batch carries the device context: app version, channel, OS version, manufacturer, model, screen size, network, carrier and language. Location is resolved from the IP on the server; the visitor IP is stored on the server and is only available through the open API (MCP), not shown in the console.

Metrics

  • Active users: distinct devices with events in the range. New users: devices first seen within the range.
  • Launches: number of sessions; returning to the foreground after more than 30 seconds (configurable) in the background starts a new one. Launches per user = launches ÷ active users.
  • Avg. session length: total foreground time per launch ÷ launches.
  • Time on screen: time until the next screen view or background event in the same session, capped at 30 minutes.
  • Crash rate = sessions with a crash (Java + Native) ÷ sessions; crash-free users = 1 − devices with a crash ÷ active devices. ANRs are counted separately.
  • Crashes are grouped into issues by kind + exception class + top 5 stack frames (line numbers removed).
  • Launch time: P50, P75 and P90 for cold, warm and hot starts separately.
  • Retention: new users grouped by first-use date, share still active on day N.
Didn't find an answer?After signing in, check the announcements under the bell at the top right, or find our contact details on the About page.