Android手機上擷取物理唯一標識碼

來源:互聯網
上載者:User

標籤:

最近在做項目的過程中需要唯一標識使用者的裝置,後台在做push notification的時候需要用到這個唯一的標識號。

首先我會想到的是裝置的device id,毫無疑問可以唯一標識裝置,第一個版本也正是這樣做的。國慶期間使用者的一封郵件讓哥很不淡定,因為需要拿到device id,所以必然要在AndroidManifest檔案中添加許可權

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

添加完這條許可權很自然的在使用者下載App的時候會提示以下許可權接受的列表:

OK。問題來了,使用者覺得這個東西比較敏感,我選擇不安裝你們的這個App,心中一萬隻羊駝在奔跑。

想想換換其他方式來實現這一需求吧。今天和大家總結分享下每種方式的利弊。

第一種方式:裝置的Device Id作為唯一標識

在AndroidManifest設定檔中添加許可權

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

具體擷取的方法如下,我是寫在工具類中的:

public static String getDeviceIdInfo(Context mContext) {        //String imei = ((TelephonyManager) mContext.getSystemService(mContext.TELEPHONY_SERVICE)).getDeviceId();        String imei = Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID);        return imei;    }

這種實現方式的缺點在於:

1.遇到安全警覺性比較高的使用者,我不接受這樣的許可權,不安裝你的App。

2.非手機裝置,如果只帶有Wifi的裝置或者音樂播放器沒有通話的硬體功能的話就沒有這個DEVICE_ID。

3.作為手機來講,IMEI是唯一的,它應該類似於359881030314356(除非你有一個沒有量產的手機(水貨)它可能有無效的IMEI,如:0000000000000)。說白了,如果只為了擷取它,沒有用到其他的通話功能,那這個許可權有點大才小用。

4.在少數的一些手機裝置上,該實現有漏洞,會返回垃圾,如:zeros或者asterisks的產品。

第二種方式:擷取MAC ADDRESS

我們也可以通過手機的Wifi或者藍牙裝置擷取MAC ADDRESS作為DEVICE ID,但是並不建議這麼做,因為並不是所有的裝置都有Wifi,並且,如果Wifi沒有開啟,那硬體裝置無法返回MAC ADDRESS.
The WLAN MAC Address string, 是另一個唯一ID。毫無疑問你需要在AndroidManifest檔案中添加如下許可權:

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

代碼中的實現:

WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();

Returns: 00:11:22:33:44:55 (這不是一個真實的地址。而且這個地址能輕易地被偽造。).WLan不必開啟,就可讀取些值。

第三種方式:BT MAC ADDRESS

只在有藍芽的裝置上運行。並且要加入android.permission.BLUETOOTH 許可權.

BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();

Returns: 43:25:78:50:93:38 . 藍芽沒有必要開啟,也能讀取。

第四種方式:Serial Number

裝有SIM卡的裝置可以通過getSystemService(Context.TELEPHONY_SERVIEC).getSimSerialNumber();擷取到
sim serial number。 注意對CDMA裝置,返回的是一個空值。
在Android 2.3可以通過android.os.Build.SERIAL擷取,非手機裝置可以通過該介面擷取。

第五種方式:ANDROID_ID

ANDROID_ID是裝置第一次啟動時產生和儲存的64bit的一個數,當裝置被wipe後該數重設
ANDROID_ID似乎是擷取Device ID的一個好選擇,但它也有缺陷:

它在Android <=2.1 or Android >=2.3的版本是可靠、穩定的,但在2.2的版本並不是100%可靠的
在主流廠商生產的裝置上,有一個很經常的bug,就是每個裝置都會產生相同的ANDROID_ID:9774d56d682e549c

具體擷取的方法:

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

第六種方式:Installtion ID : UUID

這種方式也正是我最後採用的一種方式。

以上幾種方式都有或多或少存在的一定的局限性或者bug,在這裡,有另外一種方式解決,就是使用UUID,該方法無需訪問裝置的資源,也跟裝置類型無關。
這種方式是通過在程式安裝後第一次運行後產生一個ID實現的,但該方式跟裝置唯一標識不一樣,它會因為不同的應用程式而產生不同的ID,而不是裝置唯一ID。

因此經常用來標識在某個應用中的唯一ID(即Installtion ID),或者跟蹤應用的安裝數量。

我在程式中建立了這麼一個工具類來擷取這個UUID

import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;import java.util.UUID;import android.content.Context;public class Installation {    private static String sID = null;    private static final String INSTALLATION = "INSTALLATION";    public synchronized static String id(Context context) {        if (sID == null) {              File installation = new File(context.getFilesDir(), INSTALLATION);            try {                if (!installation.exists())                    writeInstallationFile(installation);                sID = readInstallationFile(installation);            } catch (Exception e) {                throw new RuntimeException(e);            }        }        return sID;    }    private static String readInstallationFile(File installation) throws IOException {        RandomAccessFile f = new RandomAccessFile(installation, "r");        byte[] bytes = new byte[(int) f.length()];        f.readFully(bytes);        f.close();        return new String(bytes);    }    private static void writeInstallationFile(File installation) throws IOException {        FileOutputStream out = new FileOutputStream(installation);        String id = UUID.randomUUID().toString();        out.write(id.getBytes());        out.close();    }}

綜上所述,我還是比較推薦最後一種方式。如果還有別的實現方式大家可以留言一起學習討論。

Android手機上擷取物理唯一標識碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.