如何检索Android设备的唯一ID

2023-05-16

Android的开发者在一些特定情况下都需要知道手机中的唯一设备ID。

关于本文档

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

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" >

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

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()APIro.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>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Android常用功能代码

    非完全原创 xff0c 大多源自网络向作者致敬 xff01 26 汉字按拼音排序比较器 汉字按字母顺序排列的比较器 class PinyinComarator implements Comparator lt Contact gt 64 O
  • ubuntu11.10安装经验

    1 用u盘安装的 xff0c 用ultraISO写入硬盘镜像 不过安装过程中卡在ubuntu下面有几个点的界面 xff0c 解决办法 xff1a 把u盘里面的isolinux文件夹命名为syslinux就好了 2 安装前在windows7里
  • Java常用类练习

    public class Unit7 1 public static void main String args System out println args length for String str args System out p
  • Virtualbox 虚拟机网络不通解决

    在桥接模式下 xff0c 混杂模式要选拒绝 否则可能不通
  • java遍历目录中的文件

    1 从一个教程上看到java遍历目录输出目录里面的文件的一个例子 xff0c 里面用到了递归的算法思想 xff0c 记得上高中的时候数学上学过这种思想 xff0c 当时有个汉诺塔的故事 public static void main Str
  • Android常用技术、常用工具和开源项目

    待解决和待学习的Android技术问题 xff1a 横竖屏切换生命周期的执行 xff1b startActivityForResult的使用 xff1b 地图上标记路线 搜索内容 xff1b Properties的使用 View有两对wid
  • Java IO学习笔记

    Java不会 xff0c 就去学Android xff0c 简直是扯淡 xff01 后悔晚了 xff0c 奋起直追吧 File类 xff1b RandomAccessFile xff1b OutputStream InputStream 字
  • 关于Java输入输出流的疑问

    一段拷贝功能代码 import java io File import java io InputStream import java io OutputStream import java io FileOutputStream impo
  • android 2.* 下如何使用actionbar

    想在android2 下面使用actionbar 我们可以使用JakeWharton写的support library扩展 ActionBarSherlock 1 ActionBarSherlock主页 http actionbarsher
  • JAVA基础之理解JNI原理

    JAVA基础之理解JNI原理 JNI是JAVA标准平台中的一个重要功能 xff0c 它弥补了JAVA的与平台无关这一重大优点的不足 xff0c 在JAVA实现跨平台的同时 xff0c 也能与其它语言 xff08 如C C 43 43 xff
  • cmd命令学习

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 Lin
  • 编程学习和感悟

    1 程序开发 xff0c 从想法到做出来有一个过程 xff0c 这个过程被称为algorithm xff08 算法 xff09 例如 xff1a Android中加载图片 图片的异步加载 xff1a SoftReference 不能阻止gc
  • 程序员应该阅读的书

    程序员书 http book douban com doulist 995723 UNIX编程艺术
  • 读取手机参数

    手机操作系统版本获取 public static int getSDKVersionNumber int sdkVersion try sdkVersion 61 Integer valueOf android os Build VERSI
  • 关于ASP.NET 不允许所请求的注册表访问权。

    这个问题困扰了我一天 xff0c 到现在头还是疼的 xff0c 参考了网上N个解决办法 xff0c 最后问了孟宪会老师 xff0c 老师说 匿名账户没有访问注册表的权限 xff0c 通过老师提醒 xff0c 我试着启用GUEST账户 xff
  • android中的density

    原帖地址 xff1a http blog csdn net zouxueping article details 5605332 向作者致谢 为什么要引入dip The reason for dip to exist is simple e
  • Doxygen code style

    64 file LifeActivity java 64 brief Android lifecycle test lt pre gt lt b gt company lt b gt http www microsoft com lt pr
  • Android中自定义属性的格式详解

    1 reference xff1a 参考某一资源ID xff08 1 xff09 属性定义 xff1a lt declare styleable name 61 34 名称 34 gt lt attr name 61 34 backgrou
  • 物理和数学

    内容来自于 加速度 xff08 Acceleration xff09 是速度变化量与发生这一变化所用时间的比值 是描述物体速度改变快慢的物理量 xff0c 通常用a表示 xff0c 单位是m s 2 xff08 米 秒 2 xff09 在物
  • android Activity LifeCycle

    android横竖屏切换时候的Activity LifeCycle 程序启动 01 23 18 33 47 711 I MainActivity 11233 gt onCreate 01 23 18 33 47 711 I MainActi

