關於本文檔 html
Android的開發者在一些特定狀況下都須要知道手機中的惟一設備ID。例如,跟蹤應用程序的安裝,生成用於複製保護的DRM時須要使用設備的惟一ID。在本文檔結尾處提供了做爲參考的示例代碼片斷。 java
範圍 android
本文提供有關如何讀取各類Android設備的 ID的介紹,用以使用標識號。本文假定用戶已經安裝了Android以及開發應用程序必要的工具。而且,本文假定用戶已瞭解Android的基本知識。 網絡
簡介在搭載Android操做系統的設備中,已經存在好幾種類型的設備標識號。先前的全部Android設備都具備電話功能,所以查找每部設備硬件惟一的IMEI,MEID,或ESN也很容易。但僅能使用Wifi的設備或音樂播放器沒有電話硬件,因此沒有這種類型的惟一標識號。本文闡述瞭如何讀取不一樣Android設備的標識號。檢索Android設備ID各類方式 app
如下是Android設備不一樣類型的識別設備ID。 ide
· 惟一編號(IMEI,MEID,ESN,IMSI) 工具
· MAC地址 佈局
· 序列號 ui
· 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" >
</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使用,請參考下面的代碼示例。
- <span style="font-size:16px;">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) {
- }</span>
缺點
序列號沒法在全部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
- <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;
-
- 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" );
- }
- });
- }
- } </span></strong></span>
類: 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>