Skip to main content
Version: 4.6.1-saas

Android Agent

Overview

The NetFUNNEL Android agent is a dedicated client that communicates with the NetFUNNEL server from mobile applications. Users can apply a virtual waiting room by applying and implementing the various functions provided by the agent in their client application code.

Minimum Requirements

  • Android API Level 22 (Lollipop 5.1) or higher
  • Java 1.8 or higher
  • Kotlin 2.0.0-RC1 or higher

External Dependencies

  • Ktor (3.0.0 or higher)
  • Kotlinx Serialization (any version)

Agent Operation Flow

Before Waiting

  • Before waiting, configuration is initialized. This process involves fetching configuration from the NetFUNNEL server and initializing objects based on that information.
  • Use the "initialization function" to initialize NetFUNNEL configuration.

While Waiting

  • This is the process of displaying the virtual waiting room and applying traffic waiting on the screen (Activity or Fragment) where you want it.
  • Use the "wait start function" to apply the virtual waiting room.

After Waiting

  • This is the process of handling situations after waiting ends. Situations where an end-user's wait ends are:
    • Entry success after waiting
    • Entry failure due to server or network error during waiting
    • End-user cancels waiting during wait
  • Use the "callback function" and "wait stop function" to implement logic after waiting ends.

Agent Installation

info

This guide is written for the Android Studio environment.

The NetFUNNEL Android agent is provided in .aar (Android Archive) format. Add the .aar file to your Android project and register the dependency through Gradle configuration.

Agent Download

Download the NetFUNNEL Android agent from the agent tab in the NetFUNNEL Console.

Add .aar File

Copy the provided .aar file to the app/libs directory of your project.

Project root/
├── app/
| └── libs/
| └── netfunnel-android-agent-release-{{latest}}.aar
| └── netfunnel-android-agent-debug-{{latest}}.aar
└── gradle/

Gradle Configuration

Add Agent Dependency

Add the dependency to the build.gradle file as follows so that the .aar file is recognized.

Kotlin DSL (build.gradle.kts)

dependencies {
implementation(files("libs/netfunnel-android-agent-release-{{latest}}.aar"))
...
}

Groovy DSL (build.gradle)

dependencies {
implementation files("libs/netfunnel-android-agent-release-{{latest}}.aar")
...
}
info

The NetFUNNEL Android agent provides two files depending on the build environment. Use debug for debugging and release for app distribution.

Add External Libraries

The NetFUNNEL Android agent does not include external libraries. Add the following libraries to your project.

Kotlin DSL (build.gradle.kts)

dependencies {
val ktorVersion = "{{KTOR_VERSION}}"
val serializationVersion = "{{SERIALIZATION_VERSION}}"

// Ktor dependencies
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")

// Serialization dependency
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
...
}

Groovy DSL (build.gradle)

ext {
ktorVersion = "{{KTOR_VERSION}}"
serializationVersion = "{{SERIALIZATION_VERSION}}"
}

dependencies {
// Ktor dependencies
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"

// Serialization dependency
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion"
...
}

Manifest Configuration

Internet permission must be added to communicate with the NetFUNNEL server. Allow internet access in the AndroidManifest.xml file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

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

</manifest>

Agent Initialization

The NetFUNNEL Android agent must be initialized when the app starts.

info

Perform initialization in the Application class's onCreate() so that it runs only once at app startup.

Kotlin

Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
serverUrl = "{{SERVER_URL}}",
errorUrl = "{{ERROR_URL}}",
networkTimeout = 3000,
retryCount = 0,
printLog = false,
errorBypass = false,
useNetfunnelTemplate = true,
userId = "{{USER_ID}}",
useNetworkRecoveyMode = true,
healthCheckUrl = "{{HEALTH_CHECK_URL}}",
statusBarStyle = null
)

Java

Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}",
"{{SERVER_URL}}",
"{{ERROR_URL}}",
3000,
0,
false,
false,
true,
"{{USER_ID}}",
true,
"{{HEALTH_CHECK_URL}}",
null
);
ParameterTypeDescriptionRequiredCondition
clientIdStringUser unique identifierOCannot be empty string
serverUrlStringNetFUNNEL server addressXNone (use default address)
errorUrlStringHTML address of NetFUNNEL error pageXNone (use default address)
networkTimeoutLongMaximum time to wait for network responseXDefault (ms): 3,000
Max (ms): 10,000
Min (ms): 100
retryCountIntNumber of retries on network request failureXDefault (times): 0
Max (times): 10
Min (times): 0
printLogBooleanWhether to print logs for debuggingXDefault: false
errorBypassBooleanWhether to bypass on errorXDefault: false
useNetfunnelTemplateBooleanWhether to use NetFUNNEL waiting room customized in ConsoleXDefault: true
userIdStringEnd-user unique identifier for blacklist/whitelist checkXDefault: null
useNetworkRecoveryModeBooleanWhether to use waiting room retention and reconnection on network disconnectXDefault: false
healthCheckUrlStringHealth check URL to distinguish network delay from NetFUNNEL server failureXDefault: null
statusBarStyleStringStatus bar transparency option for NetFUNNEL waiting room (WebView)XDefault: null

