如何檢索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. String imeistring = null;  
  6. String imsistring = null;  
  7.     {  
  8.         TelephonyManager    telephonyManager;  
  9.         telephonyManager =  
  10.             (TelephonyManager) getSystemService( Context.TELEPHONY_SERVICE );  
  11.   
  12.         /* 
  13.          * getDeviceId() function Returns the unique device ID. 
  14.          * for example,the IMEI for GSM and the MEID or ESN for CDMA phones. 
  15.          */                                                                
  16.         imeistring = telephonyManager.getDeviceId();  
  17.         /* 
  18.         * getSubscriberId() function Returns the unique subscriber ID, 
  19.         * for example, the IMSI for a GSM phone. 
  20.         */  
  21.         imsistring = telephonyManager.getSubscriberId();  
  22.     }  

如要只讀取手機的狀態,則需添加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 plaincopy
  1. <span style="font-size:16px;">import java.lang.reflect.Method;  
  2.   
  3. String serialnum = null;  
  4.   
  5.     try {  
  6.         Class<?> c = Class.forName("android.os.SystemProperties");  
  7.         Method get = c.getMethod("get", String.class, String.class );  
  8.         serialnum = (String)(   get.invoke(c, "ro.serialno""unknown" )  );  
  9.     } catch (Exception ignored) {                                
  10.     }</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 plaincopy
  1. <span xmlns="http://www.w3.org/1999/xhtml" style="font-size:12px;color:#000000;"><strong xmlns="http://www.w3.org/1999/xhtml"><span xmlns="http://www.w3.org/1999/xhtml" style="">package com.deviceid;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.Context;  
  7. import android.os.Bundle;  
  8. import android.provider.Settings;  
  9. import android.telephony.TelephonyManager;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13. import android.widget.TextView;  
  14.   
  15. public class ReadDeviceID extends Activity {  
  16.   
  17.     Button bt;  
  18.     TextView idView;  
  19.     /** Called when the activity is first created. */  
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.main);  
  24.         bt=(Button)findViewById(R.id.button1);  
  25.         idView=(TextView)findViewById(R.id.textView1);  
  26.         bt.setOnClickListener(new OnClickListener() {  
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 String imeistring=null;  
  30.                 String imsistring=null;  
  31.                 TelephonyManager   telephonyManager =  
  32.                     ( TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE );  
  33.                 /* 
  34.                  * getDeviceId() function Returns the unique device ID. 
  35.                  * for example,the IMEI for GSM and the MEID or ESN for CDMA phones. 
  36.                  */  
  37.                 imeistring = telephonyManager.getDeviceId();  
  38.                 idView.append("IMEI No : "+imeistring+"\n");  
  39.                 /* 
  40.                  * getSubscriberId() function Returns the unique subscriber ID, 
  41.                  * for example, the IMSI for a GSM phone. 
  42.                  */  
  43.                 imsistring = telephonyManager.getSubscriberId();  
  44.                 idView.append("IMSI No : "+imsistring+"\n");  
  45.                 /* 
  46.                  * System Property ro.serialno returns the serial number as unique number 
  47.                  * Works for Android 2.3 and above         
  48.                  */  
  49.                 String hwID = android.os.SystemProperties.get("ro.serialno""unknown");  
  50.                 idView.append( "hwID : " + hwID + "\n" );  
  51.                 String serialnum = null;  
  52.                 try {  
  53.                     Class<?> c = Class.forName("android.os.SystemProperties");  
  54.                     Method get = c.getMethod("get", String.class, String.class );  
  55.                     serialnum = (String)(   get.invoke(c, "ro.serialno""unknown" )  );  
  56.                     idView.append( "serial : " + serialnum + "\n" );  
  57.                 } catch (Exception ignored) {  
  58.                 }  
  59.                 String serialnum2 = null;  
  60.                 try {  
  61.                     Class myclass = Class.forName( "android.os.SystemProperties" );  
  62.                     Method[] methods = myclass.getMethods();  
  63.                     Object[] params = new Object[] { new String( "ro.serialno" ) , new String("Unknown" ) };  
  64.                     serialnum2 = (String)(methods[2].invoke( myclass, params ));  
  65.                     idView.append( "serial2 : " + serialnum2 + "\n" );  
  66.                 }catch (Exception ignored) {  
  67.                       
  68.                 }  
  69.                 /* 
  70.                  * Settings.Secure.ANDROID_ID returns the unique DeviceID 
  71.                  * Works for Android 2.2 and above         
  72.                  */  
  73.                 String androidId = Settings.Secure.getString(getContentResolver(),  
  74.                         Settings.Secure.ANDROID_ID);  
  75.                 idView.append( "AndroidID : " + androidId + "\n" );  
  76.             }  
  77.         });  
  78.     }  
  79. } </span></strong></span>  

: SystemProperties.java

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

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章