1.mac 地址,在 Android 6.0(API 级别 23)及更高版本中,本地设备 MAC 地址(例如 WLAN 和蓝牙)无法通过第三方 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手机有效:

12
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); String szImei = TelephonyMgr.getDeviceId();

采用此种方法,需要在AndroidManifest.xml中加入一个许可:android.permission.READ_PHONE_STATE,并且用户应当允许安装此应用。作为手机来讲,IMEI是唯一的,它应该类似于 359881030314356(除非你有一个没有量产的手机(水货)它可能有无效的IMEI,如:0000000000000)。

4.Pseudo-Unique ID, 这个在任何Android手机中都有效
有一些特殊的情况,一些如平板电脑的设置没有通话功能,或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的(因为如果两个手机应用了同样的硬件以及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是指在一台机器上生成的数字,它保证对在 同一时空中 的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字.

总结:个人感觉从上面的内容看,方法四 更好一些,虽然现在项目用的是mac 地址,后台要mac 给他mac 就是了,不想多BB。感觉移动端还是有点苦逼的,后台不需要了解移动端,前端更不必,但移动端却要要求懂后台和前端,还要搞jni +c 。立个flag 总有一天,前端,后台,移动端 全自己做了

更多相关文章

  1. *.android.com上不去的解决方法
  2. Android中Intent传递Java对象的方法
  3. Android(安卓)Tabhost使用方法详解
  4. 【Android】深入理解Android中的自定义属性
  5. 获取手机的视频和图片的缩略图
  6. Android(安卓)骁龙Camera拍照流程梳理
  7. 简单的Android之apk包反编译方法
  8. ListView的item高度调整
  9. Android(安卓)API Demo实例解析

随机推荐

  1. 【Android】TextView常用属性
  2. Android之TableLayout布局
  3. Android中attrs.xml文件的使用详解
  4. Android截屏浅析
  5. Mac下发布Unity3d中Android平台下出现“a
  6. Android之常用类型转换
  7. android 导入工程报错:Unable to resolve
  8. Android解析服务器端发来的xml数据
  9. android控件注意点(一)
  10. 利用Android中的SQLite进行CRUD