如何获取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 = ...
随机推荐
- Entity Framework Tutorial Basics(22):Disconnected Entities
Disconnected Entities: Before we see how to perform CRUD operation on disconnected entity graph, let ...
- xml元素类型PCDATA和CDATA的区别(DTD中)
PCDATAPCDATA 的意思是被解析的字符数据(parsed character data).可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本.PCDATA 是会被解析器解析的文 ...
- 数据结构_Search
问题描述 可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索自己的手机.现在我们假设 Bibi 的家位于一棵二叉树的根部.在 Bibi 的心中,每个节点都有一个权值 x,代表他心 ...
- ServletContext接口(六)
javax.servlet.ServletContext接口 ServletContext(上下文)是公用的,就是.net中的application,主要用到的就是全局set设置值,get获取值,ja ...
- 「美团 CodeM 初赛 Round A」最长树链
题目描述 Mr. Walker 最近在研究树,尤其是最长树链问题.现在树中的每个点都有一个值,他想在树中找出最长的链,使得这条链上对应点的值的最大公约数不等于1.请求出这条最长的树链的长度. 输入格式 ...
- javaweb访问hdfs的一些错误
javaweb 与 HDFS 坑 前提:javaweb 项目,hdfs中的数据文件,导入访问hdfs的jar包,eclipse调试 问题:在×××.java代码中正常访问hdfs,浏览jsp时调用×× ...
- JavaScript高级知识点整理
一.JS中的数组 1.数组的三种定义方式 (1).实例化对象 var aArray=new Array(1,2,3,4,5); (2).快捷创建 var aTwoArray = [1,2,3,&quo ...
- oracle select非group by的字段
可以把group by的结果集当作一个表,然后从这里表里取数就可以了. e.g. SELECT A.PROJECT_CODE,A.DIE_NO,E.ONE_CONSUMING FROM (SELECT ...
- 内核启动后,lcd显示logo失败
针对-s5pv210,但对其他平台也使用 lcd显示logo失败,若显示成功默认的logo是一只企鹅,但是串口打印“Start display and show logo”,但是LCD屏没有显示 ...
- 关于AppiumDriver
java client2.0之后把AppiumDriver作为抽象类,IOSDriver和AndroidDriver继承AppiumDriver.安卓端就用AndroidDriver.2.0之前And ...