Agent Application

You can apply the waiting room to specific screens using the functions provided by the NetFUNNEL Android agent.

info

Project Key and Segment Key used in the start and stop functions can be found in the Console's project tab.

Callback Functions

To use the NetFUNNEL Android agent, you must inject callback functions into the start and stop functions.

The waiting room can end in various situations (wait success, cancel, block, error, network error, etc.), and handling for each situation can be implemented through callback functions.

abstract classabstract functionRequired
NetfunnelCallbackonSuccessRequired
NetfunnelCallbackonErrorRequired
NetfunnelCallbackonNetworkErrorRequired
NetfunnelCallbackonBlockOptional
NetfunnelCallbackonCloseOptional
NetfunnelCallbackonContinueOptional
NetfunnelCompleteCallbackonCompleteOptional

Start Callback - NetfunnelCallback

CallbackStatus CodeScenario
onSuccess200Passed queue normally; service access allowed
onSuccess300Subscription or license expired
Console project/segment deactivated
Agent errorBypass=true and error occurred
onSuccess303Request with IP or ID registered on Console whitelist (admin bypass)
onError500Start function called without agent initialization
Non-existent project/segment key in start function
Segment deleted in Console
Response partially missing due to server error
onNetworkError1001Network connection blocked (Wi-Fi, cellular data blocked)
onNetworkError1002Network timeout
Invalid HTML URL received due to server error
No response due to server down (502, etc.)
onBlock301Console segment block (voluntary entry block)
onBlock302Request with IP or ID on Console blacklist (admin block)
Console BotManager Basic enabled (malicious entry block)
onClose495Post-wating room close button or back button pressed
onClose496Pre-waiting room close button or back button pressed
onClose497Macro block room close button or back button pressed
onClose498Block Room close button or back button pressed
onClose499Waiting Room cancel button or back button pressed
onContinue201Agent useNetfunnelTemplate=false and default wait

Kotlin

import com.nf4.NetfunnelCallback

class StartCallback {

companion object {
private const val TAG = "NetFUNNEL"
}

private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
Log.d(TAG, "onSuccess $statusCode $message")
/**
* Logic to run when queue is passed
* ex - service screen entry
*/
}

override fun onError(statusCode: Int, message: String) {
Log.d(TAG, "onError $statusCode $message")
/**
* Logic to run on error
* ex - show error message to user or bypass
*/
}

override fun onNetworkError(statusCode: Int, message: String) {
Log.d(TAG, "onNetworkError $statusCode $message")
/**
* Logic to run on network error
* ex - guide to reconnect or navigate to retry screen
*/
}

override fun onBlock(statusCode: Int, message: String) {
Log.d(TAG, "onBlock $statusCode $message")
/**
* Logic when user entry is blocked
* ex - show access denied message
*/
}

override fun onClose(statusCode: Int, message: String) {
Log.d(TAG, "onClose $statusCode $message")
/**
* Logic when user cancels wait or presses back (WebView closes and returns to previous screen)
* ex - show exit Toast
*/
}

override fun onContinue(statusCode: Int, message: String, aheadWait: Int, behindWait: Int, waitTime: String, progressRate: Int) {
Log.d(TAG, "onContinue $statusCode $message")
/**
* UI update logic while waiting (only when using custom waiting room)
* ex - update custom waiting screen with real-time wait info
*/
}
}

fun getCallback(): NetfunnelCallback = callback
}

Java

import com.nf4.NetfunnelCallback;

public class StartCallback{

private static final String TAG = "NetFUNNEL";

private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
Log.d(TAG, "onSuccess " + statusCode + " " + message);
/**
* Logic to run when queue is passed
* ex - service screen entry
*/
}

@Override
public void onError(int statusCode, @NonNull String message) {
Log.d(TAG, "onError " + statusCode + " " + message);
/**
* Logic to run on error
* ex - show error message to user or bypass
*/
}

