To enable app protection for your Android apps, integrate the Anti-Bot SDK (referred to as SDK in this topic) before activating the feature.
Limitations
Android API level 16 or later is required. If your app targets an earlier API level, the SDK will not work as expected.
Prerequisites
Before you begin, make sure you have:
App protection purchased and enabled. See Procedure to enable app protection.
The SDK package (AAR file) for Android. Contact technical support in the DingTalk service group, or submit a ticket to request it. The file is named
AliTigerTally_X.Y.Z.aar, whereX.Y.Zis the version number.The app key (SDK authentication key). To get it, log on to the WAF console, choose Protection Configurations > Website Protection, go to the Bot Management tab, turn on App Protection, and click Obtain and Copy Appkey.
Each Alibaba Cloud account has one unique app key that works for all domain names in your Web Application Firewall (WAF) instance, and for both Android and iOS apps.Example app key:
****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****How it works
The SDK signs each outgoing request from your app. WAF verifies these signatures server-side to detect and block malicious traffic, then forwards legitimate requests to your origin server.
(Optional) Create a test Android project
If you want to practice the integration steps before applying them to your production app, create a test project in Android Studio first.
The following figure shows a sample test project named TigerTally_sdk_test. 
Run the test project to verify it works before proceeding. 
Integrate the SDK
Step 1: Open the project in Android Studio
Open your project in Android Studio and navigate to the project's file directory.
Step 2: Add the AAR dependency
Copy
AliTigerTally.aarinto thelibsdirectory of your project. You can also drag the file directly into the directory.
Open
build.gradleand add the following configurations:Declare
libsas a local repository:repositories { flatDir { dirs 'libs' } }Add a compile dependency:
dependencies { compile(name: 'AliTigerTally_X.Y.Z', ext: 'aar') }Important: Replace
X.Y.Zwith the actual version number from the AAR filename you downloaded.
Click Sync Now to apply the changes.
If you use ProGuard to obfuscate your app, add the following rule to your ProGuard configuration file immediately after adding the dependency. This prevents SDK classes from being stripped at build time, which would cause runtime failures.
-keep class com.aliyun.TigerTally.* {*;}
Step 3: Configure native library filters (if needed)
Skip this step if your project already includes an SO file. Otherwise, add the following ndk block to build.gradle:
android {
defaultConfig {
ndk {
abiFilters 'arm64-v8a', 'x86', 'armeabi-v7a'
//abiFilters "armeabi-v7a"
}
}
}Step 4: Apply for permissions
Add the following permissions to your AndroidManifest.xml. Only INTERNET is required for the SDK to function.
| Permission | Required | Runtime request (Android 6.0+) | Description |
|---|---|---|---|
android.permission.INTERNET | Yes | No — automatically granted at install | Allows the SDK to send signed requests to WAF. |
android.permission.ACCESS_NETWORK_STATE | No | No — automatically granted at install | Reads the device network status for enhanced risk signals. |
android.permission.ACCESS_WIFI_STATE | No | No — automatically granted at install | Reads the Wi-Fi connection status for enhanced risk signals. |
android.permission.READ_PHONE_STATE | No | Yes — must request at runtime | Reads device identity for enhanced risk signals. |
android.permission.BLUETOOTH | No | No — automatically granted at install | Reads Bluetooth device information for enhanced risk signals. |
android.permission.READ_EXTERNAL_STORAGE | No | Yes — must request at runtime | Reads external storage for enhanced risk signals. |
android.permission.CHANGE_NETWORK_STATE | No | No — automatically granted at install | Modifies network connectivity state for enhanced risk signals. |
Step 5: Add the integration code
5a. (Optional) Set the user ID
Call setAccount() to associate a user ID with SDK requests. This helps WAF apply user-level protection policies. Skip this call if the user is not logged in — call init() directly instead.
// Signature: int setAccount(String account)
// Returns: 0 on success, -1 on failure
final String account = "account"; // Use a masked user ID
TigerTallyAPI.setAccount(account);| Parameter | Type | Description |
|---|---|---|
account | String | The user ID. Use a masked value to protect user privacy. |
5b. Initialize the SDK
Call init() once when your app starts. This performs a one-time collection of device information used for risk analysis.
Two collection modes are available:
`DEFAULT`: Collects all device data, including sensitive fields (
imei,imsi,simSerial,wifiMac,wifiList,bluetoothMac). Requires the corresponding permissions. Use this mode after the user has accepted the app's privacy policy.`NOT_GRANTED`: Skips sensitive fields. Use this mode before the user has accepted the privacy policy.
// Signature: int init(Context context, String appkey, int type)
// Returns: 0 on success, -1 on failure
final String appkey = "your_appkey";
// Full data collection (after user accepts privacy policy)
int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.CollectType.DEFAULT);
// Exclude sensitive fields (before user accepts privacy policy)
int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.CollectType.NOT_GRANTED);
Log.d("AliSDK", "ret:" + ret);| Parameter | Type | Description |
|---|---|---|
context | Context | The application context. |
appkey | String | The app key obtained from the WAF console. |
type | CollectType | Data collection mode: DEFAULT or NOT_GRANTED. |
5c. Sign the request
Call vmpSign() before each outgoing HTTP request. Pass the request body as a byte array; for GET requests or empty POST bodies, pass null or "".getBytes("UTF-8").
// Signature: String vmpSign(int signType, byte[] input)
// Returns: the wToken signature string
String request_body = "i am the request body, encrypted or not!";
String wToken = null;
try {
wToken = TigerTallyAPI.vmpSign(1, request_body.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.d("AliSDK", "wToken:" + wToken);| Parameter | Type | Description |
|---|---|---|
signType | int | Signature algorithm. Set to 1 to use the default algorithm. |
input | byte[] | The request body to sign. Pass null or an empty byte array for GET or empty POST requests. |
5d. Add the signature to the HTTP header
Set the wToken value as an HTTP header property before sending the request. The following example uses HttpURLConnection:
String request_body = "i am the request body, encrypted or not!";
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL("https://www.aliyundoc.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("POST");
// Add the wToken signature to the request header
conn.setRequestProperty("wToken", wToken);
OutputStream os = conn.getOutputStream();
// Write the request body
byte[] requestBody = request_body.getBytes("UTF-8");
os.write(requestBody);
os.flush();
os.close();
int code = conn.getResponseCode();
Log.d("respCode", Integer.toString(code));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();What happens after integration
Once integrated, for every outbound request your app sends:
vmpSign()generates awTokensignature from the request body.Your code attaches
wTokenas an HTTP header.WAF inspects the
wTokenheader, blocks requests that fail signature verification, and forwards valid requests to your origin server.
Example app key: