Android 如何检索Android设备的唯一ID
关于本文档
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
- import android.telephony.TelephonyManager;
- import android.content.Context;
- String imeistring = null;
- String imsistring = null;
- {
- TelephonyManager telephonyManager;
- telephonyManager =
- ( TelephonyManager )getSystemService( Context.TELEPHONY_SERVICE );
- /*
- * getDeviceId() function Returns the unique device ID.
- * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.
- */
- imeistring = telephonyManager.getDeviceId();
- /*
- * getSubscriberId() function Returns the unique subscriber ID,
- * for example, the IMSI for a GSM phone.
- */
- imsistring = telephonyManager.getSubscriberId();
- }
如要只读取手机的状态,则需添加READ_PHONE_STATE许可到AndroidManifest.xml文件中。
- <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使用,请参考下面的代码示例。
- import java.lang.reflect.Method;
- String serialnum = null;
- try {
- Class<?> c = Class.forName("android.os.SystemProperties");
- Method get = c.getMethod("get", String.class, String.class );
- serialnum = (String)( get.invoke(c, "ro.serialno", "unknown" ) );
- }
- catch (Exception ignored)
- {
- }
缺点
序列号无法在所有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
- package com.deviceid;
- import java.lang.reflect.Method;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.provider.Settings;
- import android.telephony.TelephonyManager;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- public class ReadDeviceID extends Activity {
- Button bt;
- TextView idView;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- bt=(Button)findViewById(R.id.button1);
- idView=(TextView)findViewById(R.id.textView1);
- bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String imeistring=null;
- String imsistring=null;
- TelephonyManager telephonyManager =
- ( TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );
- /*
- * getDeviceId() function Returns the unique device ID.
- * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.
- */
- imeistring = telephonyManager.getDeviceId();
- idView.append("IMEI No : "+imeistring+"\n");
- /*
- * getSubscriberId() function Returns the unique subscriber ID,
- * for example, the IMSI for a GSM phone.
- */
- imsistring = telephonyManager.getSubscriberId();
- idView.append("IMSI No : "+imsistring+"\n");
- /*
- * System Property ro.serialno returns the serial number as unique number
- * Works for Android 2.3 and above
- */
- String hwID = android.os.SystemProperties.get("ro.serialno", "unknown");
- idView.append( "hwID : " + hwID + "\n" );
- String serialnum = null;
- try {
- Class<?> c = Class.forName("android.os.SystemProperties");
- Method get = c.getMethod("get", String.class, String.class );
- serialnum = (String)( get.invoke(c, "ro.serialno", "unknown" ) );
- idView.append( "serial : " + serialnum + "\n" );
- } catch (Exception ignored) {
- }
- String serialnum2 = null;
- try {
- Class myclass = Class.forName( "android.os.SystemProperties" );
- Method[] methods = myclass.getMethods();
- Object[] params = new Object[] { new String( "ro.serialno" ) , new String(
- "Unknown" ) };
- serialnum2 = (String)(methods[2].invoke( myclass, params ));
- idView.append( "serial2 : " + serialnum2 + "\n" );
- }catch (Exception ignored)
- {
- }
- /*
- * Settings.Secure.ANDROID_ID returns the unique DeviceID
- * Works for Android 2.2 and above
- */
- String androidId = Settings.Secure.getString(getContentResolver(),
- Settings.Secure.ANDROID_ID);
- idView.append( "AndroidID : " + androidId + "\n" );
- }
- });
- }
- }
类: SystemProperties.java
- package android.os;
- /**
- * Gives access to the system properties store. The system properties
- * store contains a list of string key-value pairs.
- *
- * {@hide}
- */
- public class SystemProperties
- {
- public static final int PROP_NAME_MAX = 31;
- public static final int PROP_VALUE_MAX = 91;
- private static native String native_get(String key);
- private static native String native_get(String key, String def);
- private static native int native_get_int(String key, int def);
- private static native long native_get_long(String key, long def);
- private static native boolean native_get_boolean(String key, boolean def);
- private static native void native_set(String key, String def);
- /**
- * Get the value for the given key.
- * @return an empty string if the key isn't found
- * @throws IllegalArgumentException if the key exceeds 32 characters
- */
- public static String get(String key) {
- if (key.length() > PROP_NAME_MAX) {
- throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
- }
- return native_get(key);
- }
- /**
- * Get the value for the given key.
- * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
- * @throws IllegalArgumentException if the key exceeds 32 characters
- */
- public static String get(String key, String def) {
- if (key.length() > PROP_NAME_MAX) {
- throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
- }
- return native_get(key, def);
- }
- /**
- * Get the value for the given key, and return as an integer.
- * @param key the key to lookup
- * @param def a default value to return
- * @return the key parsed as an integer, or def if the key isn't found or
- * cannot be parsed
- * @throws IllegalArgumentException if the key exceeds 32 characters
- */
- public static int getInt(String key, int def) {
- if (key.length() > PROP_NAME_MAX) {
- throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
- }
- return native_get_int(key, def);
- }
- /**
- * Get the value for the given key, and return as a long.
- * @param key the key to lookup
- * @param def a default value to return
- * @return the key parsed as a long, or def if the key isn't found or
- * cannot be parsed
- * @throws IllegalArgumentException if the key exceeds 32 characters
- */
- public static long getLong(String key, long def) {
- if (key.length() > PROP_NAME_MAX) {
- throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
- }
- return native_get_long(key, def);
- }
- /**
- * Get the value for the given key, returned as a boolean.
- * Values 'n', 'no', '0', 'false' or 'off' are considered false.
- * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
- * (case insensitive).
- * If the key does not exist, or has any other value, then the default
- * result is returned.
- * @param key the key to lookup
- * @param def a default value to return
- * @return the key parsed as a boolean, or def if the key isn't found or is
- * not able to be parsed as a boolean.
- * @throws IllegalArgumentException if the key exceeds 32 characters
- */
- public static boolean getBoolean(String key, boolean def) {
- if (key.length() > PROP_NAME_MAX) {
- throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
- }
- return native_get_boolean(key, def);
- }
- /**
- * Set the value for the given key.
- * @throws IllegalArgumentException if the key exceeds 32 characters
- * @throws IllegalArgumentException if the value exceeds 92 characters
- */
- public static void set(String key, String val) {
- if (key.length() > PROP_NAME_MAX) {
- throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
- }
- if (val != null && val.length() > PROP_VALUE_MAX) {
- throw new IllegalArgumentException("val.length > " +
- PROP_VALUE_MAX);
- }
- native_set(key, val);
- }
- }
使用"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>
输出结果
上方示例代码的输出结果如下图所示:
Android 如何检索Android设备的唯一ID的更多相关文章
- 如何检索Android设备的唯一ID
关于本文档 Android的开发者在一些特定情况下都需要知道手机中的唯一设备ID.例如,跟踪应用程序的安装,生成用于复制保护的DRM时需要使用设备的唯一ID.在本文档结尾处提供了作为参考的示例代码片段 ...
- 【转】 不需要任何权限获得Android设备的唯一ID
不需要任何权限获得Android设备的唯一ID,权限android设备id 这个问题来自于Is there a unique Android device ID? 我对这个问题的答案做了整理,包括将另 ...
- 设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识 zz
原文地址:http://www.vonwei.com/post/UniqueDeviceIDforWindows.html 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保 ...
- [转]设备唯一标识方法(Unique Identifier):如何在Windows系统上获取设备的唯一标识
原文地址:http://www.vonwei.com/post/UniqueDeviceIDforWindows.html 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保 ...
- Android开发 - 获取Android设备的唯一标识码(Android 6.0或更高)
在我们的APP开发中,通常需要获取到设备的唯一标识.在Android6.0之前,有很多方法我们可以方便获取到硬件的唯一标识,但是在Android6.0之后,Android系统大幅限制了我们获取设备的硬 ...
- 获取Android设备的唯一识别码|设备号|序号|UUID
如何获取一个能唯一标识每台Android设备的序号? 这个问题有很多答案,但是他们中的大部分只在某些情况下有效. 根据测试: 所有的设备都可以返回一个 TelephonyManager.getDevi ...
- 移动设备(手机)的唯一ID有哪些
移动设备(手机)的唯一ID有哪些 在移动广告领域,设备的ID 是用来追踪一个人的最重要的标识. 对于APP自身产品而言,使用设备唯一ID可以追踪到用户从下载到激活.注册.使用.流失.回归的全流程数据, ...
- Android - 支持不同的设备 - 支持不同的平台版本
在最新版本的Android为app提供很好的新API时,也应该继续支持旧版本的Android直到大部分设备已经更新了.这里将要介绍如何在使用最新API带来的优点的同时继续支持老版本. Dashboar ...
- Android 在同一台设备上安装多个同一项目的apk
如果设备上已经安装了一个apk,再次安装这个apk就会提示覆盖前面的应用 解决办法: 方法一:手动改包名 不好改,改了几次都不成功(可能是代码在svn管理的原因,改完后文件夹里的代码就没了),确实不实 ...
随机推荐
- Android ListView带CheckBox实现单选
第1种方法: 首先是我们的bean: public class Bean { private boolean isChecked; private String msg = "这是一条测试数 ...
- 3、U-boot的环境变量: bootcmd 和bootargs
u-bootcmdbootcmd是uboot自动启动时默认执行的一些命令,因此你可以在当前环境中定义各种不同配置,不同环境的参数设置,然后设置bootcmd为你经常使用的那种参数. 现在我的boo ...
- 数据结构与算法实验题 9.1 K 歌 DFS+剪枝
数据结构与算法实验题 K 歌 ★实验任务 3* n 个人(标号1~ 3 * n )分成 n 组 K 歌.有 m 个 3 人组合,每个组合都对应一个分数,你能算出最大能够得到的总分数么? ★数据输入 输 ...
- 【例题5-2 UVA - 101】The Blocks Problem
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用vector模拟就好. resize的时候,只是把多余的清理掉. 原先的不会变的. [错的次数] 在这里输入错的次数 [反思] 在 ...
- hadoop一些常见报错的解决方式
Failed to set setXIncludeAware(true) for parser 遇到此问题通常是jar包冲突的问题. 一种情况是我们向java的lib文件夹加入我们自己的jar包导致h ...
- iOS开发RunnLoop学习二:GCD中的定时器
#import "ViewController.h" @interface ViewController () /** 注释 */ @property (nonatomic, st ...
- adb常用命令 分类: H1_ANDROID 2013-09-08 15:22 510人阅读 评论(0) 收藏
安装软件 adb install apk文件名称.apk 重新安装该软件 adb install -r apk文件名称.apk 卸载apk软件 adb uninstall apk包名.apk ...
- jquery修改获取radio的选中项
<input id="txtBeginDate" onclick="$('#divDate').css({'top':$('#txtBeginDate').offs ...
- 五一巨献,问答有礼,105QB送给IT互联网界的劳动人民
活动主题:五一巨献,问答有礼,105QB送给IT互联网界的劳动人民活动时间:4月30日晚上10点~5月2日晚上10点活动期数:第1期,20150401 奖品:105QB获奖人数:20人1~5:每人10 ...
- ajax传递list集合
原文链接:https://blog.csdn.net/qq_37936542/article/details/79277495 一:ajax传递List<String>类型的数据 js代码 ...