关于本文档

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

[java] view
plain
copy

  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文件中。

[java] view
plain
copy

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

缺点

•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. 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. }
  8. catch (Exception ignored)
  9. {
  10. }

缺点

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

ANDROID_ID

说明

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

[java] view
plain
copy

  1. 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

[java] view
plain
copy

  1. 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(
  60. "Unknown" ) };
  61. serialnum2 = (String)(methods[2].invoke( myclass, params ));
  62. idView.append( "serial2 : " + serialnum2 + "\n" );
  63. }catch (Exception ignored)
  64. {
  65. }
  66. /*
  67. * Settings.Secure.ANDROID_ID returns the unique DeviceID
  68. * Works for Android 2.2 and above
  69. */
  70. String androidId = Settings.Secure.getString(getContentResolver(),
  71. Settings.Secure.ANDROID_ID);
  72. idView.append( "AndroidID : " + androidId + "\n" );
  73. }
  74. });
  75. }
  76. }

类: SystemProperties.java

[java] view
plain
copy

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

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

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="@string/hello"
  11. />
  12. <Button
  13. android:text="GetDeviceID"
  14. android:id="@+id/button1"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content">
  17. </Button>
  18. <TextView
  19. android:id="@+id/textView1"
  20. android:layout_width="fill_parent"
  21. android:layout_height="wrap_content">
  22. </TextView>
  23. </LinearLayout>

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

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.deviceid"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <uses-sdk android:minSdkVersion="7" />
  7. <application android:icon="@drawable/icon" android:label="@string/app_name">
  8. <activity android:name=".ReadDeviceID"
  9. android:label="@string/app_name">
  10. <intent-filter>
  11. <action android:name="android.intent.action.MAIN" />
  12. <category android:name="android.intent.category.LAUNCHER" />
  13. </intent-filter>
  14. </activity>
  15. </application>
  16. <uses-permission
  17. android:name="android.permission.READ_PHONE_STATE" >
  18. </uses-permission>
  19. </manifest>

输出结果

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

Android 如何检索Android设备的唯一ID的更多相关文章

  1. 如何检索Android设备的唯一ID

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

  2. 【转】 不需要任何权限获得Android设备的唯一ID

    不需要任何权限获得Android设备的唯一ID,权限android设备id 这个问题来自于Is there a unique Android device ID? 我对这个问题的答案做了整理,包括将另 ...

  3. 设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识 zz

    原文地址:http://www.vonwei.com/post/UniqueDeviceIDforWindows.html 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保 ...

  4. [转]设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识

    原文地址:http://www.vonwei.com/post/UniqueDeviceIDforWindows.html 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保 ...

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

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

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

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

  7. 移动设备(手机)的唯一ID有哪些

    移动设备(手机)的唯一ID有哪些 在移动广告领域,设备的ID 是用来追踪一个人的最重要的标识. 对于APP自身产品而言,使用设备唯一ID可以追踪到用户从下载到激活.注册.使用.流失.回归的全流程数据, ...

  8. Android - 支持不同的设备 - 支持不同的平台版本

    在最新版本的Android为app提供很好的新API时,也应该继续支持旧版本的Android直到大部分设备已经更新了.这里将要介绍如何在使用最新API带来的优点的同时继续支持老版本. Dashboar ...

  9. Android 在同一台设备上安装多个同一项目的apk

    如果设备上已经安装了一个apk,再次安装这个apk就会提示覆盖前面的应用 解决办法: 方法一:手动改包名 不好改,改了几次都不成功(可能是代码在svn管理的原因,改完后文件夹里的代码就没了),确实不实 ...

随机推荐

  1. [Angular] Reactive Store and AngularFire Observables

    A simple store implemenet: import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } ...

  2. (转)利用openfiler实现iSCSI

    转自:http://czmmiao.iteye.com/blog/1735417 openfiler openfiler是一个基于浏览器的网络存储管理工具.来自于Linux系统.openfiler在一 ...

  3. [Angular2 Router] Auxiliary Routes bit by bit

    Article Github Auxiliary Routes is is little bit hard to understand. Here is demo, link You can see ...

  4. UVA 10106 Product (大数相乘)

    Product The Problem The problem is to multiply two integers X, Y. (0<=X,Y<10250) The Input The ...

  5. thinkphp3.2.3 小程序获取手机号 php 解密

    首先是把这个文件夹放到\ThinkPHP\Library\Org里面 //zll 根据加密字符串和session_key和iv获取手机号 /** * [getphone description] * ...

  6. 【29.70%】【codeforces 723D】Lakes in Berland

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. 【TP SRM 703 div2 500】 GCDGraph

    Problem Statement You are given four ints: n, k, x, and y. The ints n and k describe a simple undire ...

  8. 在Scope利用Content sharing Widget来分享内容

    在最新的Scope Widget中,有一个新的Content Sharing Widget.我们能够利用这个Widget来分享我们的图片到信息.Facebook,Twitter等渠道.比方,在我们的S ...

  9. iOS开发Quartz2D十二:手势解锁实例

    一:效果如图: 二:代码: #import "ClockView.h" @interface ClockView() /** 存放的都是当前选中的按钮 */ @property ( ...

  10. [转载]Surging教学视频资源汇总

    surging是什么 surging 是一个分布式微服务框架,提供高性能RPC远程服务调用,采用Zookeeper.Consul作为surging服务的注册中心,集成了哈希,随机,轮询.压力最小优先作 ...