1. 程式人生 > >Android手機裝置唯一識別符號

Android手機裝置唯一識別符號

在Android App開發過程中有時需要確定手機裝置的唯一性。但是Android 手機裝置的唯一標識的獲取並不能保持每次都能獲取成功,因而無法保持手機的唯一性。Android手機獲取唯一標識一直沒有統一標準,每個公司都有自己的一套規則。首先說一下幾種比較常用的作為手機裝置唯一標識的:

  • IMEI
    範圍:只能支援擁有通話功能的裝置,對於平板不可以。
    永續性:返廠,資料擦除的時候不徹底,保留了原來的標識。
    許可權:需要許可權:Android.permission.READ_PHONE_STATE
    bug: 有些廠家的實現有bug,返回一些不可用的資料

  • Mac地址
    範圍:有支援無限上網的裝置
    許可權:需要ACCESS_WIFI_STATE許可權
    永續性:有些裝置沒有WiFi,或者藍芽,就不可以,如果WiFi沒有開啟,硬體也不會返回Mac地址,不建議使用

  • Android_ID
    範圍:所有Android系統裝置
    Bug:2.2(Froyo,8)版本系統會不可信,來自主要生產廠商的主流手機,至少有一個普遍發現的bug,這些有問題的手機相同的ANDROID_ID: 9774d56d682e549c但是如果返廠的手機,或者被root的手機,可能會變

  • Serial Number
    範圍:從android 2.3 (“Gingerbread”)開始可用,可以通過android.os.Build.SERIAL獲取,對於沒有通話功能的裝置,它會返回一個唯一的device ID,

驗證在手機Wifi關閉情況下獲取標識的情況:

品牌 型號 系統版本 IMEI Mac Android id Serial Number
Vivo X5Pro V 5.0.2
Oppo R7s 4.4.4
華為 ALE-UL00 5.0.2
小米 Redmi note2 5.0.2
小米 4LTE 6.0.1
魅族 M2 note 5.1
HTC m8sw 5.0.2
華為 MT7-TL10 5.1.1
三星 SM-G9200 6.0.1
  • 生成方案
    常見手機裝置唯一表示碼選擇上面的一種或幾種,但是部分手機的Mac碼的獲取會與Wifi狀態有關,改動較大因此捨棄Mac碼。挑選出IMEI碼、Android ID、Serial Number拼接成一個字串,然後通過MD5加密生成一個唯一標識。

IMEI碼、Android ID、Serial Number的獲取:

String macId = getMacAddress(this);
Log.e("yushan", "macId:::" + macId);

String IMIESId = getIMIEStatus(this);
Log.e("yushan", "IMIESId:::" + IMIESId);

String AndroidId = getAndroidId(this);
Log.e("yushan", "AndroidId:::" + AndroidId);

String AndroidSerial = getAndroidSerial();
Log.e("yushan", "AndroidSerial:::" + AndroidSerial);

public static String getMacAddress(Context context) {
    String macAddress = null;
    WifiInfo wifiInfo = getWifiInfo(context);
    if (wifiInfo != null) {
        macAddress = wifiInfo.getMacAddress();
    }
    return macAddress;
}

/**
 * 獲取WifiInfo
 */
public static WifiInfo getWifiInfo(Context context) {
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    WifiInfo info = null;
    if (null != wifiManager) {
        info = wifiManager.getConnectionInfo();
    }
    return info;
}

private static String getIMIEStatus(Context context) {
    String deviceId = "";
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);

    } else {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        deviceId = tm.getDeviceId();

    }
    return deviceId;
}

private static String getAndroidId(Context context) {
    String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    return androidId;
}

private String getAndroidSerial() {
    String serialNum = Build.SERIAL;
    return serialNum;
}

通過MD5加密生成唯一標識:

String pseudoId = "21" + // 加鹽
        getIMIEStatus(this) + // IMEI碼
        getAndroidSerial() + // Serial num
        getAndroidId(this); // Android Id

String md5Str = makeMD5(pseudoId);
Log.e("yushan", "md5Str:::" + md5Str);

// MD5加密
public static String makeMD5(String password) {
    try {
        // 生成一個MD5加密計算摘要
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 計算md5函式
        md.update(password.getBytes());
        // digest()最後確定返回md5 hash值,返回值為8為字串。因為md5 hash值是16位的hex值,實際上就是8位的字元
        // BigInteger函式則將8位的字串轉換成16位hex值,用字串來表示;得到字串形式的hash值
        return new BigInteger(1, md.digest()).toString(16);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return password;
}

關於Android 手機裝置唯一識別符號的生成就到這裡,希望這篇部落格能夠為小夥伴們提供一些幫助。