使用 NPM/Node 检查 Android Phone 上的 USB 调试

Use NPM/Node for checking USB Debugging on Android Phone

我正在尝试通过 NPM/Node 检查 USB 调试是否打开或关闭。一旦 android phone 连接到我的系统并关闭 USB 调试,我就需要向用户显示提示以在他的 phone 上启用 USB 调试。

根据我的研究,连接到我系统的每个设备 (Scanner/Phones/USB) 都有一个 唯一的 GUID,这有助于我区分连接的是哪个设备。此外,我无法获取 USB 调试详细信息。 请帮忙!

到目前为止我写的代码是基于 iSerialNumber 但我想根据 BUS-TYPE GUID 来区分它。

var usb = require('usb');
usb.on('attach', function(device) {
var devices = usb.getDeviceList();
var check = devices[0].deviceDescriptor;
if(check.iSerialNumber == '3')
{
    console.log("Please enable USB Debugging");
}
else
{
    console.log("Connect an Android device");
}

});

I'm facing these issues.

if(check.iSerialNumber == '3')

iSerialNumber 不是实际的序列号,它只是存储在设备中的序列号字符串描述符的索引。您可以在此 link. GUID is not used by USB devices but may be used by OS itself as mentioned here. Serial Numbers are unique across every non-telephony Android devices as mentioned here 上查看有关 USB 设备描述符的更多详细信息,因此不建议使用序列号将设备标记为 Android。我发现最好的方法是检查设备供应商 ID 和产品 ID,它们分别存储在设备描述符中,如 idVendoridProduct。我找到了供应商 ID 列表,但没有找到每个供应商的任何产品 ID 列表。

Android 设备公开了多个用于不同目的的接口,如 MTP、PTP、大容量存储和 USB 调试等。我们想找出具有 接口的 USB 调试接口的状态 Class 255 子接口 Class 66 接口协议 1。我找到了这些数字 here

程序首先测试新连接的设备是否为 Android,如果为 Android,则检查 USB 调试。我不是普通 node.js 用户,所以我的代码不好。

main.js

var usb = require('usb');
usb.on('attach', function(device) {
    getDeviceInformation(device, function onInfromation(error, information)
    {
        if (error)
        {
            console.log("Unable to get Device information");
            return;
        }

        if (isAndroidDevice(information))
        {
            if (!isDebuggingEnabled(device))
            {
                console.log("Please enable USB Debugging from Developer Options in Phone Settings");
                return;
            }

            //Do your thing here
            console.log("Device connected with Debugging enabled");
            console.log("Device Information");
            console.log(information);
            console.log();
        }
    });
});

function getDeviceInformation(device, callback)
{
    var deviceDescriptor = device.deviceDescriptor;
    var productStringIndex = deviceDescriptor.iProduct;
    var manufacturerStringIndex = deviceDescriptor.iManufacturer;
    var serialNumberIndex = deviceDescriptor.iSerialNumber;

    var callbacks = 3;
    var resultError = false;
    var productString = null;
    var manufacturerString = null;
    var serialNumberString = null;

    device.open();
    device.getStringDescriptor(productStringIndex, function callback(error, data)
    {
        if (error)resultError = true;
        else productString = data;

        if (--callbacks == 0)onFinish();
    });

    device.getStringDescriptor(manufacturerStringIndex, function callback(error, data)
    {
        if (error)resultError = true;
        else manufacturerString = data;

        if (--callbacks == 0)onFinish();
    });

    device.getStringDescriptor(serialNumberIndex, function callback(error, data)
    {
        if (error)resultError = true;
        else serialNumberString = data;

        if (--callbacks == 0)onFinish();
    });

    function onFinish()
    {
        device.close();

        var result = null;
        if (!resultError)
        {
            result = {
                idVendor: deviceDescriptor.idVendor,
                idProduct: deviceDescriptor.idProduct,
                Product: productString,
                Manufacturer: manufacturerString,
                Serial: serialNumberString
            };
        }

        callback(resultError, result);
    }
}

/**
 *Currently this procedure only check vendor id
 *from limited set of available vendor ids
 *for complete functionality it should also
 *check for Product Id, Product Name or Serial Number
 */
