Androidユニーク識別コードノート

9935 ワード

1.macアドレス、Android 6.0(APIレベル23)以降のバージョンでは、ローカルデバイスMACアドレス(WLANやBluetoothなど)はサードパーティAPIから取得できません.WifiInfo.getMacAddress()メソッドおよびBluetoothAdapter.getDefaultAdapter().getAddress()メソッドは、いずれも02:00:00:00:00:00,を返しますが、他の方法で取得できます.6.0,7.0デバイスで入手できる有効な方法を次に示します.
public final class DeviceUtils {

    private DeviceUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }



    /**
     * Return version code of device's system.
     *
     * @return version code of device's system
     */
    public static int getSDKVersionCode() {
        return Build.VERSION.SDK_INT;
    }

    /**
     * Return the android id of device.
     *
     * @return the android id of device
     */
    @SuppressLint("HardwareIds")
    public static String getAndroidID() {
        return Settings.Secure.getString(
                Utils.getApp().getContentResolver(),
                Settings.Secure.ANDROID_ID
        );
    }

    /**
     * Return the MAC address.
     * 

Must hold * {@code }, * {@code }

* * @return the MAC address */ @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET}) public static String getMacAddress() { String macAddress = getMacAddressByWifiInfo(); if (!"02:00:00:00:00:00".equals(macAddress)) { return macAddress; } macAddress = getMacAddressByNetworkInterface(); if (!"02:00:00:00:00:00".equals(macAddress)) { return macAddress; } macAddress = getMacAddressByInetAddress(); if (!"02:00:00:00:00:00".equals(macAddress)) { return macAddress; } macAddress = getMacAddressByFile(); if (!"02:00:00:00:00:00".equals(macAddress)) { return macAddress; } return "please open wifi"; } @SuppressLint({"HardwareIds", "MissingPermission"}) private static String getMacAddressByWifiInfo() { try { Context context = Utils.getApp().getApplicationContext(); WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (wifi != null) { WifiInfo info = wifi.getConnectionInfo(); if (info != null) return info.getMacAddress(); } } catch (Exception e) { e.printStackTrace(); } return "02:00:00:00:00:00"; } private static String getMacAddressByNetworkInterface() { try { Enumeration nis = NetworkInterface.getNetworkInterfaces(); while (nis.hasMoreElements()) { NetworkInterface ni = nis.nextElement(); if (ni == null || !ni.getName().equalsIgnoreCase("wlan0")) continue; byte[] macBytes = ni.getHardwareAddress(); if (macBytes != null && macBytes.length > 0) { StringBuilder sb = new StringBuilder(); for (byte b : macBytes) { sb.append(String.format("%02x:", b)); } return sb.substring(0, sb.length() - 1); } } } catch (Exception e) { e.printStackTrace(); } return "02:00:00:00:00:00"; } private static String getMacAddressByInetAddress() { try { InetAddress inetAddress = getInetAddress(); if (inetAddress != null) { NetworkInterface ni = NetworkInterface.getByInetAddress(inetAddress); if (ni != null) { byte[] macBytes = ni.getHardwareAddress(); if (macBytes != null && macBytes.length > 0) { StringBuilder sb = new StringBuilder(); for (byte b : macBytes) { sb.append(String.format("%02x:", b)); } return sb.substring(0, sb.length() - 1); } } } } catch (Exception e) { e.printStackTrace(); } return "02:00:00:00:00:00"; } private static InetAddress getInetAddress() { try { Enumeration nis = NetworkInterface.getNetworkInterfaces(); while (nis.hasMoreElements()) { NetworkInterface ni = nis.nextElement(); // To prevent phone of xiaomi return "10.0.2.15" if (!ni.isUp()) continue; Enumeration addresses = ni.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress inetAddress = addresses.nextElement(); if (!inetAddress.isLoopbackAddress()) { String hostAddress = inetAddress.getHostAddress(); if (hostAddress.indexOf(':') < 0) return inetAddress; } } } } catch (SocketException e) { e.printStackTrace(); } return null; } private static String getMacAddressByFile() { ShellUtils.CommandResult result = ShellUtils.execCmd("getprop wifi.interface", false); if (result.result == 0) { String name = result.successMsg; if (name != null) { result = ShellUtils.execCmd("cat /sys/class/net/" + name + "/address", false); if (result.result == 0) { String address = result.successMsg; if (address != null && address.length() > 0) { return address; } } } } return "02:00:00:00:00:00"; }

2.android_Idは、Android 8.0(APIレベル26)以降で、SSAIDは、同じ開発者によって署名された鍵によって署名されたアプリケーション間で共通の識別子を提供する.これにより、ユーザーがアカウントにログインする必要がなく、これらのアプリケーション間でステータスを共有できます.これは公式サイトの翻訳で、本当にどういう意味か分かりません!出荷時の設定を復元するとこの値が変更され、nullを取得したデバイスがあることがわかります.
    @SuppressLint("HardwareIds")
    public static String getAndroidID() {
        return Settings.Secure.getString(
                Utils.getApp().getContentResolver(),
                Settings.Secure.ANDROID_ID
        );
    }

次の内容は次のとおりです.http://blog.rcant.com/2018/05/02/android/android_uuid_get/
3.The IMEI:Android携帯電話のみ有効:
1
2
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); 
String szImei = TelephonyMgr.getDeviceId();

この方法を採用するにはAndroidManifestが必要である.xmlにライセンスを追加:android.permission.READ_PHONE_STATEは、ユーザがアプリケーションのインストールを許可しなければならない.携帯電話としては、IMEIが唯一であり、359881030314356に似ているはずです(量産されていない携帯電話(水産物)がない限り、無効なIMEIがある可能性があります.例えば、00000000億円).
4.Pseudo-Unique ID、これはいかなるAndroid携帯電話の中ですべて有効でいくつかの特殊な情況があって、いくつか例えばタブレットの設置は通話機能がなくて、あるいはあなたはREADに参加したくないですPHONE_STATE許可.唯一のシリアル番号のようなものを手に入れたいと思っていますこの場合、ROMバージョン、メーカー、CPUモデル、その他のハードウェア情報を取り出すことで実現できます.このように計算されたIDは唯一ではありません(2つの携帯電話に同じハードウェアとRomミラーが適用されている場合).しかし、このような状況が発生する可能性は基本的に無視できることが理解されるべきだ.これを実現するには、Buildクラスを使用します.
ほとんどのBuildメンバーは文字列形式であり、長さ情報のみを取得します.13個の数字を取り、前に「35」を付けます.これでこのIDは15ビットのIMEIと同じように見えます
String m_szDevIDShort = "35" + //we make this look like a valid IMEI 

Build.BOARD.length()%10 + 
Build.BRAND.length()%10 + 
Build.CPU_ABI.length()%10 + 
Build.DEVICE.length()%10 + 
Build.DISPLAY.length()%10 + 
Build.HOST.length()%10 + 
Build.ID.length()%10 + 
Build.MANUFACTURER.length()%10 + 
Build.MODEL.length()%10 + 
Build.PRODUCT.length()%10 + 
Build.TAGS.length()%10 + 
Build.TYPE.length()%10 + 
Build.USER.length()%10 ; //13 digits

5.パッチ生成UUID
//         
 public String getPhoneSign(){
   StringBuilder deviceId = new StringBuilder();
   //     
   deviceId.append("a");
   try {
    //IMEI(imei)
    TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
    String imei = tm.getDeviceId();
    if(!TextUtils.isEmpty(imei)){
     deviceId.append("imei");
     deviceId.append(imei);
     return deviceId.toString();
    }
    //   (sn)
    String sn = tm.getSimSerialNumber();
    if(!TextUtils.isEmpty(sn)){
     deviceId.append("sn");
     deviceId.append(sn);
     return deviceId.toString();
    }
    //       ,      id:   
    String uuid = getUUID();
    if(!TextUtils.isEmpty(uuid)){
     deviceId.append("id");
     deviceId.append(uuid);
     return deviceId.toString();
    }
   } catch (Exception e) {
    e.printStackTrace();
    deviceId.append("id").append(getUUID());
   }
   return deviceId.toString();
  }
/**
  *       UUID
  */
 private String uuid;
 public String getUUID(){
  SharedPreferences mShare = getSharedPreferences("uuid",MODE_PRIVATE);
  if(mShare != null){
   uuid = mShare.getString("uuid", "");
  }
  if(TextUtils.isEmpty(uuid)){
   uuid = UUID.randomUUID().toString();
   mShare.edit().putString("uuid",uuid).commit();
  }
  return uuid;
 }

UUIDとは、1台のマシンで生成された数字で、同じ時間に空中にいるすべてのマシンに対して唯一であることを保証します.通常、プラットフォームは生成されたAPIを提供します.オープンソフトウェア財団(OSF)が制定する標準計算に従って、イーサネットカードアドレス、ナノ秒級時間、チップIDコード、および多くの可能な数字が用いられる.
まとめ:个人的な感じは上の内容から见て、方法の4はもっと良くて、今プロジェクトはmacアドレスを使っていますが、バックグラウンドはmacを彼にmacをあげて、多くBBしたくありません.移動端はまだ少し苦しいと感じて、バックグラウンドは移動端を理解する必要はなくて、フロントエンドは更に必要ありませんが、移動端はバックグラウンドとフロントエンドを理解することを要求して、jni+cをします.flagを立てていつか、フロントエンド、バックグラウンド、モバイルエンドはすべて自分でやりました