欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

详解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设备有限,只覆盖部分机型):

详解Android MacAddress 适配心得

结论

通过上述对比,通过ip获取mac地址和扫描网络接口获取mac结合使用,可以达到准确的效果。

通过ip获取的mac地址优先级高,只有在它获取不到的情况下,再使用扫描网络接口获取的mac地址。

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

上一篇:

下一篇: