由于项目开发需要获取设备的mac地址,因此查阅了Android获取mac地址相关信息,本篇博客转载自《Android获取Mac地址-适配所有版本》,并在此基础上进行进一步整理。
根据Android版本,可将Android获取mac的方法分为三类: Android 6.0以下,Android 6.0以上、7.0以下, Android 7.0以上。
1. Android 6.0以下
在Android 6.0以下,首先需要获取如下权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE">
获取mac地址的方法如下:
/**
* Android 6.0 之前(不包括6.0)获取mac地址
* 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
* @param context * @return
*/
public static String getMacDefault(Context context) {
String mac = "";
if (context == null) {
return mac;
}
WifiManager wifi = (WifiManager)context.applicationContext.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = null;
try {
info = wifi.getConnectionInfo();
} catch (Exception e) {
e.printStackTrace();
}
if (info == null) {
return null;
}
mac = info.getMacAddress();
if (!TextUtils.isEmpty(mac)) {
mac = mac.toUpperCase(Locale.ENGLISH);
}
return mac;
}
2.Android 6.0以上、7.0以下
android 6.0以后 将不再能通过 wifimanager 获取mac,获取到的mac将是固定的:02:00:00:00:00:00 。android sdk后来做了6.0适配,通过cat /sys/class/net/wlan0/address,可以在6.0上获取mac地址。
获取mac地址的方法如下:
/**
* Android 6.0-Android 7.0 获取mac地址
*/
public static String getMacAddress() {
String macSerial = null;
String str = "";
try {
Process pp = Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address");
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
while (null != str) {
str = input.readLine();
if (str != null) {
macSerial = str.trim();//去空格
break;
}
}
} catch (IOException ex) {
// 赋予默认值
ex.printStackTrace();
}
return macSerial;
}
3.Android 7.0以上
android 7.0 后,通过上述适配的方法,将获取不到mac地址。
经过调研和测试,7.0上仍有办法获取mac地址:
总共分为三种方式:
(1)通过ip地址来获取绑定的mac地址
(2)扫描各个网络接口获取mac地址
(3)通过busybox获取本地存储的mac地址
以下为通过(2)方法获取mac地址,其他方法请参考原博客:
/**
* Android 7.0之后获取Mac地址
* 遍历循环所有的网络接口,找到接口是 wlan0
* 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
* @return
*/
public static String getMacFromHardware() {
try {
Enumeration<NetworkInterface> all =
Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.name.equals("wlan0", ignoreCase = true))
continue;
Byte macBytes[] = nif.getHardwareAddress()
if (macBytes == null) return ""
StringBuilder res1 = new StringBuilder();
for (Byte b : macBytes) {
res1.append(String.format("%02X:", b))
}
if (!TextUtils.isEmpty(res1)) {
res1.deleteCharAt(res1.length - 1)
}
return res1.toString()
}
} catch (e: Exception) {
e.printStackTrace()
}
return ""
}
最后,将三个方法整合,就能适配所有Android版本了:
/**
* 获取mac地址(适配所有Android版本)
* @return
*/
fun getMac(context: Context): String? {
String mac: String? = ""
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
mac = getMacDefault(context)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
mac = getMacAddress()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mac = getMacFromHardware()
}
return mac
}