function isAndroidDevice(information)
{
    var vendorId = information.idVendor;
    var index = require('./usb_vendor_ids').builtInVendorIds.indexOf(vendorId);
    return index == -1? false : true;
}

/**
 *Currently this procedure only check the
 *interfaces of default activated configuration 
 *for complete functionality it should check 
 *all interfaces available on each configuration 
 */
function isDebuggingEnabled(device)
{
    const ADB_CLASS = 255;
    const ADB_SUBCLASS = 66;
    const ADB_PROTOCOL = 1;

    /*opened device is necessary to set new configuration and 
     *to get available interfaces on that configuration
     */
    device.open();

    var result = false;
    const interfaces = device.interfaces;
    for (var i = 0, len = interfaces.length; i < len; ++i)
    {
        const bClass = interfaces[i].descriptor.bInterfaceClass;
        const bSubClass = interfaces[i].descriptor.bInterfaceSubClass;
        const bProtocol = interfaces[i].descriptor.bInterfaceProtocol;
        if (bClass == ADB_CLASS && bSubClass == ADB_SUBCLASS && bProtocol == ADB_PROTOCOL)
        {
            result = true;
            break;
        }
    }

    device.close();
    return result;
}

usb_vendor_ids.js

//copied from https://github.com/karfield/adb/blob/master/src/usb_vendor_ids.c
module.exports.builtInVendorIds = [
    0x18d1, /* Google */
    0x0bb4, /* HTC */
    0x04e8, /* Samsung */
    0x22b8, /* Motorola */
    0x1004, /* LG */
    0x12D1, /* Huawei */
    0x0502, /* Acer */
    0x0FCE, /* Sony Ericsson */
    0x0489, /* Foxconn */
    0x413c, /* Dell */
    0x0955, /* Nvidia */
    0x091E, /* Garmin-Asus */
    0x04dd, /* Sharp */
    0x19D2, /* ZTE */
    0x0482, /* Kyocera */
    0x10A9, /* Pantech */
    0x05c6, /* Qualcomm */
    0x2257, /* On-The-Go-Video */
    0x0409, /* NEC */
    0x04DA, /* Panasonic Mobile Communication */
    0x0930, /* Toshiba */
    0x1F53, /* SK Telesys */
    0x2116, /* KT Tech */
    0x0b05, /* Asus */
    0x0471, /* Philips */
    0x0451, /* Texas Instruments */
    0x0F1C, /* Funai */
    0x0414, /* Gigabyte */
    0x2420, /* IRiver */
    0x1219, /* Compal */
    0x1BBB, /* T & A Mobile Phones */
    0x2006, /* LenovoMobile */
    0x17EF, /* Lenovo */
    0xE040, /* Vizio */
    0x24E3, /* K-Touch */
    0x1D4D, /* Pegatron */
    0x0E79, /* Archos */
    0x1662, /* Positivo */
    0x15eb, /* VIA-Telecom */
    0x04c5, /* Fujitsu */
    0x091e, /* GarminAsus */
    0x109b, /* Hisense */
    0x24e3, /* KTouch */
    0x17ef, /* Lenovo */
    0x2080, /* Nook */
    0x10a9, /* Pantech */
    0x1d4d, /* Pegatron */
    0x04da, /* PMCSierra */
    0x1f53, /* SKTelesys */
    0x054c, /* Sony */
    0x0fce, /* SonyEricsson */
    0x2340, /* Teleepoch */
    0x19d2, /* ZTE */
    0x201e, /* Haier */
    /* TODO: APPEND YOUR ID HERE! */
];

试试这个代码,但它只适用于三星设备:-

var usbDetect = require('usb-detection');
var Promise = require('bluebird');
var adb = require('adbkit');
var client = adb.createClient();

usbDetect.on('add', function(dev) {
    setTimeout(checkAndyDevice, 1500);
 }); 

var checkAndyDevice = function(){
 client.listDevices()
      .then(function(devices) {
        return Promise.map(devices, function() {
          return devices;
        })
      })
      .then(function(id) {
        if((JSON.stringify(id)) == '[]')
        {
            console.log("Please enable Usb Debugging option from your Android device");
        }
      })
      .catch(function(err) {
        console.error('Something went wrong:', err.stack)
      });
 };