详解Android MacAddress 适配心得
程序员文章站
2023-12-15 10:18:16
android 6.0以下mac地址获取
我们获取mac地址一般都是这样写的:
/**
* 根据wifi信息获取本地mac
* @param...
android 6.0以下mac地址获取
我们获取mac地址一般都是这样写的:
/** * 根据wifi信息获取本地mac * @param context * @return */ public static string getlocalmacaddressfromwifiinfo(context context){ wifimanager wifi = (wifimanager) context.getsystemservice(context.wifi_service); wifiinfo winfo = wifi.getconnectioninfo(); string mac = winfo.getmacaddress(); return mac; }
android 6.0及以上、7.0以下
android 6.0以后 将不再能通过 wifimanager 获取mac,获取到的mac将是固定的:02:00:00:00:00:00 。
然而我开发的sdk就是通过wifimanager获取的mac。
android sdk后来做了6.0适配,通过cat /sys/class/net/wlan0/address,可以在6.0上获取mac地址。
/** * 获取mac地址 * @param context * @return */ public static string getmacaddress(context context){ //如果是6.0以下,直接通过wifimanager获取 if(build.version.sdk_int<build.version_codes.m){ string macaddress0 = getmacaddress0(context); if(!textutils.isempty(macaddress0)){ return macaddress0; } } 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) { log.e("----->" + "netinfomanager", "getmacaddress:" + ex.tostring()); } if (macserial == null || "".equals(macserial)) { try { return loadfileasstring("/sys/class/net/eth0/address") .touppercase().substring(0, 17); } catch (exception e) { e.printstacktrace(); log.e("----->" + "netinfomanager", "getmacaddress:" + e.tostring()); } } return macserial; } private static string getmacaddress0(context context) { if (isaccesswifistateauthorized(context)) { wifimanager wifimgr = (wifimanager) context .getsystemservice(context.wifi_service); wifiinfo wifiinfo = null; try { wifiinfo = wifimgr.getconnectioninfo(); return wifiinfo.getmacaddress(); } catch (exception e) { log.e("----->" + "netinfomanager", "getmacaddress0:" + e.tostring()); } } return ""; } /** * check whether accessing wifi state is permitted * * @param context * @return */ private static boolean isaccesswifistateauthorized(context context) { if (packagemanager.permission_granted == context .checkcallingorselfpermission("android.permission.access_wifi_state")) { log.e("----->" + "netinfomanager", "isaccesswifistateauthorized:" + "access wifi state is enabled"); return true; } else return false; } private static string loadfileasstring(string filename) throws exception { filereader reader = new filereader(filename); string text = loadreaderasstring(reader); reader.close(); return text; } private 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(); }
android 7.0及以上
android 7.0 后,通过上述适配的方法,将获取不到mac地址。
经过调研和测试,7.0上仍有办法回去mac地址:
(1)通过ip地址来获取绑定的mac地址
/** * 获取移动设备本地ip * @return */ private 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 * @return */ private static string getlocalipaddress() { try { for (enumeration<networkinterface> en = networkinterface .getnetworkinterfaces(); en.hasmoreelements();) { networkinterface intf = en.nextelement(); for (enumeration<inetaddress> enumipaddr = intf .getinetaddresses(); enumipaddr.hasmoreelements();) { inetaddress inetaddress = enumipaddr.nextelement(); if (!inetaddress.isloopbackaddress()) { return inetaddress.gethostaddress().tostring(); } } } } catch (socketexception ex) { ex.printstacktrace(); } return null; } /** * 根据ip地址获取mac地址 * @return */ public static string getmacaddress(){ 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; }
(2)扫描各个网络接口获取mac地址
/** * 获取设备hardwareaddress地址 * @return */ public static string getmachinehardwareaddress(){ enumeration<networkinterface> 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) break; } catch (socketexception e) { e.printstacktrace(); } } 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(); }
(3)通过busybox获取本地存储的mac地址
/** * 根据busybox获取本地mac * @return */ public static string getlocalmacaddressfrombusybox(){ string result = ""; string mac = ""; result = callcmd("busybox ifconfig","hwaddr"); //如果返回的result == null,则说明网络不可取 if(result==null){ return "网络异常"; } //对该行数据进行解析 //例如:eth0 link encap:ethernet hwaddr 00:16:e8:3e:df:67 if(result.length()>0 && result.contains("hwaddr")==true){ mac = result.substring(result.indexof("hwaddr")+6, result.length()-1); result = mac; } return result; } private static string callcmd(string cmd,string filter) { string result = ""; string line = ""; try { process proc = runtime.getruntime().exec(cmd); inputstreamreader is = new inputstreamreader(proc.getinputstream()); bufferedreader br = new bufferedreader (is); while ((line = br.readline ()) != null && line.contains(filter)== false) { result += line; } result = line; } catch(exception e) { e.printstacktrace(); } return result; }
对比效果截图
上述三种方法,对比我开发的sdk现在使用的方法以及通过wifimanager获取mac地址的方法,效果如下(7.0设备有限,只覆盖部分机型):
结论
通过上述对比,通过ip获取mac地址和扫描网络接口获取mac结合使用,可以达到准确的效果。
通过ip获取的mac地址优先级高,只有在它获取不到的情况下,再使用扫描网络接口获取的mac地址。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。