Skip to main content
Version: 4.6.1

Quickstart

Get your NetFUNNEL 4 Android Agent up and running in 5-10 minutes with this quickstart guide.

What you can do with this guide

  • Code-based Integration: Apply traffic control by calling NetFUNNEL functions in your Android code
  • Basic Control: Limit entry speed for activities, button clicks, and API calls
  • Section Control: Control concurrent users within specific application sections
Choose Your Control Type

Not sure which control type to use? Check out the Integration Methods Overview to compare Basic Control and Section Control approaches and find the best fit for your use case.


Prerequisites

  • NetFUNNEL console access
  • Android Studio environment
  • Basic understanding of Android development (Java/Kotlin)
  • Android API Level 22 (Lollipop 5.1) or higher
Practice Projects Available

Need a basic project to practice with? Check out our Sample Projects which include an Android Application (Single Activity) template ready for NetFUNNEL SDK integration practice.


Step 1: Install SDK & Initialize Agent

1.1 Download SDK from NetFUNNEL Console

  1. Log in to your NetFUNNEL console
  2. Navigate to Agent → Mobile Agent → Android
  3. Download the ZIP file: netfunnel-android-agent-{{version}}.zip
  4. Extract to get AAR files:
    • netfunnel-android-agent-debug-{{version}}.aar (development)
    • netfunnel-android-agent-release-{{version}}.aar (production)

1.2 Add Dependencies

1. Place AAR files:

  • Create app/libs/ directory
  • Copy AAR files to app/libs/

2. Configure app/build.gradle:

dependencies {
// NetFUNNEL Android Agent
implementation(files("libs/netfunnel-android-agent-debug-{{version}}.aar"))

// External dependencies
val ktorVersion = "2.3.12"
val serializationVersion = "1.6.3"

implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-gson:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
}

android {
compileSdk = 34
defaultConfig {
minSdk = 22
targetSdk = 34
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}

3. Add internet permission to AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

1.3 Initialize Agent

Get initialization code from NetFUNNEL console:

  1. Go to Agent → Mobile Agent → Android
  2. Copy the initialization code with your actual client ID

Add to your Application class:

Critical: Must Initialize First

Initialize in Application.onCreate() before super.onCreate(). Missing this step = bypass mode (no protection).

class YourAppNameApplication : Application() {
override fun onCreate() {
super.onCreate()

Netfunnel.initialize(
clientId = "{{CLIENT_ID}}"
)
}
}

Register Application class in AndroidManifest.xml:

<application android:name=".YourAppNameApplication">
<!-- Your activities -->
</application>
Use Real Code

Replace the example client ID with your actual client ID from the console.


Step 2: Choose Your Control Type

Option A: Basic Control (5 minutes)

Best for: Activity entry, button clicks, API calls

  1. Add the SDK to your project (see Installation & Initialization)
  2. Create a segment in NetFUNNEL console:
    • Go to ProjectsSegmentsCreate Segment
    • Choose Basic Control
    • Set Limited Inflow to 0 (for testing)
  3. Add this code to your activity:
import com.nf4.Netfunnel
import com.nf4.NetfunnelCallback
import com.nf4.NetfunnelCompleteCallback

// When user enters an activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

Netfunnel.nfStart("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, this)
}

private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
// User can proceed - run your original logic
setupUI()
}

override fun onError(statusCode: Int, message: String) {
// System error - proceed with original logic for service availability
setupUI()
}

override fun onNetworkError(statusCode: Int, message: String) {
// Network error - log only, rely on network recovery mode
Log.d("NetFUNNEL", "Network error: $message")
}

override fun onBlock(statusCode: Int, message: String) {
// User is blocked - show appropriate message
Log.d("NetFUNNEL", "User blocked: $message")
}

override fun onClose(statusCode: Int, message: String) {
// User closed waiting room - handle appropriately
Log.d("NetFUNNEL", "User closed waiting room: $message")
}

override fun onContinue(
statusCode: Int,
message: String,
aheadWait: Int,
behindWait: Int,
waitTime: String,
progressRate: Int
) {
Log.d("NetFUNNEL", "Continue: $message, waitTime: $waitTime")
}
}

// Return key when user leaves
override fun onDestroy() {
super.onDestroy()
Netfunnel.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)
}

Result: A waiting room appears when users enter the activity.

Option B: Section Control (10 minutes)

Best for: Multi-step processes, maintaining concurrent user limits

  1. Add the SDK to your project (same as Option A)
  2. Create a segment in NetFUNNEL console (choose Section Control)
  3. Add this code to your checkout/payment flow:
import com.nf4.Netfunnel
import com.nf4.NetfunnelCallback
import com.nf4.NetfunnelCompleteCallback

// Start section (e.g., checkout process)
fun startCheckout() {
Netfunnel.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, this)
}

private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
// User entered the section
showCheckoutForm()
}

override fun onError(statusCode: Int, message: String) {
// System error - proceed with original logic for service availability
showCheckoutForm()
}

override fun onNetworkError(statusCode: Int, message: String) {
// Network error - log only, rely on network recovery mode
Log.d("NetFUNNEL", "Network error: $message")
}

override fun onBlock(statusCode: Int, message: String) {
// User is blocked - show appropriate message
Log.d("NetFUNNEL", "User blocked: $message")
}

override fun onClose(statusCode: Int, message: String) {
// User closed waiting room - handle appropriately
Log.d("NetFUNNEL", "User closed waiting room: $message")
}

override fun onContinue(
statusCode: Int,
message: String,
aheadWait: Int,
behindWait: Int,
waitTime: String,
progressRate: Int
) {
Log.d("NetFUNNEL", "Continue: $message, waitTime: $waitTime")
}
}

// End section (e.g., after payment completion)
fun completeCheckout() {
// Your checkout completion logic
processPayment()

// Return key after successful completion
Netfunnel.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)
}

Result: Users wait in queue before entering the checkout section, maintaining controlled concurrency.


Step 3: Test It Works

For Basic Control:

  1. Set Limited Inflow to 0 in your segment (waiting room should appear)
  2. Check the waiting room displays correctly (shows estimated wait time)
  3. Set Limited Inflow to 1 (should enter immediately)
  4. Verify key return in logs or network monitoring

For Section Control:

  1. Set Limited Inflow to 0 in your segment (waiting room should appear)
  2. Check the waiting room displays correctly (no estimated wait time shown)
  3. Set Limited Inflow to 1 (should enter section immediately)
  4. Navigate through section (Section1 → Section2 → End)
  5. Verify key timeout extension in logs (look for 5003 requests)
  6. Verify key return when section completes

Need Help?

  • Troubleshooting: Common issues and solutions
  • Check the Android logs for NetFUNNEL messages (enable printLog = true)
  • Verify your project/segment keys match the console exactly