Skip to main content

Overview

APK Extractor automatically detects Android devices connected via USB or WiFi, extracting detailed device information including brand, model, and Android version. The system monitors devices in real-time and supports mDNS auto-connection for wireless debugging.

Detection Methods

USB Device Detection

When you connect an Android device via USB with debugging enabled, APK Extractor instantly detects it using ADB’s device listing:
const out = await runAdb('devices');
const lines = out.split('\n').slice(1);
for (const line of lines) {
  const tabIdx = line.indexOf('\t');
  if (tabIdx === -1) continue;
  const serial = line.substring(0, tabIdx).trim();
  const status = line.substring(tabIdx).trim();
  if (status === 'device' && serial) {
    // Device detected
  }
}
USB devices appear with a serial number identifier (e.g., R58N123456A).

WiFi Device Detection

Devices connected wirelessly appear with their IP address and port:
const isWireless = serial.includes(':') || serial.includes('._adb');
Wireless devices have two formats:
  • Manual connection: 192.168.1.100:5555
  • mDNS auto-connection: adb-R58N123456A._adb-tls-connect._tcp
Android 11+ supports wireless debugging with automatic mDNS broadcasting. APK Extractor detects these devices automatically without manual pairing.

mDNS Support

For devices using wireless debugging with mDNS (Android 11+), APK Extractor:
  1. Detects the mDNS service name format: adb-*._adb-tls-connect._tcp
  2. Resolves the device’s IP address using ADB shell commands
  3. Extracts device information (brand/model)
  4. Auto-saves the device for quick reconnection
if (serial.includes('._adb')) {
  try {
    const ipOut = await runAdb('shell ip route', serial, 5000);
    const srcMatch = ipOut.match(/src\s+([\d.]+)/);
    if (srcMatch) ip = srcMatch[1];
  } catch { }
}

Real-Time Monitoring

The web interface polls for device changes every 4 seconds using an optimized lightweight endpoint:
app.get('/api/devices/poll', async (req, res) => {
  const out = await runAdb('devices', null, 5000);
  const lines = out.split('\n').slice(1);
  const serials = [];
  for (const line of lines) {
    const tabIdx = line.indexOf('\t');
    if (tabIdx === -1) continue;
    const serial = line.substring(0, tabIdx).trim();
    const status = line.substring(tabIdx).trim();
    if (status === 'device' && serial) serials.push(serial);
  }
  res.json({ serials });
});
The polling endpoint only returns serial numbers for performance. Full device info loads when you select a device.

Device Information Extraction

APK Extractor extracts comprehensive device details using ADB’s getprop command:
const props = await runAdb(
  `shell "getprop ro.product.manufacturer && getprop ro.product.model"`,
  serial, 5000
);
const lines = props.trim().split('\n').map(l => l.trim());
const brand = lines[0] || '';
const model = lines[1] || '';
if (brand && model && brand !== 'N/A') label = `${brand} ${model}`;

Properties Collected

PropertyADB CommandExample Value
Brandgetprop ro.product.manufacturerSamsung
Modelgetprop ro.product.modelGalaxy S21
Android Versiongetprop ro.build.version.release13
SDK Levelgetprop ro.build.version.sdk33
Device Codenamegetprop ro.product.deviceSM-G991B

Parallel Processing

All connected devices are processed in parallel for maximum performance:
const devices = await Promise.all(pending.map(async (serial) => {
  const isWireless = serial.includes(':') || serial.includes('._adb');
  let label = serial;
  let ip = null;

  try {
    const props = await runAdb(
      `shell "getprop ro.product.manufacturer && getprop ro.product.model"`,
      serial, 5000
    );
    const lines = props.trim().split('\n').map(l => l.trim());
    const brand = lines[0] || '';
    const model = lines[1] || '';
    if (brand && model && brand !== 'N/A') label = `${brand} ${model}`;
  } catch { }

  return { serial, status: 'device', label, ip, wireless: isWireless };
}));
Detecting 10 devices takes the same time as detecting 1 device thanks to parallel ADB calls.

How It Works

  1. Poll Detection (every 4s)
    • Execute adb devices command
    • Parse output for device serials
    • Compare with previous state
    • Notify UI of changes
  2. Device Selection
    • User clicks on a device
    • Fetch detailed info using getprop commands
    • Extract brand, model, Android version
    • Display in device panel
  3. Wireless IP Resolution
    • For WiFi devices, parse serial for IP
    • For mDNS devices, run shell ip route
    • Extract source IP from route table
    • Auto-update saved devices database
  4. Auto-Save WiFi Devices
    • Detect wireless connection
    • Extract device label
    • Save to devices.json
    • Enable one-click reconnection

Device Display

Devices appear in the interface with:
  • Brand and Model (e.g., “Samsung Galaxy S21”)
  • Serial Number (for USB) or IP Address (for WiFi)
  • Connection Type indicator (USB/WiFi icon)
  • Custom Name (if assigned)
The detection system automatically prioritizes custom names over auto-detected labels, ensuring your personalized device names always appear first.

Performance Optimization

Caching Strategy

  • Device list cached in memory
  • Polling only fetches serial numbers
  • Full device info loaded on demand
  • 5-second timeout for responsiveness

Error Handling

try {
  const props = await runAdb(
    `shell "getprop ro.product.manufacturer && getprop ro.product.model"`,
    serial, 5000
  );
  // Process properties
} catch {
  // Fallback to serial number
  label = serial;
}
If device info extraction fails, APK Extractor gracefully falls back to displaying the serial number.

Build docs developers (and LLMs) love