随机推荐

  • Java判断字符串是否为空的方法

    以下是 Java 判断字符串是否为空的几种方法 方法一 最多人使用的一个方法 直观 方便 但效率很低 方法二 比较字符串长度 效率高 是我知道的最好一个方法 方法三 Java SE 6 0 才开始提供的办法 效率和方法二基本上相等 但出于兼
  • 64位windows7的安装和系统分区扩展

    今天哥带来一台HASEE笔记本 xff0c 2G内存 xff0c i3处理器 xff0c 300G的硬盘 xff0c 让我装一个64位的windows7 因为只有安装64位的系统才能发挥出64位硬件的性能 xff0c 否则真是浪费硬件性能资
  • 汇编语言Assembly Language

    想念wangfeng老师 xff0c 他将深奥的汇编语言解析的是那么透彻明白 xff0c 身为学生的我真的受益良多 字符 十六进制ASCII 0 9 30h 39h A Z 41h 5ah a z 61h 7ah 逻辑运算 xff1a 与
  • SVN的使用

    1 Attempted to lock an already locked dir svn Working copy 39 x mywork project res layout 39 locked 原因 xff1a 产生这种情况大多是因为
  • 注册表文件的编写

    Windows 中的注册表文件 xff08 system dat和 user dat xff09 是 Windows 的核心数据库 xff0c 因此 xff0c 对 Windows 来说是非常重要的 通过修改注册表文件中的数据 xff0c
  • ASP.NET网站安装部署,加入注册码验证等等

    最近通过自己实践 xff0c 完成了ASP NET网站安装部署 xff0c 实现了SQL打包 xff0c 实现了配置文件的打包等等 xff0c 并实现了注册码的验证等等 xff0c 如有需要请跟帖 xff0c 留下联系方式
  • Windows使用经验收集

    19 最快的编辑任意网页代码 打开浏览器 xff0c 浏览一个网页 xff0c 按下F12打开开发人员工具 xff0c 然后点击console xff0c 也就是控制台 xff0c 输入 document body contentEdita
  • 如何提高自己的编程能力

    原帖地址 xff1a http www blogjava net xvridan archive 2007 02 17 100143 html 1 扎实的基础 数据结构 离散数学 编译原理 xff0c 这些是所有计算机科学的基础 xff0c
  • 排序算法学习

    61 61 61 冒泡排序 61 61 61 JAVA语言实现 学习冒泡排序 冒泡排序 xff08 Bubble Sort xff0c 台湾译为 xff1a 泡沫排序或气泡排序 xff09 是一种简单的排序算法 它重复地走访过要排序的数列
  • Android的Activity屏幕切换动画(二)-左右滑动深入与实战

    原帖 xff1a http www oschina net question 97118 34523 上一篇文章讲了 Android的左右滑动切换 xff0c 实现过程是非常简单 xff0c 一些新手可能会向深入了了解Activity切换的
  • Android 第三方 UI 库 GreenDroid 使用方法

    原帖地址 xff1a http www acwind net blog p 61 1297 一直觉得 Android SDK 本身提供的界面 UI 库实在是太难看了 xff0c 而且提供的功能也总是这里那里很多缺憾 所以一直在关注各种第三方
  • android视野慢慢开阔

    1 umeng 友盟移动开发者服务平台 http www umeng com 原来是分析用户的 xff0c 长见识了 友盟统计分析3 0 用更精细的数据读懂用户 服务超过30 000开发者 100 000款APP xff0c 日启动次数15
  • HTC G7 desire刷机和小米4刷原生安卓

    步骤 1 root 2 安装recovery recovery img文件 http down10 zol com cn shouji recovery clockwork 2 5 0 1 bravo slcd img reflash文件
  • java一些疑问的求证和遇到的问题

    100 关于byte array 有一个字符串s xff0c 输出字符对应的unicode十进制和十六进制 getBytes 貌似获取每个字符的8位二进制的字节 xff1b 输出字节的十六进制形式的字符串验证后确实是 String s 61
  • Java基础

    Java语言的一些基础知识 xff0c 需要常记在心 xff0c 但是好记性不如烂笔头 就记在这吧 final 修饰的变量不能被赋值 xff0c 可以在定义的同时赋值 final 修饰的方法可以被继承 xff0c 不能被重写override
  • Java EE学习

    遇见的问题 servlet访问出现404 xff0c jsp正常访问 java jdk1 8 eclipse2018 12 4 10 0 Dynamic web module version 4 0 Tomcat9 0 经过一番搜索 xff
  • 手把手教你Asp.net三层架构

    首先简单介绍下三层乃至多层架构 xff08 高手跳过 xff09 xff1a BLL 就是business Logic laywer xff08 业务逻辑层 xff09 他只负责向数据提供者也就是DAL调用数据 然后传递给客户程序也就是UI
  • 深奥的补码

    上学的时候汇编语言中有原码 反码 补码 考试的时候经常考 xff0c 比较好的办法就是记住他们的转换规则 xff0c 但是虽然记住转换规则 xff0c 考试也考不差 xff0c 心头却始终有朵乌云挥之不去 xff0c 令人异常纠结 xff0
  • 详解Android Intent

    一 Intent 作用 Intent被译作意图 xff0c 其实还是很能传神的 xff0c Intent期望做到的 xff0c 就是把实现者和调用者完全解耦 xff0c 调用者专心将以意图描述清晰 xff0c 发送出去 xff0c 就可以梦
  • 如何检索Android设备的唯一ID

    Android的开发者在一些特定情况下都需要知道手机中的唯一设备ID 关于本文档 Android 的开发者在一些特定情况下都需要知道手机中的唯一设备 ID 例如 xff0c 跟踪应用程序的安装 xff0c 生成用于复制保护的 DRM 时需要