虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Android编程 > 详解Android MacAddress 适配心得

详解Android MacAddress 适配心得
类别:Android编程   作者:码皇   来源:互联网   点击:

本篇文章主要介绍了详解Android MacAddress 适配心得,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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地址。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关热词搜索: Android MacAddress 适配 Android MacAddr