java - Android 设备选择器中的序列号/名称

标签 java android eclipse development-environment adt

如果我在 Eclipse 中开发,我通常会按下绿色的 run 按钮。出现一个名为 Android Device Chooser 的弹出窗口,让我从已连接设备的列表中进行选择。一般来说,这没有问题,因为任何电话都会出现。我刚刚观察到 Serial Number 列显示了两个不同的内容:

通常它只显示序列号,但有时会显示设备名称,即 Asus Nexus 7。这是非常有用的,特别是如果你有不止一台设备要测试,而你不能(或不会)记住所有这些序列号(如果你有不止一台带有著名序列号 的设备,那就更令人困惑了0x0123456789ABCDEF).

我不知道 eclipse 为什么以及何时显示设备名称,但我想找到一种方法来强制 eclipse 收集这些设备名称而不是它们的序列号,并在设备选择器中显示它们.

最佳答案

查看源代码 com.android.ddmlib.Device 以了解 DDMS 如何生成设备名称/序列号:

private static final String DEVICE_MODEL_PROPERTY = "ro.product.model"; //$NON-NLS-1$
private static final String DEVICE_MANUFACTURER_PROPERTY = "ro.product.manufacturer"; //$NON-NLS-1$

... ...

private static final char SEPARATOR = '-';

... ...

@Override
public String getName() {
    if (mName == null) {
        mName = constructName();
    }

    return mName;
}

private String constructName() {
    if (isEmulator()) {
        String avdName = getAvdName();
        if (avdName != null) {
            return String.format("%s [%s]", avdName, getSerialNumber());
        } else {
            return getSerialNumber();
        }
    } else {
        String manufacturer = cleanupStringForDisplay(
                getProperty(DEVICE_MANUFACTURER_PROPERTY));
        String model = cleanupStringForDisplay(
                getProperty(DEVICE_MODEL_PROPERTY));

        StringBuilder sb = new StringBuilder(20);

        if (manufacturer != null) {
            sb.append(manufacturer);
            sb.append(SEPARATOR);
        }

        if (model != null) {
            sb.append(model);
            sb.append(SEPARATOR);
        }

        sb.append(getSerialNumber());
        return sb.toString();
    }
}

private String cleanupStringForDisplay(String s) {
    if (s == null) {
        return null;
    }

    StringBuilder sb = new StringBuilder(s.length());
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        if (Character.isLetterOrDigit(c)) {
            sb.append(Character.toLowerCase(c));
        } else {
            sb.append('_');
        }
    }

    return sb.toString();
}

如果您想查看 DDMS 如何呈现此设备名称/序列号,请参阅 com.android.ddmuilib.DevicePanel

ro.product.manufacturerro.product.model/system/build.prop,你可以使用adb -e shell getprop|grep "\[ro.product"来查看当前值:

[ro.product.manufacturer]: [samsung]
[ro.product.model]: [GT-I9100]

那么DDMS透视图中显示的设备名称/序列号是samsung-gt_i9100-0x0123456789ABCDEF。请注意,一些 kludge 供应商没有正确设置这两个属性,这就是为什么对于那些设备,它只显示序列号。

Eclipse 中没有配置可以让您简单地勾选并强制显示。如果您的设备已获得 root 权限,您可以编辑这些属性,以便设备的制造商和型号在 DDMS 透视图中正确显示,例如,使用 adb shell setprop <key> <value> 或直接编辑文件系统中的 build.prop。


深度 DDMS

DDMS获取设备信息的方式比较复杂,一般情况下,当AndroidDebugBridge启动并运行时,它会在一个单独的线程中启动一个DeviceMonitor,它会不断监听接收到的设备连接,并向特定的设备发出一个远程shell命令getprop device 查询 ro.product.manufacturerro.product.model 等设备信息,这个远程 shell 命令执行是不可靠的(可能受多种因素影响),并且不保证一直抓取属性。参见 com.android.ddmlib.DeviceMonitor:

/**
 * Queries a device for its build info.
 * @param device the device to query.
 */
private void queryNewDeviceForInfo(Device device) {
    // TODO: do this in a separate thread.
    try {
        // first get the list of properties.
        device.executeShellCommand(GetPropReceiver.GETPROP_COMMAND,
                new GetPropReceiver(device));

        queryNewDeviceForMountingPoint(device, IDevice.MNT_EXTERNAL_STORAGE);
        queryNewDeviceForMountingPoint(device, IDevice.MNT_DATA);
        queryNewDeviceForMountingPoint(device, IDevice.MNT_ROOT);

        // now get the emulator Virtual Device name (if applicable).
        if (device.isEmulator()) {
            EmulatorConsole console = EmulatorConsole.getConsole(device);
            if (console != null) {
                device.setAvdName(console.getAvdName());
            }
        }
    } catch (TimeoutException e) {
        Log.w("DeviceMonitor", String.format("Connection timeout getting info for device %s",
                device.getSerialNumber()));

    } catch (AdbCommandRejectedException e) {
        // This should never happen as we only do this once the device is online.
        Log.w("DeviceMonitor", String.format(
                "Adb rejected command to get  device %1$s info: %2$s",
                device.getSerialNumber(), e.getMessage()));

    } catch (ShellCommandUnresponsiveException e) {
        Log.w("DeviceMonitor", String.format(
                "Adb shell command took too long returning info for device %s",
                device.getSerialNumber()));

    } catch (IOException e) {
        Log.w("DeviceMonitor", String.format(
                "IO Error getting info for device %s",
                device.getSerialNumber()));
    }
}

注意 device.executeShellCommand() 抛出和处理的所有异常,如果发生任何异常,DDMS 将无法正确获取属性。

如果您想阅读完整的源代码,请查看 here

关于java - Android 设备选择器中的序列号/名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12669508/

相关文章:

python - Eclipse中打开各种main.py文件而不新建项目

java - Eclipse 不突出显示我的 JSP 文件

eclipse - 嵌入在 Web App 上的 Java openCV

java - Http 客户端 POST 上传文件 - MultipartException : Curren t request is not a multipart request

java - 自定义ListView的RelativeLayout中的Android布局居中

android - 如何以编程方式更改按钮的图标?

Android 和 SSL - 检查证书有效性

java - 如何在 Android 8 的主屏幕上创建快捷方式?

java - 将此 Objective-C 方法转换为 Android 的 Java 的正确方法是什么?

java - JMS处理期间apachemq异常