关于本文档

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

范围

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

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

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

·唯一编号(IMEIMEIDESNIMSI

·MAC地址

·序列号

·ANDROID_ID

唯一编号(IMEIMEIDESNIMSI

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

TelephonyManager.getDeviceId

IMEIMEIDESNIMSI的定义如下:

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

•MEID

•ESN

•IMSI

[java]view plaincopy

<EMBED id=ZeroClipboardMovie_1 name=ZeroClipboardMovie_1 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=1&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. importandroid.telephony.TelephonyManager;

  2. importandroid.content.Context;

  3. Stringimeistring=null;

  4. Stringimsistring=null;

  5. {

  6. TelephonyManagertelephonyManager;

  7. telephonyManager=

  8. (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

  9. /*

  10. *getDeviceId()functionReturnstheuniquedeviceID.

  11. *forexample,theIMEIforGSMandtheMEIDorESNforCDMAphones.

  12. */

  13. imeistring=telephonyManager.getDeviceId();

  14. /*

  15. *getSubscriberId()functionReturnstheuniquesubscriberID,

  16. *forexample,theIMSIforaGSMphone.

  17. */

  18. imsistring=telephonyManager.getSubscriberId();

  19. }


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

<uses-permission

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

</uses-permission>

缺点

•Android设备要具有电话功能

其工作不是很可靠

序列号

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

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使用,请参考下面的代码示例。

[java]view plaincopy

<EMBED id=ZeroClipboardMovie_2 name=ZeroClipboardMovie_2 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=2&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. <spanstyle="font-size:16px;">importjava.lang.reflect.Method;

  2. Stringserialnum=null;

  3. try{

  4. Class<?>c=Class.forName("android.os.SystemProperties");

  5. Methodget=c.getMethod("get",String.class,String.class);

  6. serialnum=(String)(get.invoke(c,"ro.serialno","unknown"));

  7. }catch(Exceptionignored){

  8. }</span>


缺点

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

ANDROID_ID

说明

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

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

缺点

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

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

结论

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

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

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

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

示例代码

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

: ReadDeviceID.java

[java]view plaincopy

<EMBED id=ZeroClipboardMovie_3 name=ZeroClipboardMovie_3 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=3&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. <spanxmlns="http://www.w3.org/1999/xhtml"style="font-size:12px;color:#000000;"><strongxmlns="http://www.w3.org/1999/xhtml"><spanxmlns="http://www.w3.org/1999/xhtml"style="">packagecom.deviceid;

  2. importjava.lang.reflect.Method;

  3. importandroid.app.Activity;

  4. importandroid.content.Context;

  5. importandroid.os.Bundle;

  6. importandroid.provider.Settings;

  7. importandroid.telephony.TelephonyManager;

  8. importandroid.view.View;

  9. importandroid.view.View.OnClickListener;

  10. importandroid.widget.Button;

  11. importandroid.widget.TextView;

  12. publicclassReadDeviceIDextendsActivity{

  13. Buttonbt;

  14. TextViewidView;

  15. /**Calledwhentheactivityisfirstcreated.*/

  16. @Override

  17. publicvoidonCreate(BundlesavedInstanceState){

  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(newOnClickListener(){

  23. @Override

  24. publicvoidonClick(Viewv){

  25. Stringimeistring=null;

  26. Stringimsistring=null;

  27. TelephonyManagertelephonyManager=

  28. (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

  29. /*

  30. *getDeviceId()functionReturnstheuniquedeviceID.

  31. *forexample,theIMEIforGSMandtheMEIDorESNforCDMAphones.

  32. */

  33. imeistring=telephonyManager.getDeviceId();

  34. idView.append("IMEINo:"+imeistring+"\n");

  35. /*

  36. *getSubscriberId()functionReturnstheuniquesubscriberID,

  37. *forexample,theIMSIforaGSMphone.

  38. */

  39. imsistring=telephonyManager.getSubscriberId();

  40. idView.append("IMSINo:"+imsistring+"\n");

  41. /*

  42. *SystemPropertyro.serialnoreturnstheserialnumberasuniquenumber

  43. *WorksforAndroid2.3andabove

  44. */

  45. StringhwID=android.os.SystemProperties.get("ro.serialno","unknown");

  46. idView.append("hwID:"+hwID+"\n");

  47. Stringserialnum=null;

  48. try{

  49. Class<?>c=Class.forName("android.os.SystemProperties");

  50. Methodget=c.getMethod("get",String.class,String.class);

  51. serialnum=(String)(get.invoke(c,"ro.serialno","unknown"));

  52. idView.append("serial:"+serialnum+"\n");

  53. }catch(Exceptionignored){

  54. }

  55. Stringserialnum2=null;

  56. try{

  57. Classmyclass=Class.forName("android.os.SystemProperties");

  58. Method[]methods=myclass.getMethods();

  59. Object[]params=newObject[]{newString("ro.serialno"),newString("Unknown")};

  60. serialnum2=(String)(methods[2].invoke(myclass,params));

  61. idView.append("serial2:"+serialnum2+"\n");

  62. }catch(Exceptionignored){

  63. }

  64. /*

  65. *Settings.Secure.ANDROID_IDreturnstheuniqueDeviceID

  66. *WorksforAndroid2.2andabove

  67. */

  68. StringandroidId=Settings.Secure.getString(getContentResolver(),

  69. Settings.Secure.ANDROID_ID);

  70. idView.append("AndroidID:"+androidId+"\n");

  71. }

  72. });

  73. }

  74. }</span></strong></span>

: SystemProperties.java

[java]view plaincopy

<EMBED id=ZeroClipboardMovie_4 name=ZeroClipboardMovie_4 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=4&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">

  1. packageandroid.os;

  2. /**

  3. *Givesaccesstothesystempropertiesstore.Thesystemproperties

  4. *storecontainsalistofstringkey-valuepairs.

  5. *

  6. *{@hide}

  7. */

  8. publicclassSystemProperties{

  9. publicstaticfinalintPROP_NAME_MAX=31;

  10. publicstaticfinalintPROP_VALUE_MAX=91;

  11. privatestaticnativeStringnative_get(Stringkey);

  12. privatestaticnativeStringnative_get(Stringkey,Stringdef);

  13. privatestaticnativeintnative_get_int(Stringkey,intdef);

  14. privatestaticnativelongnative_get_long(Stringkey,longdef);

  15. privatestaticnativebooleannative_get_boolean(Stringkey,booleandef);

  16. privatestaticnativevoidnative_set(Stringkey,Stringdef);

  17. /**

  18. *Getthevalueforthegivenkey.

  19. *@returnanemptystringifthekeyisn'tfound

  20. *@throwsIllegalArgumentExceptionifthekeyexceeds32characters

  21. */

  22. publicstaticStringget(Stringkey){

  23. if(key.length()>PROP_NAME_MAX){

  24. thrownewIllegalArgumentException("key.length>"+PROP_NAME_MAX);

  25. }

  26. returnnative_get(key);

  27. }

  28. /**

  29. *Getthevalueforthegivenkey.

  30. *@returnifthekeyisn'tfound,returndefifitisn'tnull,oranemptystringotherwise

  31. *@throwsIllegalArgumentExceptionifthekeyexceeds32characters

  32. */

  33. publicstaticStringget(Stringkey,Stringdef){

  34. if(key.length()>PROP_NAME_MAX){

  35. thrownewIllegalArgumentException("key.length>"+PROP_NAME_MAX);

  36. }

  37. returnnative_get(key,def);

  38. }

  39. /**

  40. *Getthevalueforthegivenkey,andreturnasaninteger.

  41. *@paramkeythekeytolookup

  42. *@paramdefadefaultvaluetoreturn

  43. *@returnthekeyparsedasaninteger,ordefifthekeyisn'tfoundor

  44. *cannotbeparsed

  45. *@throwsIllegalArgumentExceptionifthekeyexceeds32characters

  46. */

  47. publicstaticintgetInt(Stringkey,intdef){

  48. if(key.length()>PROP_NAME_MAX){

  49. thrownewIllegalArgumentException("key.length>"+PROP_NAME_MAX);

  50. }

  51. returnnative_get_int(key,def);

  52. }

  53. /**

  54. *Getthevalueforthegivenkey,andreturnasalong.

  55. *@paramkeythekeytolookup

  56. *@paramdefadefaultvaluetoreturn

  57. *@returnthekeyparsedasalong,ordefifthekeyisn'tfoundor

  58. *cannotbeparsed

  59. *@throwsIllegalArgumentExceptionifthekeyexceeds32characters

  60. */

  61. publicstaticlonggetLong(Stringkey,longdef){

  62. if(key.length()>PROP_NAME_MAX){

  63. thrownewIllegalArgumentException("key.length>"+PROP_NAME_MAX);

  64. }

  65. returnnative_get_long(key,def);

  66. }

  67. /**

  68. *Getthevalueforthegivenkey,returnedasaboolean.

  69. *Values'n','no','0','false'or'off'areconsideredfalse.

  70. *Values'y','yes','1','true'or'on'areconsideredtrue.

  71. *(caseinsensitive).

  72. *Ifthekeydoesnotexist,orhasanyothervalue,thenthedefault

  73. *resultisreturned.

  74. *@paramkeythekeytolookup

  75. *@paramdefadefaultvaluetoreturn

  76. *@returnthekeyparsedasaboolean,ordefifthekeyisn'tfoundoris

  77. *notabletobeparsedasaboolean.

  78. *@throwsIllegalArgumentExceptionifthekeyexceeds32characters

  79. */

  80. publicstaticbooleangetBoolean(Stringkey,booleandef){

  81. if(key.length()>PROP_NAME_MAX){

  82. thrownewIllegalArgumentException("key.length>"+PROP_NAME_MAX);

  83. }

  84. returnnative_get_boolean(key,def);

  85. }

  86. /**

  87. *Setthevalueforthegivenkey.

  88. *@throwsIllegalArgumentExceptionifthekeyexceeds32characters

  89. *@throwsIllegalArgumentExceptionifthevalueexceeds92characters

  90. */

  91. publicstaticvoidset(Stringkey,Stringval){

  92. if(key.length()>PROP_NAME_MAX){

  93. thrownewIllegalArgumentException("key.length>"+PROP_NAME_MAX);

  94. }

  95. if(val!=null&&val.length()>PROP_VALUE_MAX){

  96. thrownewIllegalArgumentException("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

更多相关文章

  1. 使用ant让Android自动打包的build.xml,自动生成签名的apk文件(支
  2. Android中使用语音引擎入门七步曲
  3. Android(安卓)HAL实现的三种方式(1) - 基于JNI的简单HAL设计
  4. 使用IntelliJ IDEA开发Android中,你用崩溃汇报插件么?
  5. Linux文件的特殊权限位SUID、SGID作用及编程设置/读取
  6. 关于Android的selector背景选择器的配置不起作用的问题
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. android程序执行adb shell命令
  2. 详解Android(安卓)App AllowBackup配置带
  3. android使用util工具包
  4. android opensource webs
  5. android 短信拦截
  6. Android逆向基础之Dalvik指令集
  7. 优化布局在Android–减少过度渲染
  8. Android解析聚合数据之天气预报API
  9. Android studio的点击事件
  10. Android调用Jni,非常简单的一个Demo