关于本文档

Android的开发者在一些特定情况下都需要知道手机中的唯一设备ID。例如,跟踪应用程序的安装,生成用于复制保护的DRM时需要使用设备的唯一ID。在本文档结尾处提供了作为参考的示例代码片段。

范围

本文提供有关如何读取各种Android设备的 ID的介绍,用以使用标识号。本文假定用户已经安装了Android以及开发应用程序必要的工具。并且,本文假定用户已了解Android的基本知识。

简介在搭载Android操作系统的设备中,已经存在好几种类型的设备标识号。先前的所有Android设备都具有电话功能,因此查找每部设备硬件唯一的IMEI,MEID,或ESN也很容易。但仅能使用Wifi的设备或音乐播放器没有电话硬件,所以没有这种类型的唯一标识号。本文阐述了如何读取不同Android设备的标识号。检索Android设备ID各种方式

以下是Android设备不同类型的识别设备ID。

· 唯一编号(IMEI,MEID,ESN,IMSI)

· MAC地址

· 序列号

· ANDROID_ID

唯一编号(IMEI,MEID,ESN,IMSI)

说明在以前,当Android设备均作为电话使用时,寻找唯一标识号比较简单:()可用于找到(取决于网络技术)手机硬件唯一的IMEI,MEID,ESN和IMSI编号。

TelephonyManager.getDeviceId

IMEI,MEID,ESN,IMSI的定义如下:

•IMEI(国际移动设备识别码)唯一编号,用于识别 GSM,WCDMA手机以及一些卫星电话(移动设备识别码)全球唯一编号,用于识别CDMA移动电台设备的物理硬件,MEID出现的目的是取代ESN号段(电子序列号)(电子序列号)唯一编号,用于识别CDMA手机(国际移动用户识别码)与所有GSM和UMTS网络手机用户相关联的唯一识别编号如需要检索设备的ID,在项目中要使用以下代码:

•MEID

•ESN

•IMSI

  1. import android.telephony.TelephonyManager;
  2. import android.content.Context;
  3. String imeistring = null;
  4. String imsistring = null;
  5. {
  6. TelephonyManager    telephonyManager;
  7. telephonyManager =
  8. (TelephonyManager) getSystemService( Context.TELEPHONY_SERVICE );
  9. /*
  10. * getDeviceId() function Returns the unique device ID.
  11. * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.
  12. */
  13. imeistring = telephonyManager.getDeviceId();
  14. /*
  15. * getSubscriberId() function Returns the unique subscriber ID,
  16. * for example, the IMSI for a GSM phone.
  17. */
  18. imsistring = telephonyManager.getSubscriberId();
  19. }

如要只读取手机的状态,则需添加READ_PHONE_STATE许可到AndroidManifest.xml文件中。

<uses-permission

android:name="android.permission.READ_PHONE_STATE" >

</uses-permission>

缺点

•Android设备要具有电话功能

•其工作不是很可靠

•序列号

•当其工作时,该值保留了设备的重置信息(“恢复出厂设置”),从而可以消除当客户删除自己设备上的信息,并把设备转另一个人时发生的错误。

Mac地址

(1) 调用android 的API: NetworkInterface. getHardwareAddress ()

该API的level为9,只有android 2.3以上才有该接口

(2) 调用java 的方法: nbtstat/arp

一般android不支持这两个命令

(3) 调用Android的API: WifiManager

权限:

1
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>

代码:

1
2
3
4
5
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
 
WifiInfo info = wifi.getConnectionInfo();
 
return info.getMacAddress();

这个是设备开通Wifi连接,获取到网卡的MAC地址

说明

可通过检索找到设备的Wi - Fi或蓝牙硬件的Mac地址。但是,不推荐使用Mac地址作为唯一的标识号。

缺点设备要具备Wi – Fi功能(并非所有的设备都有Wi – Fi功能)如果设备目前正在使用Wi - Fi,则不能报告Mac地址

序列号

从Android 2.3(“姜饼”)开始,通过android.os.Build.SERIAL方法序列号可被使用。没有电话功能的设备也都需要上给出唯一的设备ID;  某些手机也可以需要这样做。序列号可以用于识别MID(移动互联网设备)或PMP(便携式媒体播放器),这两种设备都没有电话功能。通过读取系统属性值“ro.serialno”的方法,可以使用序列号作为设备ID 。如检索序列号并作为设备ID使用,请参考下面的代码示例。

  1. <span style="font-size:16px;">import java.lang.reflect.Method;
  2. String serialnum = null;
  3. try {
  4. Class<?> c = Class.forName("android.os.SystemProperties");
  5. Method get = c.getMethod("get", String.class, String.class );
  6. serialnum = (String)(   get.invoke(c, "ro.serialno", "unknown" )  );
  7. } catch (Exception ignored) {
  8. }</span>

