获取MAC 地址
获取Wi-Fi MAC
直接上代码:
public static String getMacAddrByIp() {
String strMacAddr = null;
try {
// 获得IpD地址
InetAddress ip = getLocalInetAddress();
byte[] b = NetworkInterface.getByInetAddress(ip)
.getHardwareAddress();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < b.length; i++) {
if (i != 0) {
buffer.append(':');
}
String str = Integer.toHexString(b[i] & 0xFF);
buffer.append(str.length() == 1 ? 0 + str : str);
}
strMacAddr = buffer.toString().toUpperCase();
} catch (Exception e) {
}
return strMacAddr;
}
/**
* 获取移动设备本地IP
*
* @return
*/
public static InetAddress getLocalInetAddress() {
InetAddress ip = null;
try {
// 列举
Enumeration<NetworkInterface> en_netInterface = NetworkInterface
.getNetworkInterfaces();
while (en_netInterface.hasMoreElements()) {// 是否还有元素
NetworkInterface ni = (NetworkInterface) en_netInterface
.nextElement();// 得到下一个元素
Enumeration<InetAddress> en_ip = ni.getInetAddresses();// 得到一个ip地址的列举
while (en_ip.hasMoreElements()) {
ip = en_ip.nextElement();
if (!ip.isLoopbackAddress()
/* && ip.getHostAddress().indexOf(":") == -1*/)
break;
else
ip = null;
}
if (ip != null) {
break;
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return ip;
}
ip.getHostAddress().indexOf(":") == -1 这个注释掉就是不取,IPv6的地址。
以上代码注意一个问题:就是如果使用的流量网络,就是IP是流量网络给予的,那么会取成流量网络的MAC。这个MAC是会变更。
如果需要单独取Wi-Fi的MAC,就需要下面的方法。
NetworkInterface 这个类会把机器所有涉及到网络的东西都取出来。
public static String getMachineHardwareAddress() {
Enumeration<NetworkInterface> interfaces = null;
try {
interfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
e.printStackTrace();
}
String hardWareAddress = null;
NetworkInterface iF = null;
if (interfaces == null) {
return null;
}
while (interfaces.hasMoreElements()) {
iF = interfaces.nextElement();
/*List<InetAddress> list = Collections.list(iF.getInetAddresses());
for (InetAddress ip : list) {
输出这个设备下面的所有IP,会有回路IP,127。0。0。0这种
}*/
try {
hardWareAddress = bytesToString(iF.getHardwareAddress());
/*if (hardWareAddress != null)
break;*/
} catch (SocketException e) {
e.printStackTrace();
}
}
return hardWareAddress;
}
上面的方法是取最后一个,需要的大家自己改。Wi-Fi的名字叫wlan0,有线的一般叫eth0.具体的看系统。这两个是不会变的,其他的会改变。
Android 10强制要求MAC是随机的,上面的方法取得也是随机的,真实的IP需要使用DevicePolicyManager.getWifiMacAddress(@NonNull ComponentName admin).这个权限基本没有,大家可以不用想了。
蓝牙(Bluetooth)MAC
蓝牙的只介绍高版本的,常规手法大家都知道的。
@TargetApi(23)
public static String getBluetoothAddressSdk23(BluetoothAdapter adapter) {
if (adapter == null) return null;
Class<? extends BluetoothAdapter> btAdapterClass = adapter.getClass();
try {
Class<?> btClass = Class.forName("android.bluetooth.IBluetooth");
Field bluetooth = btAdapterClass.getDeclaredField("mService");
bluetooth.setAccessible(true);
Method method = btClass.getMethod("getAddress");
Method method1 = bluetooth.get(adapter).getClass().getMethod("getAddress");
return (String) bluetooth.get(adapter).getClass().getMethod("getAddress").invoke(bluetooth.get(adapter));
} catch (Exception e) {
e.printStackTrace();
return adapter.getAddress();
}
}
注意上面的代码,method和method1。
public abstract java.lang.String android.bluetooth.IBluetooth.getAddress() throws android.os.RemoteException //method
public java.lang.String android.bluetooth.IBluetooth$Stub$Proxy.getAddress() throws android.os.RemoteException //method1
虽然不影响,但是能看出来具体的东东。
Android9,还是10以后,反射不行了,反射也是需要权限的.调用上面的代码会告诉你需要LOCAL_MAC_ADDRESS。这个权限是需要系统ID的。
以上,完毕。谢谢大家。