Practical Android Device Security Checks: Identifying Enabled Developer Options, ADB Debugging, and Root Access

To protect sensitive app logic or user data, verifying the host Android device’s security configuration is a critical layer of defense. Below are actionable implementations for monitoring three high-risk device states.

Checking for Enabled Developer Options

Modern Android stores developer options toggle state in Settings.Global (deprecated usage in Settings.Secure for newer API levels). The following implementation graceful handles API differences, returning a boolean flagging enabled status:

import android.content.Context
import android.provider.Settings

fun checkDevOptionsActive(ctx: Context): Boolean {
    val resolver = ctx.contentResolver
    val key = Settings.Global.DEVELOPMENT_SETTINGS_ENABLED
    return try {
        Settings.Global.getInt(resolver, key) == 1
    } catch (e: Settings.SettingNotFoundException) {
        // If key is missing, default to false as disabled state
        false
    }
}

Verifying ADB Debugging Activation

ADB debugging grants full device access when connected to a trusted computer, so its status must be checked. This implementation also uses Settings.Global with error handling:

import android.content.Context
import android.provider.Settings

fun checkAdbDebuggingOn(ctx: Context): Boolean {
    val resolver = ctx.contentResolver
    val debugKey = Settings.Global.ADB_ENABLED
    return try {
        Settings.Global.getInt(resolver, debugKey) != 0
    } catch (ex: Settings.SettingNotFoundException) {
        // Fallback: assume disabled if setting is unavailable
        false
    }
}

Detecting Root Privileges

Root detection combines multiple checks to reduce false negatives, including su binary location scanning, system property validation, and test command execution. Here’s a multi-layered Kotlin implementation:

import java.io.File

fun checkDeviceRooted(): Boolean {
    // Step 1: Scan common su binary directories
    val suPaths = listOf(
        "/system/bin/su", "/system/xbin/su", "/sbin/su", "/system/sd/xbin/su",
        "/system/bin/failsafe/su", "/data/local/xbin/su", "/data/local/bin/su",
        "/data/local/su", "/system/sbin/su", "/usr/bin/su", "/vendor/bin/su"
    )
    val hasSuBinary = suPaths.any { File(it).exists() }
    if (hasSuBinary) return true

    // Step 2: Test execution of su command
    return try {
        Runtime.getRuntime().exec(arrayOf("su", "-c", "id")).waitFor() == 0
    } catch (t: Throwable) {
        false
    }
}

Tags: Android mobile security Root Detection ADB Debugging Developer Options

Posted on Wed, 17 Jun 2026 17:23:34 +0000 by merck_delmoro