這真是在開發Android所使用的好文章!

my bible!

 

 

轉貼內容:

1. Device ID (IMEI/MEID)


Device ID 看得是各地電信商提供什麼系統,若是 GSM 所取出的編碼就是 IMEI;若是 CDMA 取出的就是 MEID 或 ESN。

表面上,這應該是設備中最穩定的識別碼,但仍是有諸多 Android 設備是沒有的,像在 2012 年剛上市的 Nexus 7 就只有出 WIFI 的版本,就取不到這個識別碼。像現行有的電視盒或是展場上採用 Android 的設備,可能就是只有 WIFI ,在這種狀況下,取出來的值就是 null。

另外,要取得這個值,所需要的權限得用到「READ_PHONE_STATE」,這個權限其實頗大的,當使用者在安裝時,就會看到這個 APP 會要到的權限是「讀取手機狀態」,以現在 Android 病毒亂竄的狀況下,使用者會對這個權限是有疑心的,也可能因為這樣就不裝了。下圖所示的內容分別是從 4.1.2 以及 4.4.2 的設備中擷出來的畫面。

在 activity 中

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = tm.getDeviceId();

需要在 Manifest 加上權限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

 

2. Subscriber ID


用戶唯一碼,若是 GSM 就是 IMSI 碼;若是使用者沒有插卡,這個值會為 null。而 CDMA 的卡片也取不到值。

和 1. 相同,這個權限需要用到「READ_PHONE_STATE」。

在 activity 中

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = tm.getDeviceId();

需要在 Manifest 加上權限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

 

3. Serial ID


這個識別碼是由不分大小寫的英文字母跟數字所組成。此識別碼對比 1 跟 2,他不用任何權限就可以使用,也的確是唯一碼。但他需要在 Android 2.3 以上的設備才能取得,也就是說,自己的 APP 若是從 2.3 開始支援,用這個值原則上是沒問題的。

if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
    String serial = Build.SERIAL;
}

 

4. MAC Address


設備網卡的編碼。這個在沒有 WIFI 的設備仍是取不到;除了前述問題,有可能會因為系統更新、重新設定、重新開機在還未連線的狀況下取不到的資料,所以也要小心。

在 activity 中

WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifi = wm.getConnectionInfo();
String macAddress = wifi.getMacAddress();

需要在 Manifest 加上權限

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

 

5. Bluetooth Address


藍芽的設備碼。沒有藍芽的設備取不到;

BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
String btAddress = (btAdapter != null) ? btAdapter.getAddress() : "";

需要在 Manifest 加上權限

<uses-permission android:name="android.permission.BLUETOOTH"/>

 

6. Android ID


這個 ID 的優點也是不需要任何權限,他是在設備出廠後第一次啟動時產生。

但是他在 2.2 以前是不可靠的,曾經有一批設備在出廠後,所產生的編號都是:9774d56d682e549c。

另外還有一個問題,當設備被執行「恢復原廠設定」時,這個 id 會被重新產生。

在 activity 中

String androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

 

7. UUID


這個 ID 並不是由設備自動產生,是開發者自行寫在 APP 程式中,而且必需是寫在程式一開始就一定會執行到的地方,並立即將之存於設備裡。其最大的缺點就是當 APP 被執行「清除資料」或是移除重裝後的 ID 都會重新產生。因為要存入設備中,所以需要有寫入的權限。

這個函式是 android 內建,依循 RFC 4122 的規範隨機產出一組編號。

  • API Level:1 (Android Document)
  • 權限需求:WRITE_EXTERNAL_STORAGE
  • Code:
String id = UUID.randomUUID().toString();

 

總結


最後歸納一下,各種識別碼可取出的 API 版本,以及可能遇到的問題:

  1. Device ID (IMEI/MEID)
    • API Level:1
    • Permission:READ_PHONE_STATE
    • 潛在問題:
      • 沒有 3G 介面的設備會取不到,如 Nexus 7 2012 WIFI only。
      • 要求的權限較大,可能會讓在意的使用者怯步。
  2. Subscriber ID
    • API Level:1
    • Permission:READ_PHONE_STATE
    • 潛在問題:
      • 和 Device ID 一樣,沒有 3G 介面一定會取不到。
      • 沒有插卡取不到。
      • CDMA 系統取不到。
      • 要求的權限較大,可能會讓在意的使用者怯步。
  3. Serial ID
    • API Level:9
    • Permission:無
    • 潛在問題:
      • 要版本 2.3 以上的手機才有值。
  4. MAC Address
    • API Level:1
    • Permission:ACCESS_WIFI_STATE
    • 潛在問題:
      • 有的設備沒有 WIFI。
      • 有可能因為沒有連線,而取不到值。
  5. Bluetooth Address
    • API Level:5
    • Permission:BLUETOOTH
    • 潛在問題:
      • 有的設備沒有藍芽。
      • 可能因為沒開啟,而拿不到值。
  6. Android ID
    • API Level:3
    • Permission:無
    • 潛在問題:
      • 有一批設備全部都會產生「9774d56d682e549c」。
      • 執行「恢復原廠設定」後,會重新產生一組。
  7. UUID
    • API Level:1
    • Permission:WRITE_EXTERNAL_STORAGE
    • 潛在問題:
      • 要自己寫演算法。要留意 APP 一被執行就要產生,並存在設備中,同時留意不會被重覆執行到。
      • 該 APP 被「清除資料」就會重新產生。
      • 該 APP 被移除重裝後,會重新產生。

 

來源:http://blog.mosil.biz/2014/05/android-device-id-uuid/

 

8月4日追加:

As of API 15 you can use the following method:

Try replacing your UUID with the return value of getUuids() method of BluetoothDevice class. What worked for me was something like this:

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);

The reason this works is that different devices support different UUIDs and by getting the UUIDs of the device using getUuids you are supporting all features and devices.

Another interesting new method (supported since API 14) is this: BluetoothHealth.getConnectionState

來源:http://stackoverflow.com/questions/3397071/service-discovery-failed-exception-using-bluetooth-on-android

查看原文 >>
相关文章