Java-ADB-Library

Java library for working with Android smartphone via ADB

Stars
2

Java ADB Library

Description

This library provides a comprehensive set of features to manage Android devices using ADB (Android Debug Bridge). It facilitates tasks such as application and permission management, file system interactions, and device network information retrieval. Key features include:

  • Application Management: Install, uninstall, and retrieve detailed properties of applications (permissions, hashes).
  • Permission Management: Grant and revoke application permissions using ADB shell.
  • File System Operations: List directories, move, rename, push, and pull files on the Android device.
  • Network Information: Retrieve network interfaces and IP addresses.
  • Device Reboot Modes: Reboot into root, recovery, or bootloader mode.
  • Power Management: Manage power-saving modes like Doze and light Doze.
  • Device properties management: You can get any property of an Android device either by selecting the appropriate define or by the name of this property

This library is ideal for automating various Android device management tasks in development, testing, or security environments.

Usage

Installation

  1. Build the library with command
mvn install
  1. Add the following dependency to your project
<dependency>
	<groupId>ru.opensource.adb</groupId>
	<artifactId>ADBLibrary</artifactId>
	<version>1.1</version>
</dependency>
  1. Done! Now you can use the library in your project

Usage examples

ADBClient initialization and getting of decies list

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.exceptions.paths.ADBNotFoundException;
import ru.enplus.adblibrary.exceptions.paths.ADBIncorrectPathException;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient()) {
            // Retrieve connected devices
            System.out.println("Connected devices: " + adbClient.getConnectedDevices());
        } catch (ADBNotFoundException | ADBIncorrectPathException e) {
            e.printStackTrace();
        }
    }
}

Custom ADB Path Initialization

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.exceptions.paths.ADBIncorrectPathException;

public class Main {
    public static void main(String[] args) {
        String adbPath = "/path/to/adb";
        try (ADBClient adbClient = new ADBClient(adbPath)) {
            System.out.println("Connected devices: " + adbClient.getConnectedDevices());
        } catch (ADBIncorrectPathException e) {
            e.printStackTrace();
        }
    }
}

Connect to an External ADB Server

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.exceptions.base.ADBException;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient("127.0.0.1", "5037")) {
            System.out.println("Connected devices: " + adbClient.getConnectedDevices());
        } catch (ADBException e) {
            e.printStackTrace();
        }
    }
}

Execute Custom ADB Commands

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.exceptions.base.ADBException;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient()) {
            List<String> output = adbClient.executeCommand("adb shell getprop ro.product.model");
            output.forEach(System.out::println);
        } catch (ADBException e) {
            e.printStackTrace();
        }
    }
}

Handling Shell Execution with Custom Handler

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.exceptions.base.ADBException;
import ru.enplus.adblibrary.connection.ADBClient.CommandResultHandler;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient()) {
            String deviceId = adbClient.getConnectedDevices().get(0);
            String command = adbClient.getCommandBase(deviceId) + "ls /sdcard";
            
            List<String> files = adbClient.executeCommandWithHandling(command, new CommandResultHandler<List<String>>() {
                @Override
                public List<String> handle(List<String> result) {
                    // Custom handling of result
                    return result;
                }
            });
            files.forEach(System.out::println);
        } catch (ADBException e) {
            e.printStackTrace();
        }
    }
}