缺点

序列号无法在所有Android设备上使用。

ANDROID_ID

说明

更具体地说,Settings.Secure.ANDROID_ID 是一串64位的编码(十六进制的字符串),是随机生成的设备的第一个引导,其记录着一个固定值,通过它可以知道设备的寿命(在设备恢复出厂设置后,该值可能会改变)。 ANDROID_ID也可视为作为唯一设备标识号的一个好选择。如要检索用于设备ID 的ANDROID_ID,请参阅下面的示例代码

String androidId = Settings.Secure.getString(getContentResolver(),Settings.Secure.ANDROID_ID);

缺点

• 对于Android 2.2(“Froyo”)之前的设备不是100%的可靠

• 此外,在主流制造商的畅销手机中至少存在一个众所周知的错误,每一个实例都具有相同的ANDROID_ID。

结论

对于绝大多数应用来说,只需识别特定的安装配置,而不需要识别物理设备。所幸是,这样做就省去了麻烦。

下面是部分使用设备ID的最佳途径:

•支持各种设备类型的另一种方法是使用getDeviceID()API和ro.serialno的组合

•有许多值得参考的原因,来提醒开发者避免试图识别特定的设备。对于那些想做一下这方面尝试的用户, 最好的办法可能是使用ANDROID_ID,并在一些传统设备上做尝试。

示例代码

下面是用于追踪Android设置的示例代码

类: ReadDeviceID.java

  1. <span xmlns="http://www.w3.org/1999/xhtml" style="font-size:12px;color:#000000;"><strong xmlns="http://www.w3.org/1999/xhtml"><span xmlns="http://www.w3.org/1999/xhtml" style="">package com.deviceid;
  2. import java.lang.reflect.Method;
  3. import android.app.Activity;
  4. import android.content.Context;
  5. import android.os.Bundle;
  6. import android.provider.Settings;
  7. import android.telephony.TelephonyManager;
  8. import android.view.View;
  9. import android.view.View.OnClickListener;
  10. import android.widget.Button;
  11. import android.widget.TextView;
  12. public class ReadDeviceID extends Activity {
  13. Button bt;
  14. TextView idView;
  15. /** Called when the activity is first created. */
  16. @Override
  17. public void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.main);
  20. bt=(Button)findViewById(R.id.button1);
  21. idView=(TextView)findViewById(R.id.textView1);
  22. bt.setOnClickListener(new OnClickListener() {
  23. @Override
  24. public void onClick(View v) {
  25. String imeistring=null;
  26. String imsistring=null;
  27. TelephonyManager   telephonyManager =
  28. ( TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
  29. /*
  30. * getDeviceId() function Returns the unique device ID.
  31. * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.
  32. */
  33. imeistring = telephonyManager.getDeviceId();
  34. idView.append("IMEI No : "+imeistring+"\n");
  35. /*
  36. * getSubscriberId() function Returns the unique subscriber ID,
  37. * for example, the IMSI for a GSM phone.
  38. */
  39. imsistring = telephonyManager.getSubscriberId();
  40. idView.append("IMSI No : "+imsistring+"\n");
  41. /*
  42. * System Property ro.serialno returns the serial number as unique number
  43. * Works for Android 2.3 and above
  44. */
  45. String hwID = android.os.SystemProperties.get("ro.serialno", "unknown");
  46. idView.append( "hwID : " + hwID + "\n" );
  47. String serialnum = null;
  48. try {
  49. Class<?> c = Class.forName("android.os.SystemProperties");
  50. Method get = c.getMethod("get", String.class, String.class );
  51. serialnum = (String)(   get.invoke(c, "ro.serialno", "unknown" )  );
  52. idView.append( "serial : " + serialnum + "\n" );
  53. } catch (Exception ignored) {
  54. }
  55. String serialnum2 = null;
  56. try {
  57. Class myclass = Class.forName( "android.os.SystemProperties" );
  58. Method[] methods = myclass.getMethods();
  59. Object[] params = new Object[] { new String( "ro.serialno" ) , new String("Unknown" ) };
  60. serialnum2 = (String)(methods[2].invoke( myclass, params ));
  61. idView.append( "serial2 : " + serialnum2 + "\n" );
  62. }catch (Exception ignored) {
  63. }
  64. /*
  65. * Settings.Secure.ANDROID_ID returns the unique DeviceID
  66. * Works for Android 2.2 and above
  67. */
  68. String androidId = Settings.Secure.getString(getContentResolver(),
  69. Settings.Secure.ANDROID_ID);
  70. idView.append( "AndroidID : " + androidId + "\n" );
  71. }
  72. });
  73. }
  74. } </span></strong></span>

