获取android设备mac,android获取设备mac地址(兼容6.0+版本)

最近接手一个新项目,该项目中一直使用getMacAddress获取设备的mac地址。我在实际测试中发现,小米4的手机该方法一直返回02:00:00:00:00:00。

查阅资料得知,android 6.0之后,官方加强了对访问硬件信息的管控。

To provide users with greater data protection, starting in this release, Android removes programmatic access to the device’s local hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods now return a constant value of 02:00:00:00:00:00.

To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions.

解决方法

使用Java获取设备网络设备信息的API:NetworkInterface.getNetworkInterfaces() 间接地获取到MAC地址。

具体代码如下:

public static String getLocalMacAddress(Context context) {

String mac;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

mac = getMachineHardwareAddress();

} else {

WifiManager wifi = (WifiManager) context

.getSystemService(Context.WIFI_SERVICE);

WifiInfo info = wifi.getConnectionInfo();

mac = info.getMacAddress().replace(":", "");

}

return mac;

}

/**

* 获取设备的mac地址和IP地址(android6.0以上专用)

* @return

*/

public static String getMachineHardwareAddress(){

Enumeration interfaces = null;

try {

interfaces = NetworkInterface.getNetworkInterfaces();

} catch (SocketException e) {

e.printStackTrace();

}

String hardWareAddress = null;

NetworkInterface iF = null;

while (interfaces.hasMoreElements()) {

iF = interfaces.nextElement();

try {

hardWareAddress = bytesToString(iF.getHardwareAddress());

if(hardWareAddress == null) continue;

} catch (SocketException e) {

e.printStackTrace();

}

}

if(iF != null && iF.getName().equals("wlan0")){

hardWareAddress = hardWareAddress.replace(":","");

}

return hardWareAddress ;

}

/***

* byte转为String

* @param bytes

* @return

*/

private static String bytesToString(byte[] bytes){

if (bytes == null || bytes.length == 0) {

return null ;

}

StringBuilder buf = new StringBuilder();

for (byte b : bytes) {

buf.append(String.format("%02X:", b));

}

if (buf.length() > 0) {

buf.deleteCharAt(buf.length() - 1);

}

return buf.toString();

}

但是在实际测试中,出现了一个兼容性问题。在华为荣耀8手机,android 7.0系统运行该代码出现如下异常。

d0082e8e2c8f?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

运行异常日志.png

该手机直接执行“adb shell cat /sys/class/net/wlan0/address”提示Permission Denied。找另外的小米手机6.0及7.0均可以执行该命令,且可以通过代码获取到Mac地址。到这里可以总结出因为华为荣耀8的7.0系统修改了要访问的文件权限,导致该错误。而通过Runtime执行su命令也会提示权限不足。

这种场景下,建议通过本文中提到的NetworkInterface.getNetworkInterfaces方法获取Mac地址。

执行shell脚本获取mac的主要代码如下:

/**

* 获取手机的MAC地址

* @return

*/

public String getMac(){

String str="";

String macSerial="";

try {

Process pp = Runtime.getRuntime().exec(

"cat /sys/class/net/wlan0/address ");

InputStreamReader ir = new InputStreamReader(pp.getInputStream());

LineNumberReader input = new LineNumberReader(ir);

for (; null != str;) {

str = input.readLine();

if (str != null) {

macSerial = str.trim();// 去空格

break;

}

}

} catch (Exception ex) {

ex.printStackTrace();

}

if (macSerial == null || "".equals(macSerial)) {

try {

return loadFileAsString("/sys/class/net/eth0/address")

.toUpperCase().substring(0, 17);

} catch (Exception e) {

e.printStackTrace();

}

}

return macSerial;

}

public static String loadFileAsString(String fileName) throws Exception {

FileReader reader = new FileReader(fileName);

String text = loadReaderAsString(reader);

reader.close();

return text;

}

public static String loadReaderAsString(Reader reader) throws Exception {

StringBuilder builder = new StringBuilder();

char[] buffer = new char[4096];

int readLength = reader.read(buffer);

while (readLength >= 0) {

builder.append(buffer, 0, readLength);

readLength = reader.read(buffer);

}

return builder.toString();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值