• Android 如何检索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

    [java] view plaincopy
    1. import android.telephony.TelephonyManager;     
    2.    
    3. import android.content.Context;                                                        
    4.   
    5.    
    6.    
    7. String   imeistring = null;                                                           
    8.   
    9. String   imsistring = null;                                                                                        
    10.   
    11. {                                                                                      
    12.   
    13.     TelephonyManager    telephonyManager;                                              
    14.    
    15.                                                                                        
    16.   
    17.     telephonyManager =   
    18.   
    19.          ( TelephonyManager )getSystemService( Context.TELEPHONY_SERVICE );  
    20.    
    21.                        
    22.   
    23.     /* 
    24.   
    25.       * getDeviceId() function Returns the unique device ID. 
    26.   
    27.      * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.  
    28.  
    29.      */                                                                 
    30.   
    31.     imeistring = telephonyManager.getDeviceId();  
    32.    
    33.      
    34.   
    35.    /* 
    36.   
    37.     * getSubscriberId() function Returns the unique subscriber ID, 
    38.   
    39.  * for example, the IMSI for a GSM phone. 
    40.   
    41.  */  
    42.    
    43.    imsistring = telephonyManager.getSubscriberId();     
    44.   
    45. }  


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

    [java] view plaincopy
    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 plaincopy
    1. import java.lang.reflect.Method;                                    
    2.   
    3.    
    4.    
    5. String serialnum = null;                                                                                                                                          
    6.    
    7. try {                                                              
    8.   
    9.  Class<?> c = Class.forName("android.os.SystemProperties");   
    10.    
    11.  Method get = c.getMethod("get", String.class, String.class );       
    12.    
    13.  serialnum = (String)(   get.invoke(c, "ro.serialno""unknown" )  );     
    14.    
    15. }                                                                                  
    16.    
    17. catch (Exception ignored)                                                          
    18.    
    19. {                                
    20.    
    21. }  


     

    缺点

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

    ANDROID_ID

    说明

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

    [java] view plaincopy
    1. 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
    1. package com.deviceid;  
    2.    
    3.    
    4.    
    5. import java.lang.reflect.Method;  
    6.    
    7.    
    8.    
    9. import android.app.Activity;  
    10.    
    11. import android.content.Context;  
    12.    
    13. import android.os.Bundle;  
    14.    
    15. import android.provider.Settings;  
    16.    
    17. import android.telephony.TelephonyManager;  
    18.    
    19. import android.view.View;  
    20.    
    21. import android.view.View.OnClickListener;  
    22.    
    23. import android.widget.Button;  
    24.    
    25. import android.widget.TextView;  
    26.    
    27.    
    28.    
    29. public class ReadDeviceID extends Activity {  
    30.    
    31.    
    32.    
    33.  Button bt;  
    34.    
    35.  TextView idView;  
    36.    
    37.    
    38.    
    39.     /** Called when the activity is first created. */  
    40.    
    41.     @Override  
    42.    
    43.     public void onCreate(Bundle savedInstanceState) {  
    44.    
    45.         super.onCreate(savedInstanceState);  
    46.    
    47.         setContentView(R.layout.main);  
    48.    
    49.    
    50.    
    51.         bt=(Button)findViewById(R.id.button1);  
    52.    
    53.         idView=(TextView)findViewById(R.id.textView1);         
    54.   
    55.         bt.setOnClickListener(new OnClickListener() {     
    56.   
    57.  @Override  
    58.    
    59.  public void onClick(View v) {  
    60.    
    61.    String imeistring=null;      
    62.   
    63.               String imsistring=null;  
    64.    
    65.      
    66.   
    67.  TelephonyManager   telephonyManager =   
    68.    
    69. ( TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );  
    70.    
    71.          
    72.   
    73.             /* 
    74.   
    75.  * getDeviceId() function Returns the unique device ID. 
    76.   
    77.  * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.  
    78.  
    79.  */         
    80.   
    81.  imeistring = telephonyManager.getDeviceId();  
    82.    
    83.  idView.append("IMEI No : "+imeistring+" ");      
    84.    
    85.             /* 
    86.   
    87.              * getSubscriberId() function Returns the unique subscriber ID, 
    88.   
    89.              * for example, the IMSI for a GSM phone. 
    90.   
    91.              */                                                                                           
    92.    
    93.   imsistring = telephonyManager.getSubscriberId();                 
    94.    
    95.   idView.append("IMSI No : "+imsistring+" ");  
    96.    
    97.          
    98.    
    99.             /* 
    100.   
    101.   * System Property ro.serialno returns the serial number as unique number 
    102.   
    103.   * Works for Android 2.3 and above         
    104.   
    105.   */  
    106.    
    107.          
    108.    
    109.   String hwID = android.os.SystemProperties.get("ro.serialno""unknown");  
    110.    
    111.   idView.append( "hwID : " + hwID + " " );  
    112.    
    113.       String serialnum = null;       
    114.    
    115.   try {          
    116.    
    117.     Class<?> c = Class.forName("android.os.SystemProperties");                            
    118.    
    119.     Method get = c.getMethod("get", String.class, String.class );                  
    120.    
    121.                serialnum = (String)(   get.invoke(c, "ro.serialno""unknown" )  );  
    122.    
    123.      idView.append( "serial : " + serialnum + " " );  
    124.    
    125.          } catch (Exception ignored) {        
    126.    
    127.            }  
    128.    
    129.  String serialnum2 = null;  
    130.    
    131.            try {  
    132.    
    133.  Class myclass = Class.forName( "android.os.SystemProperties" );  
    134.    
    135.         Method[] methods = myclass.getMethods();  
    136.    
    137.         Object[] params = new Object[] { new String( "ro.serialno" ) , new String(   
    138.    
    139.               "Unknown" ) };           
    140.    
    141.          serialnum2 = (String)(methods[2].invoke( myclass, params ));           
    142.    
    143.             idView.append( "serial2 : " + serialnum2 + " " );  
    144.    
    145.            }catch (Exception ignored)  
    146.    
    147.  {         
    148.    
    149.  }    
    150.    
    151.    /* 
    152.   
    153.     * Settings.Secure.ANDROID_ID returns the unique DeviceID 
    154.   
    155.     * Works for Android 2.2 and above         
    156.   
    157.     */  
    158.    
    159.  String androidId = Settings.Secure.getString(getContentResolver(),   
    160.    
    161.                                                     Settings.Secure.ANDROID_ID);           
    162.    
    163.             idView.append( "AndroidID : " + androidId + " " );     
    164.    
    165.          }  
    166.    
    167.     });  
    168.    
    169.          
    170.    
    171.     }  
    172.    
    173. }  


    : SystemProperties.java

    [java] view plaincopy
    1. package android.os;  
    2.    
    3.    
    4.    
    5. /** 
    6.   
    7.  * Gives access to the system properties store. The system properties 
    8.   
    9.  * store contains a list of string key-value pairs. 
    10.   
    11.  * 
    12.   
    13.  * {@hide} 
    14.   
    15.  */  
    16.    
    17. public class SystemProperties  
    18.    
    19. {  
    20.    
    21.     public static final int PROP_NAME_MAX = 31;  
    22.    
    23.     public static final int PROP_VALUE_MAX = 91;  
    24.    
    25.     private static native String native_get(String key);  
    26.    
    27.     private static native String native_get(String key, String def);  
    28.    
    29.     private static native int native_get_int(String key, int def);  
    30.    
    31.     private static native long native_get_long(String key, long def);  
    32.    
    33.     private static native boolean native_get_boolean(String key, boolean def);  
    34.    
    35.     private static native void native_set(String key, String def);  
    36.    
    37.    
    38.    
    39.     /** 
    40.   
    41.      * Get the value for the given key. 
    42.   
    43.      * @return an empty string if the key isn't found 
    44.   
    45.      * @throws IllegalArgumentException if the key exceeds 32 characters 
    46.   
    47.      */  
    48.    
    49.     public static String get(String key) {  
    50.    
    51.         if (key.length() > PROP_NAME_MAX) {  
    52.    
    53.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
    54.    
    55.         }  
    56.    
    57.         return native_get(key);  
    58.    
    59.     }  
    60.    
    61.    
    62.    
    63.     /** 
    64.   
    65.      * Get the value for the given key. 
    66.   
    67.      * @return if the key isn't found, return def if it isn't null, or an empty string otherwise 
    68.   
    69.      * @throws IllegalArgumentException if the key exceeds 32 characters 
    70.   
    71.      */  
    72.    
    73.     public static String get(String key, String def) {  
    74.    
    75.         if (key.length() > PROP_NAME_MAX) {  
    76.    
    77.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
    78.    
    79.         }  
    80.    
    81.         return native_get(key, def);  
    82.    
    83.     }  
    84.    
    85.    
    86.    
    87.     /** 
    88.   
    89.      * Get the value for the given key, and return as an integer. 
    90.   
    91.      * @param key the key to lookup 
    92.   
    93.      * @param def a default value to return 
    94.   
    95.      * @return the key parsed as an integer, or def if the key isn't found or 
    96.   
    97.      *         cannot be parsed 
    98.   
    99.      * @throws IllegalArgumentException if the key exceeds 32 characters 
    100.   
    101.      */  
    102.    
    103.     public static int getInt(String key, int def) {  
    104.    
    105.         if (key.length() > PROP_NAME_MAX) {  
    106.    
    107.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
    108.    
    109.         }  
    110.    
    111.         return native_get_int(key, def);  
    112.    
    113.     }  
    114.    
    115.    
    116.    
    117.     /** 
    118.   
    119.      * Get the value for the given key, and return as a long. 
    120.   
    121.      * @param key the key to lookup 
    122.   
    123.      * @param def a default value to return 
    124.   
    125.      * @return the key parsed as a long, or def if the key isn't found or 
    126.   
    127.      *         cannot be parsed 
    128.   
    129.      * @throws IllegalArgumentException if the key exceeds 32 characters 
    130.   
    131.      */  
    132.    
    133.     public static long getLong(String key, long def) {  
    134.    
    135.         if (key.length() > PROP_NAME_MAX) {  
    136.    
    137.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
    138.    
    139.         }  
    140.    
    141.         return native_get_long(key, def);  
    142.    
    143.     }  
    144.    
    145.    
    146.    
    147.     /** 
    148.   
    149.      * Get the value for the given key, returned as a boolean. 
    150.   
    151.      * Values 'n', 'no', '0', 'false' or 'off' are considered false. 
    152.   
    153.      * Values 'y', 'yes', '1', 'true' or 'on' are considered true. 
    154.   
    155.      * (case insensitive). 
    156.   
    157.      * If the key does not exist, or has any other value, then the default 
    158.   
    159.      * result is returned. 
    160.   
    161.      * @param key the key to lookup 
    162.   
    163.      * @param def a default value to return 
    164.   
    165.      * @return the key parsed as a boolean, or def if the key isn't found or is 
    166.   
    167.      *         not able to be parsed as a boolean. 
    168.   
    169.      * @throws IllegalArgumentException if the key exceeds 32 characters 
    170.   
    171.      */  
    172.    
    173.     public static boolean getBoolean(String key, boolean def) {  
    174.    
    175.         if (key.length() > PROP_NAME_MAX) {  
    176.    
    177.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
    178.    
    179.         }  
    180.    
    181.         return native_get_boolean(key, def);  
    182.    
    183.     }  
    184.    
    185.    
    186.    
    187.     /** 
    188.   
    189.      * Set the value for the given key. 
    190.   
    191.      * @throws IllegalArgumentException if the key exceeds 32 characters 
    192.   
    193.      * @throws IllegalArgumentException if the value exceeds 92 characters 
    194.   
    195.      */  
    196.    
    197.     public static void set(String key, String val) {  
    198.    
    199.         if (key.length() > PROP_NAME_MAX) {  
    200.    
    201.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
    202.    
    203.         }  
    204.    
    205.         if (val != null && val.length() > PROP_VALUE_MAX) {  
    206.    
    207.             throw new IllegalArgumentException("val.length > " +  
    208.    
    209.                 PROP_VALUE_MAX);  
    210.    
    211.         }  
    212.    
    213.         native_set(key, val);  
    214.    
    215.     }  
    216.    
    217. }  


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

    [java] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2.    
    3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    4.    
    5.     android:orientation="vertical"  
    6.    
    7.     android:layout_width="fill_parent"  
    8.    
    9.     android:layout_height="fill_parent"  
    10.    
    11.     >  
    12.    
    13. <TextView   
    14.    
    15.     android:layout_width="fill_parent"  
    16.    
    17.     android:layout_height="wrap_content"  
    18.    
    19.     android:text="@string/hello"  
    20.    
    21.     />  
    22.    
    23. <Button  
    24.    
    25.     android:text="GetDeviceID"  
    26.    
    27.     android:id="@+id/button1"  
    28.    
    29.     android:layout_width="wrap_content"  
    30.    
    31.     android:layout_height="wrap_content">  
    32.    
    33. </Button>  
    34.    
    35. <TextView      
    36.    
    37.     android:id="@+id/textView1"     
    38.    
    39.     android:layout_width="fill_parent"  
    40.    
    41.     android:layout_height="wrap_content">  
    42.    
    43. </TextView>  
    44.    
    45. </LinearLayout>  


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

    [java] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2.    
    3. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    4.    
    5.       package="com.deviceid"  
    6.    
    7.       android:versionCode="1"  
    8.    
    9.       android:versionName="1.0">  
    10.    
    11.     <uses-sdk android:minSdkVersion="7" />  
    12.    
    13.    
    14.    
    15.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
    16.    
    17.         <activity android:name=".ReadDeviceID"  
    18.    
    19.                   android:label="@string/app_name">  
    20.    
    21.             <intent-filter>  
    22.    
    23.                 <action android:name="android.intent.action.MAIN" />  
    24.    
    25.                 <category android:name="android.intent.category.LAUNCHER" />  
    26.    
    27.             </intent-filter>  
    28.    
    29.         </activity>  
    30.    
    31.    
    32.    
    33.     </application>  
    34.    
    35.      
    36.   
    37.     <uses-permission  
    38.    
    39.             android:name="android.permission.READ_PHONE_STATE" >  
    40.    
    41.       </uses-permission>  
    42.    
    43.      
    44.    
    45. </manifest>  


     

    输出结果

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

  • 相关阅读:
    使用PullToRefresh实现下拉刷新和上拉加载
    Java RandomAccessFile用法
    Java_io体系之RandomAccessFile简介、走进源码及示例——20
    获取Android设备唯一标识码
    MQTT协议简记
    ORMLite学习入门笔记
    service的生命周期
    android广播(内部类)使用
    intent 几种用法
    intent.setFlags方法中的参数值含义
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469639.html
Copyright © 2020-2023  润新知