Device information class initialization.

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.domain.device.AndroidDeviceInfo;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient()) {
            String deviceId = adbClient.getConnectedDevices().get(0);
            AndroidDeviceInfo deviceInfo = new AndroidDeviceInfo(deviceId, adbClient);
            
            System.out.println("Device Brand: " + deviceInfo.getBrand());
            System.out.println("Device Model: " + deviceInfo.getModel());
            System.out.println("Android Version: " + deviceInfo.getAndroidVersion());
            System.out.println("Android SDK Version: " + deviceInfo.getAndroidSDKVersion());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Retreive property by it's name

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.domain.device.AndroidDeviceInfo;
import ru.enplus.adblibrary.domain.properties.AndroidDeviceProperties;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient()) {
            String deviceId = adbClient.getConnectedDevices().get(0);
            AndroidDeviceInfo deviceInfo = new AndroidDeviceInfo(deviceId, adbClient);
            System.out.println(deviceInfo.getRawPropertyValue("gsm.sim.state"));
            //OR
            System.out.println(deviceInfo.getRawPropertyValue(AndroidDeviceProperties.ANDROID_SIM_STATE));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Work with AndroidDevice. Initialization (it inherits AndroidDeviceInfo, so all the methods from this class you can also invoke here)

import ru.enplus.adblibrary.connection.ADBClient;
import ru.enplus.adblibrary.domain.device.AndroidDevice;

public class Main {
    public static void main(String[] args) {
        try (ADBClient adbClient = new ADBClient()) {
            String deviceId = adbClient.getConnectedDevices().get(0);
            boolean collectApplicationProperties = true;
            AndroidDevice device = new AndroidDevice(deviceId, adbClient, collectApplicationProperties);
            System.out.println("Device Model: " + device.getModel());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Install an App: Install an application from an APK file.

boolean success = device.installAppFromApk("/path/to/app.apk");

Uninstall an App: Uninstall an application using its package name.

device.uninstallApp("com.example.app");

List Applications: Retrieve a list of applications installed on the device.

List<AndroidApplication> apps = device.getApplications();

You can grant or revoke permissions for applications on the device.

device.grantPermissionShellOnly("com.example.app", "android.permission.CAMERA");
device.revokePermissionShellOnly("com.example.app", "android.permission.CAMERA");

List Network Interfaces:

List<String> interfaces = device.getNetworkInterfaces();

Get IP Address of a Network Interface:

String ipAddress = device.getInterfaceIpAddress("wlan0", "ipv4");

List Directory Contents:

List<String> dirContents = device.listDir("/sdcard/");

Pull a File:

device.pullFromDevice("/sdcard/file.txt", "/local/file.txt");

Push a File:

device.pushToDevice("/local/file.txt", "/sdcard/file.txt");

Move and Rename Files:

device.renameFile("/sdcard/file.txt", "newfile.txt");
device.moveFile("/sdcard/file.txt", "/sdcard/documents/newfile.txt");

Reboot to Root:

device.rebootRoot();

Enable Doze Mode:

device.enableDozeMode();

Reboot to Bootloader:

device.rebootBootloader();

For deeper inspection of installed applications, you can collect their permissions and hashes (it will be done automaticlu if your collectApplicationProperties in constructor is true)

device.collectApplicationProperties();

You can do same using the separate providers

Work with file system

AndroidFileSystemProvider fsProvider = new AndroidFileSystemProvider(adbClient, deviceId);
List<String> files = fsProvider.listDir(path);
fsProvider.pullFromDevice(devicePath, outputPath);
fsProvider.pushToDevice(localPath, devicePath);
fsProvider.renameFile(filePath, newFileName);
fsProvider.moveFile(filePath, newPath);

Work with Android device modes

AndroidModeProvider modeProvider = new AndroidModeProvider(adbClient, deviceId);
boolean isRebooted = modeProvider.rebootToRoot();
modeProvider.rebootToRecovery();
modeProvider.rebootToBootloader();
modeProvider.enableDozeMode();
modeProvider.enterLightDozeMode();
modeProvider.enterDeepDozeMode();
modeProvider.enableNormalMode();

Work with applications data

ApplicationDataProvider appDataProvider = new ApplicationDataProvider(adbClient, deviceId);
ArrayList<AndroidApplication> applications = appDataProvider.getApplicationsList(0); // 0 means no restriction for count of applications to collect

String applicationPath = applications.get(0).getPath(); 
Float versionNumeric = 8.0f; // Replace with the actual version number
try {
    String[] hashes = appDataProvider.getApplicationHashes(applicationPath, versionNumeric);
    System.out.println("SHA-1: " + hashes[0]);
    System.out.println("SHA-256: " + hashes[1]);
    System.out.println("SHA-512: " + hashes[2]);
} catch (IOException | NoSuchAlgorithmException | ADBException e) {
    e.printStackTrace();
}

AndroidApplication application = new AndroidApplication();
application.setPackageName("com.example.app"); // Replace with the actual package name

try {
    appDataProvider.fillApplicationPermissions(application);
    System.out.println("Dangerous Permissions: " + application.getDangerousPermissions());
    System.out.println("Install Permissions: " + application.getInstallPermissions());
    System.out.println("Runtime Permissions: " + application.getRuntimePermissions());
    System.out.println("Requested Permissions: " + application.getRequestedPermissions());
} catch (ADBException e) {
    e.printStackTrace();
}


try {
    appDataProvider.fillApplicationHashes(application, versionNumeric);
    System.out.println("SHA-1: " + application.getSha1());
    System.out.println("SHA-256: " + application.getSha256());
    System.out.println("SHA-512: " + application.getSha512());
} catch (IOException | NoSuchAlgorithmException | ADBException e) {
    e.printStackTrace();
}

Applications Management via ApplicationManagementProvider

ApplicationManagementProvider appManagementProvider = new ApplicationManagementProvider(adbClient, deviceId);
appManagementProvider.uninstallApp(packageName);
boolean success = appManagementProvider.installAppFromApk(apkPath);

Work with applications permissions via ApplicationPermissionManagementProvider

ApplicationPermissionManagementProvider permissionManagementProvider = new ApplicationPermissionManagementProvider(adbClient, deviceId);
String packageName = "com.example.app"; // Replace with the actual package name
String permission = "android.permission.CAMERA";
permissionManagementProvider.grantPermissionShellOnly(packageName, permission);

//OR
AndroidApplication app = new AndroidApplication(....);
permissionManagementProvider.grantPermissionShellOnly(app, permission);

permissionManagementProvider.revokePermissionShellOnly(packageName, permission);
permissionManagementProvider.revokePermissionShellOnly(app, permission);

Work with Network via NetworkDataProvider

NetworkDataProvider networkDataProvider = new NetworkDataProvider(adbClient, deviceId);
ArrayList<String> networkInterfaces = networkDataProvider.getNetworkInterfaces();
String ipv4Address = networkDataProvider.getInterfaceIpAddress("wlan0", "ipv4");
String ipv6Address = networkDataProvider.getInterfaceIpAddress("wlan0", "ipv6");