Android:如何以编程方式访问 AVD 管理器中显示的设备序列号(API 版本 8)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11029294/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:48:08  来源:igfitidea点击:

Android: How to programmatically access the device serial number shown in the AVD manager (API Version 8)

androidserial-number

提问by Heshan Perera

How do I programmatically access the value shown in the image below ?

如何以编程方式访问下图中显示的值?

enter image description here

在此处输入图片说明

回答by thaussma

This is the hardware serial number. To access it on

这是硬件序列号。要访问它

  • Android Q(>= SDK 29) android.Manifest.permission.READ_PRIVILEGED_PHONE_STATEis required. Only system apps can require this permission. If the calling package is the device or profile owner then the READ_PHONE_STATEpermission suffices.

  • Android 8 and later(>= SDK 26) use android.os.Build.getSerial()which requires the dangerous permission READ_PHONE_STATE. Using android.os.Build.SERIALreturns android.os.Build.UNKNOWN.

  • Android 7.1 and earlier(<= SDK 25) and earlier android.os.Build.SERIALdoes return a valid serial.

  • 需要 Android Q(>= SDK 29) android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE。只有系统应用可以需要此权限。如果调用包是设备或配置文件所有者,则READ_PHONE_STATE权限就足够了。

  • Android 8 及更高版本(> = SDK 26)使用android.os.Build.getSerial()需要危险权限READ_PHONE_STATE。使用android.os.Build.SERIAL返回android.os.Build.UNKNOWN

  • Android 7.1 及更早版本(<= SDK 25) 及更早版本android.os.Build.SERIAL确实会返回有效序列号。

It's unique for any device. If you are looking for possibilities on how to get/use a unique device id you should read here.

它对任何设备都是独一无二的。如果您正在寻找有关如何获取/使用唯一设备 ID 的可能性,您应该在这里阅读。

For a solution involving reflection without requiring a permission see this answer.

有关无需许可而涉及反射的解决方案,请参阅此答案

回答by Patrick Favre

Up to Android 7.1 (SDK 25)

最高 Android 7.1 (SDK 25)

Until Android 7.1 you will get it with:

在 Android 7.1 之前,您将获得它:

Build.SERIAL

From Android 8 (SDK 26)

从 Android 8 (SDK 26)

On Android 8 (SDK 26) and above, this field will return UNKNOWNand must be accessed with:

在 Android 8 (SDK 26) 及更高版本上,此字段将返回UNKNOWN并且必须通过以下方式访问:

Build.getSerial()

which requires the dangerous permissionandroid.permission.READ_PHONE_STATE.

这需要危险的许可android.permission.READ_PHONE_STATE

From Android Q (SDK 29)

来自 Android Q (SDK 29)

Since Android Q using Build.getSerial()gets a bit more complicated by requiring:

由于 Android Q 使用Build.getSerial()变得有点复杂,要求:

android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE(which can only be acquired by system apps), orfor the calling package to be the device or profile ownerand have the READ_PHONE_STATEpermission. This means most apps won't be able to uses this feature. See the Android Q announcementfrom Google.

android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE(只能由系统应用获取),或者调用包为设备或配置文件所有者并具有READ_PHONE_STATE权限。这意味着大多数应用程序将无法使用此功能。请参阅Google的Android Q 公告

See Android SDK reference

请参阅Android SDK 参考



Best Practice for Unique Device Identifier

唯一设备标识符的最佳实践

If you just require a unique identifier, it's best to avoid using hardware identifiers as Google continuously tries to make it harder to access them for privacy reasons. You could just generate a UUID.randomUUID().toString();and save it the first time it needs to be accessed in e.g. shared preferences. Alternatively you could use ANDROID_IDwhich is a 8 byte long hex string unique to the device, user and (only Android 8+) app installation. For more info on that topic, see Best practices for unique identifiers.

如果您只需要唯一标识符,最好避免使用硬件标识符,因为出于隐私原因,Google 会不断尝试使其更难访问。您可以UUID.randomUUID().toString();在第一次需要在例如共享首选项中访问它时生成并保存它。或者,您可以使用ANDROID_ID它是设备、用户和(仅限 Android 8+)应用程序安装所独有的 8 字节长十六进制字符串。有关该主题的更多信息,请参阅唯一标识符的最佳实践

回答by flawyte

Build.SERIALcan be emptyor sometimes return a different value (proof 1, proof 2) than what you can see in your device's settings.

Build.SERIAL可以为空或有时返回与您在设备设置中看到的值不同的值(proof 1proof 2)。

If you want a more complete and robust solution, I've compiled every possible solution I could found in a single gist. Here's a simplified version of it :

如果您想要一个更完整和更强大的解决方案,我已经在一个gist 中编译了我能找到的所有可能的解决方案。这是它的简化版本:

public static String getSerialNumber() {
    String serialNumber;

    try {
        Class<?> c = Class.forName("android.os.SystemProperties");
        Method get = c.getMethod("get", String.class);

        serialNumber = (String) get.invoke(c, "gsm.sn1");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ril.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ro.serialno");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "sys.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = Build.SERIAL;

        // If none of the methods above worked
        if (serialNumber.equals(""))
            serialNumber = null;
    } catch (Exception e) {
        e.printStackTrace();
        serialNumber = null;
    }

    return serialNumber;
}

I try to update the gist regularly whenever I can test on a new device or Android version. Contributions are welcome too.

每当我可以在新设备或 Android 版本上进行测试时,我都会尝试定期更新要点。也欢迎投稿。