@Override
public void onNetworkError(int statusCode, @NonNull String message) {
Log.d(TAG, "onNetworkError " + statusCode + " " + message);
/**
* Logic to run on network error
* ex - guide to reconnect or navigate to retry screen
*/
}

@Override
public void onBlock(int statusCode, @NonNull String message) {
Log.d(TAG, "onBlock " + statusCode + " " + message);
/**
* Logic when user entry is blocked
* ex - show access denied message
*/
}

@Override
public void onClose(int statusCode, @NonNull String message) {
Log.d(TAG, "onClose " + statusCode + " " + message);
/**
* Logic when user cancels wait (WebView closes and returns to previous screen)
* ex - show exit Toast
*/
}

@Override
public void onContinue(int statusCode, @NonNull String message, int aheadWait, int behindWait, @NonNull String waitTime, int progressRate) {
Log.d(TAG, "onContinue " + statusCode + " " + message);
/**
* UI update logic while waiting (only when using custom waiting room)
* ex - update custom waiting screen with real-time wait info
*/
}
};

public NetfunnelCallback getCallback() {
return callback;
}
}

Stop Callback - NetfunnelCompleteCallback

CallbackStatus CodeScenario
onComplete200Entry key successfully returned to server after wait
onComplete500Entry key return to server failed after wait

Kotlin

import com.nf4.NetfunnelCompleteCallback

class StopCallback {

companion object {
private const val TAG = "NetFUNNEL"
}

private val callback = object : NetfunnelCompleteCallback() {
override fun onComplete(statusCode: Int, message: String) {
Log.d(TAG, "onComplete $statusCode $message")
/**
* Logic for entry key return result
* ex - navigate to next page on successful key return
*/
}
}

fun getCallback(): NetfunnelCompleteCallback = callback
}

Java

import com.nf4.NetfunnelCompleteCallback;

public class StopCallback {

private static final String TAG = "NetFUNNEL";

private final NetfunnelCompleteCallback callback = new NetfunnelCompleteCallback() {
@Override
public void onComplete(int statusCode, @NonNull String message) {
Log.d(TAG, "onComplete " + statusCode + " " + message);
/**
* Logic for entry key return result
* ex - navigate to next page on successful key return
*/
}
};

public NetfunnelCompleteCallback getCallback() {
return callback;
}
}

Basic Control

Start Function

To apply the waiting room on a specific screen (Activity or Fragment), use the "wait start function" to show the virtual waiting room. Basic Control is useful for applying wait when an end-user enters a specific screen to manage server load and end-user experience.

Kotlin

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

Java

Netfunnel.INSTANCE.nfStart("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity);
ParameterTypeDescriptionRequired
projectKeyStringConsole Basic Control project keyO
segmentKeyStringConsole Basic Control segment keyO
callbackNetfunnelCallbackUser-defined callback for waiting room eventsO
activityActivityScreen where waiting room is appliedO

Stop Function

When Basic Control wait completes successfully, you must implement the following:

  • Code to enter the service after wait (code to enter the target page)
  • Code that calls the "wait stop function" after business logic to return the service entry key to the NetFUNNEL server

Kotlin

Netfunnel.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)

Java

Netfunnel.INSTANCE.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback);
ParameterTypeDescriptionRequired
projectKeyStringProject key used in wait start functionO
segmentKeyStringSegment key used in wait start functionO
completeCallbackNetfunnelCompleteCallbackUser-defined callback for key return after waitO

Section Control

Start Function

Section Control applies a waiting state between entry and exit of a specific page. With Section Control, users can maintain a smooth flow in a specific section of the page.

  • After entering an event page, purchasing a product, and clicking the payment complete button
  • From end-user login until logout

To start Section Control, use the "section start function" to define the start of the control section. This keeps the waiting state in that section's flow.

Kotlin

Netfunnel.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity)

Java

Netfunnel.INSTANCE.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity);
ParameterTypeDescriptionRequired
projectKeyStringConsole Section Control project keyO
segmentKeyStringConsole Section Control segment keyO
callbackNetfunnelCallbackUser-defined callback for waiting room eventsO
activityActivityScreen where waiting room is appliedO

Stop Function

When Section Control wait completes successfully, you can implement:

  • Code to enter the service after wait (code to enter the target page)

To end Section Control, use the "section stop function" to define the end of the section. This ends the end-user's section control and allows the next end-user to enter.

Kotlin

Netfunnel.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)

Java

Netfunnel.INSTANCE.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback);
ParameterTypeDescriptionRequired
projectKeyStringProject key used in wait start functionO
segmentKeyStringSegment key used in wait start functionO
completeCallbackNetfunnelCompleteCallbackUser-defined callback for key return after waitO