类: SystemProperties.java

  1. package android.os;
  2. /**
  3. * Gives access to the system properties store. The system properties
  4. * store contains a list of string key-value pairs.
  5. *
  6. * {@hide}
  7. */
  8. public class SystemProperties {
  9. public static final int PROP_NAME_MAX = 31;
  10. public static final int PROP_VALUE_MAX = 91;
  11. private static native String native_get(String key);
  12. private static native String native_get(String key, String def);
  13. private static native int native_get_int(String key, int def);
  14. private static native long native_get_long(String key, long def);
  15. private static native boolean native_get_boolean(String key, boolean def);
  16. private static native void native_set(String key, String def);
  17. /**
  18. * Get the value for the given key.
  19. * @return an empty string if the key isn't found
  20. * @throws IllegalArgumentException if the key exceeds 32 characters
  21. */
  22. public static String get(String key) {
  23. if (key.length() > PROP_NAME_MAX) {
  24. throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  25. }
  26. return native_get(key);
  27. }
  28. /**
  29. * Get the value for the given key.
  30. * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
  31. * @throws IllegalArgumentException if the key exceeds 32 characters
  32. */
  33. public static String get(String key, String def) {
  34. if (key.length() > PROP_NAME_MAX) {
  35. throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  36. }
  37. return native_get(key, def);
  38. }
  39. /**
  40. * Get the value for the given key, and return as an integer.
  41. * @param key the key to lookup
  42. * @param def a default value to return
  43. * @return the key parsed as an integer, or def if the key isn't found or
  44. *         cannot be parsed
  45. * @throws IllegalArgumentException if the key exceeds 32 characters
  46. */
  47. public static int getInt(String key, int def) {
  48. if (key.length() > PROP_NAME_MAX) {
  49. throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  50. }
  51. return native_get_int(key, def);
  52. }
  53. /**
  54. * Get the value for the given key, and return as a long.
  55. * @param key the key to lookup
  56. * @param def a default value to return
  57. * @return the key parsed as a long, or def if the key isn't found or
  58. *         cannot be parsed
  59. * @throws IllegalArgumentException if the key exceeds 32 characters
  60. */
  61. public static long getLong(String key, long def) {
  62. if (key.length() > PROP_NAME_MAX) {
  63. throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  64. }
  65. return native_get_long(key, def);
  66. }
  67. /**
  68. * Get the value for the given key, returned as a boolean.
  69. * Values 'n', 'no', '0', 'false' or 'off' are considered false.
  70. * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
  71. * (case insensitive).
  72. * If the key does not exist, or has any other value, then the default
  73. * result is returned.
  74. * @param key the key to lookup
  75. * @param def a default value to return
  76. * @return the key parsed as a boolean, or def if the key isn't found or is
  77. *         not able to be parsed as a boolean.
  78. * @throws IllegalArgumentException if the key exceeds 32 characters
  79. */
  80. public static boolean getBoolean(String key, boolean def) {
  81. if (key.length() > PROP_NAME_MAX) {
  82. throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  83. }
  84. return native_get_boolean(key, def);
  85. }
  86. /**
  87. * Set the value for the given key.
  88. * @throws IllegalArgumentException if the key exceeds 32 characters
  89. * @throws IllegalArgumentException if the value exceeds 92 characters
  90. */
  91. public static void set(String key, String val) {
  92. if (key.length() > PROP_NAME_MAX) {
  93. throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  94. }
  95. if (val != null && val.length() > PROP_VALUE_MAX) {
  96. throw new IllegalArgumentException("val.length > " +
  97. PROP_VALUE_MAX);
  98. }
  99. native_set(key, val);
  100. }
  101. }

使用"ReadDeviceID" activity 创建"com.deviceid"项目。将布局"main.xml"改写成下面的代码

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"

/>

<Button

android:text="GetDeviceID"

android:id="@+id/button1"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

</Button>

<TextView

android:id="@+id/textView1"

android:layout_width="fill_parent"

android:layout_height="wrap_content">

</TextView>

</LinearLayout>

"AndroidManifest.xml"文件中添加"READ_PHONE_STATE"许可,使应用程序可以登陆互联网。

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.deviceid"

android:versionCode="1"

android:versionName="1.0">

<uses-sdk android:minSdkVersion="7" />

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".ReadDeviceID"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

<uses-permission

android:name="android.permission.READ_PHONE_STATE" >

</uses-permission>

</manifest>

输出结果

上方示例代码的输出结果如下图所示:

原文: http://samsungapps.csdn.net/text.html?arcid=304625

还可以参考: http://www.byywee.com/page/M0/S613/613551.html

