如何获取Android手机的唯一标识
有很多场景和需求你需要用到手机设备的唯一标识符。
在Android中,有以下几种方法获取这样的ID。
1. The IMEI: 仅仅只对Android手机有效:
1 |
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); |
采用此种方法,需要在AndroidManifest.xml中加入一个许可:android.permission.READ_PHONE_STATE,并且用户应当允许安装此应用。作为手机来讲,IMEI是唯一的,它应该类似于 359881030314356(除非你有一个没有量产的手机(水货)它可能有无效的IMEI,如:0000000000000)。
2. Pseudo-Unique ID, 这个在任何Android手机中都有效
有一些特殊的情况,一些如平板电脑的设置没有通话功能,或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的(因为如果两个手机应用了同样的硬件以及Rom 镜像)。但应当明白的是,出现类似情况的可能性基本可以忽略。要实现这一点,你可以使用Build类:
1 |
String m_szDevIDShort = "35" + //we make this look like a valid IMEI Build.BOARD.length()%10 + |
大多数的Build成员都是字符串形式的,我们只取他们的长度信息。我们取到13个数字,并在前面加上“35”。这样这个ID看起来就和15位IMEI一样了。
3. The Android ID
通常被认为不可信,因为它有时为null。开发文档中说明了:这个ID会改变如果进行了出厂设置。并且,如果某个Andorid手机被Root过的话,这个ID也可以被任意改变。
1 |
String m_szAndroidID = Secure.getString(getContentResolver(), Secure.ANDROID_ID); |
Returns: 9774d56d682e549c . 无需任何许可。
4. The WLAN MAC Address string
是另一个唯一ID。但是你需要为你的工程加入android.permission.ACCESS_WIFI_STATE 权限,否则这个地址会为null。
1 |
WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); |
Returns: 00:11:22:33:44:55 (这不是一个真实的地址。而且这个地址能轻易地被伪造。).WLan不必打开,就可读取些值。
5. The BT MAC Address string
只在有蓝牙的设备上运行。并且要加入android.permission.BLUETOOTH 权限.
1 |
BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter |
Returns: 43:25:78:50:93:38 . 蓝牙没有必要打开,也能读取。
Combined Device ID
综上所述,我们一共有五种方式取得设备的唯一标识。它们中的一些可能会返回null,或者由于硬件缺失、权限问题等获取失败。
但你总能获得至少一个能用。所以,最好的方法就是通过拼接,或者拼接后的计算出的MD5值来产生一个结果。
1 |
String m_szLongID = m_szImei + m_szDevIDShort |
通过以上算法,可产生32位的16进制数据:
9DDDF85AFF0A87974CE4541BD94D5F55
现在你就可以对其进行你的应用了。
//---------------------------------------------------------------------
android下获取设备唯一标识原本非常简单(至少不会像iOS一样禁用这个,禁用那个),但是由于设备的多样性需要考虑的东西也对应复杂起来。
先附上完整代码
java代码
- protected static final String PREFS_FILE =
- "gank_device_id.xml";
- protected static final String PREFS_DEVICE_ID = "gank_device_id";
- protected static String uuid;
- static public String getUDID()
- {
- if( uuid ==null ) {
- synchronized (GankMainActivity.class) {
- if( uuid == null) {
- final SharedPreferences prefs = s_instance.getSharedPreferences(
- PREFS_FILE, 0);
- final String id = prefs.getString(PREFS_DEVICE_ID, null );
- if (id != null) {
- // Use the ids previously computed and stored in the prefs file
- uuid = id;
- } else {
- final String androidId = Secure.getString(s_instance.getContentResolver(),
- Secure.ANDROID_ID);
- // Use the Android ID unless it's broken, in which case fallback on
- deviceId,
- // unless it's not available, then fallback on a random number which we
- store
- // to a prefs file
- try {
- if (!"9774d56d682e549c".equals(androidId)) {
- uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8")).toString();
- } else {
- final String deviceId = ((TelephonyManager) s_instance.getSystemService(
- Context.TELEPHONY_SERVICE )).getDeviceId();
- uuid = deviceId!=null ?
- UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")).toString() :
- UUID.randomUUID().toString();
- }
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- // Write the value out to the prefs file
- prefs.edit().putString(PREFS_DEVICE_ID, uuid).commit();
- }
- }
- }
- }
- return uuid;
- }
复制代码
1、正常情况下可以通过((TelephonyManager) s_instance.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId(); 来获取,但是某些平板电脑此函数会返回空
2、通过 Secure.getString(s_instance.getContentResolver(), Secure.ANDROID_ID); 也可以获取到一个id,但是android2.2或者是某些山寨手机使用这个也是有问题的,它会返回一个固定的值 9774d56d682e549c
3、如果前两个都没有获取到udid,那么就在程序启动的时候创建一个随机的uuid,然后保存起来。这个算是兼容方案,当然这样的设备并不会很多。
原文链接:http://www.eyeandroid.com/thread-15908-1-1.html
如何获取Android手机的唯一标识的更多相关文章
- Android开发 - 获取Android设备的唯一标识码(Android 6.0或更高)
在我们的APP开发中,通常需要获取到设备的唯一标识.在Android6.0之前,有很多方法我们可以方便获取到硬件的唯一标识,但是在Android6.0之后,Android系统大幅限制了我们获取设备的硬 ...
- 获取Android 手机屏幕宽度和高度以及获取Android手机序列号
1.获取Android 手机屏幕宽度 1 DisplayMetrics dm = new DisplayMetrics(); 2 this.getWindowManager().getDefaultD ...
- 关于Android的Build类——获取Android手机设备各种信息
经常遇到要获取Android手机设备的相关信息,来进行业务的开发,比如经常会遇到要获取CPU的类型来进行so库的动态的下载.而这些都是在Android的Build类里面.相关信息如下: private ...
- 获取Android设备的唯一识别码|设备号|序号|UUID
如何获取一个能唯一标识每台Android设备的序号? 这个问题有很多答案,但是他们中的大部分只在某些情况下有效. 根据测试: 所有的设备都可以返回一个 TelephonyManager.getDevi ...
- Pyqt adb 获取Android手机屏幕
adb的全称为Android Debug Bridge,就是起到调试桥的作用.adb的工作方式比较特殊,采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情况下adb会da ...
- 获取android手机基本信息
/** * 获取android当前可用内存大小 */ private String getAvailMemory() {// 获取android当前可用内存大小 ActivityManager am ...
- Logback获取SkyWalking的全局唯一标识 trace-id 记录到日志中
为什么要获取trace-id 通过上文Docker-Compose搭建单体SkyWalking我们搭建了SkyWalking服务,我们需要在日志中记录下来每次请求的唯一标识(trace-id),这样就 ...
- (转)获取android手机内部存储空间和外部存储空间的参数 && 如何决定一个apk的安装位置
转:http://blog.csdn.net/zhandoushi1982/article/details/8560233 获取android文件系统的信息,需要Environment类和StatFs ...
- adb 获取Android手机信息命令(2)
#Android命令 #获取手机名称 GET_PHONE_NAME = 'adb shell getprop ro.product.model' #获取手机版本 GET_PHONE_VERSION = ...
随机推荐
- NPOI操作之一EXCEL数据导入数据库
一.概要 前面讲到NPOI操作EXCEL导出功能,下面讲下从EXCEL里获取数据添加进数据库. 二.代码 HSSFWorkbook hssfworkbook; public void ExcelDat ...
- 神奇的overflow:hidden及其背后的原理
先来看两个overflow:hidden的使用例子 1.嵌套布局内部块元素设置float:left时,导致外部元素塌方,高度为0的问题. <div class="wrap"& ...
- Netty中的Future
先看下Future的整个继承体系,还有一个ChannelFuture不在里面: 在并发编程中,我们通常会用到一组非阻塞的模型:Promise,Future 和 Callback.其中的 Fut ...
- 关于 windows mobile 进程操作的方法
#region Process class /// <summary> /// Summary description for Process. /// </summary> ...
- STL 结构体 内部函数
typedef struct Node { int val; string name; bool operator < (const Node &right) const { retur ...
- Java50道经典习题-程序36 移动位置
题目:有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数 分析:比如有4个数n=4; 1 2 3 4 各个数向后移动2位m=2,变为 1 2 3 4 将最后m个数,即将最后2个数 ...
- 【zookeeper】
window下安装zookeeper三结点集群: 1:解压缩zookeeper压缩包:复制三分并且命名成:Server_A Server_B Server_C 2:拷贝conf目录下的文件zoo ...
- DotNet经典面试题(转载)
.Net基础常见 什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS.CLS.CLR分别作何解释? 答: 1应用程序域可以理解为一种轻量级进程.起到安全的作用 ...
- Repeater控件最后一笔记录高亮显示
Insus.NET以前有写过 <Repeater控件第前10笔记录高亮显示> 不过,现在有一个想法,就是最后一笔记录高亮显示,怎样实现? 技术要求,就是获取最后一笔的索引即可.可以从数据源 ...
- BZOJ 1974 [Sdoi2010] auction 代码拍卖会(数位dp)
题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...