关于本文档

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 plain copy
  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 plain copy
  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 plain copy
  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 plain copy
  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. 从零学Android(四)、适配不同的Android设备
  2. android动作传感器
  3. Android开发中使用矢量图
  4. 解读Android(安卓)LOG机制的实现:(6)c/c++域使用LOG
  5. Android分享文件到微信和QQ功能的实现(兼容android 7.0以上的共享
  6. 一起学android之简单了解Android(安卓)OS内部机制(29)
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. android基础入门(一)――搭建android开发
  2. 如何看待安卓未来的发展
  3. 二维码的生成细节和原理
  4. 我的DIY Android 之旅--gps框架及简析
  5. Android特色开发之语音识别
  6. iWidsets公告
  7. [android开发笔记]Unable to resolve tar
  8. Android中常用的框架(从GitHub开源库中代
  9. android 开发布局之TableLayout
  10. Android:Service之远程服务和AIDL的创建