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
Android: How to programmatically access the device serial number shown in the AVD manager (API Version 8)
提问by Heshan Perera
How do I programmatically access the value shown in the image below ?
如何以编程方式访问下图中显示的值?
回答by thaussma
This is the hardware serial number. To access it on
这是硬件序列号。要访问它
Android Q(>= SDK 29)
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
is required. Only system apps can require this permission. If the calling package is the device or profile owner then theREAD_PHONE_STATE
permission suffices.Android 8 and later(>= SDK 26) use
android.os.Build.getSerial()
which requires the dangerous permission READ_PHONE_STATE. Usingandroid.os.Build.SERIAL
returns android.os.Build.UNKNOWN.Android 7.1 and earlier(<= SDK 25) and earlier
android.os.Build.SERIAL
does 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 UNKNOWN
and 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_STATE
permission. 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 公告。
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_ID
which 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.SERIAL
can be emptyor sometimes return a different value (proof 1, proof 2) than what you can see in your device's settings.
Build.SERIAL
可以为空或有时返回与您在设备设置中看到的值不同的值(proof 1,proof 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 版本上进行测试时,我都会尝试定期更新要点。也欢迎投稿。