【转】获取android设备 id的更多相关文章

  1. Appium自动获取 Android 设备 id 和包名等信息(python)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/zhusongziye/article/d ...

  2. 获取Android设备屏幕分辨率

    1.Android 4.3引入的wm工具: a.获取Android设备屏幕分辨率: adb shell wm size b.获取android设备屏幕密度: adb shell wm density ...

  3. Android 开发 获取Android设备的屏幕高宽

    获得屏幕的宽度和高度有很多种方法: //1.通过WindowManager获取 DisplayMetrics dm = new DisplayMetrics(); heigth = dm.height ...

  4. 获取Android设备WIFI的MAC地址 “MAC地址”

    需要指出的是:wifi状态和wifi AP状态是互斥的状态:也就是一旦发现WIFI AP打开,WIFI是不能被打开的. 获取Android设备的WIFI MAC地址,首先需要将设备中的WIFI个人热点 ...

  5. 获取Android设备唯一标识码

    概述 有时需要对用户设备进行标识,所以希望能够得到一个稳定可靠并且唯一的识别码.虽然Android系统中提供了这样设备识别码,但是由于Android系统版本.厂商定制系统中的Bug等限制,稳定性和唯一 ...

  6. Android开发 - 获取Android设备的唯一标识码(Android 6.0或更高)

    在我们的APP开发中,通常需要获取到设备的唯一标识.在Android6.0之前,有很多方法我们可以方便获取到硬件的唯一标识,但是在Android6.0之后,Android系统大幅限制了我们获取设备的硬 ...

  7. 获取Android设备的唯一识别码|设备号|序号|UUID

    如何获取一个能唯一标识每台Android设备的序号? 这个问题有很多答案,但是他们中的大部分只在某些情况下有效. 根据测试: 所有的设备都可以返回一个 TelephonyManager.getDevi ...

  8. 获取Android设备标识符

    Android开发中有时候因业务需要客户端要产生一个唯一的标识符使服务器能识别某台Android设备,目前一般使用三种标识符分别为DeviceId.AndroidId.MAC地址. 获取DeviceI ...

  9. 稳定获取Android设备唯一码(UUID)的解决方案

    最近做的一个项目中需要用到Android设备唯一码(UUID)来标识一台设备, Android中设备唯一码有很多,如:MAC地址.IMEI号(DeviceId).IMSI号.ANDROID_ID.序列 ...

随机推荐

  1. html5 之 canvas 相关知识(二)API-fillStyle

    颜色.样式和阴影 fillStyle 设置或返回用于填充绘画的颜色.渐变或模式 定义和用法 context.fillStyle=color|gradient|pattern;//指示绘图填充色的CSS ...

  2. Ionic之顺带APP

    1:Ionic简介 官方:我们设计ionic来帮助 web 开发人员能够像开发网站一样开发出强大的移动APP应用. ionic是一个html5开发APP的框架,在开发运行效率可以说是最好的H5框架,把 ...

  3. 通过Scrapy抓取QQ空间

    毕业设计题目就是用Scrapy抓取QQ空间的数据,最近毕业设计弄完了,来总结以下: 首先是模拟登录的问题: 由于Tencent对模拟登录比较讨厌,各个防备,而本人能力有限,所以做的最简单的,手动登录后 ...

  4. linux中重置服务器的mysql用户密码

    本文章前提条件是自己经把mysql登录密码给忘记了,这个时间我们解决方法有很多,重新安装mysql数据库一切重来,另一种是通过下面文章重新设置root密码,下面我们一起来看看方法二吧.     最 近 ...

  5. [转]oracle 实现插入自增列

    本文转自:http://blog.csdn.net/love_zt_love/article/details/7911104 刚使用oracle,它和sql server 好多地方还是有所不同的,简单 ...

  6. GridView自带分页 1总页数 首页 下一页 上一页 尾页 X 页 go 实现方法 .

    在前台GRIDVIEW中添加如下代码 <PagerTemplate> <table> <tr> <td style="text-align: rig ...

  7. 【学习笔记】【C语言】sizeof

    1.用来计算一个变量或者一个常量.一种数据类型所占的内存字节数. 2.sizeof一共有3种形式 1>sizeof( 变量\常量 ) sizeof(10); char c = 'a'; size ...

  8. dropdownlist值改变时调用js

    DropDownList的OnSelectedIndexChanged方法是服务器端方法如要用需要设置AutoPostBack选项为true,并且在服务器后台写方法 要调用js方法需要onchange ...

  9. 解决IE6下固定定位问题 使用position:fixed

    IE6浏览器有太多的bug让制作网页的人头疼.这篇文章介绍的是介绍的是如何解决IE6不支持position:fixed;属性的办法. 如果我们需要做某个元素始终位于浏览器的底部,不会因为浏览器窗口的缩 ...

  10. WCF之安全

    传输安全. 点对点,对整个消息进行加密,性能损失,当中间者不安全时,消息也就不安全了. WCF中支持传输安全和消息安全模式. 通过配置和绑定来设置.<Security Mode =Transct ...