2015-07-09 77 views
13

想要獲得Android M上的Wifi MAC地址的Android開發人員可能遇到了以下問題:獲取MAC地址的標準Android OS API返回假MAC地址(02:00:00:00:00:00)而不是真正的價值。如何在Android Marshmallow中獲取缺少的Wifi MAC地址?

正常方式獲得了WIFI MAC地址是如下:

final WifiManager wifiManager = (WifiManager) getApplication().getApplicationContext().getSystemService(Context.WIFI_SERVICE); 

final String wifiMACaddress = wifiManager.getConnectionInfo().getMacAddress(); 
+3

堆棧溢出用於編程問題。你的問題是什麼?如果您嘗試提供某種常見問題解答條目,請[請按照網站上的說明](https://stackoverflow.com/help/self-answer)提出問題,然後提供您自己的問題答案。 – CommonsWare

+0

看來,Mac地址是隨機的,即使你可以抓住它! https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id –

+0

[在Android 6.0中獲取MAC地址]的可能重複(http://stackoverflow.com/questions-33159224/getting-mac-address-in-android-6-0) – mhdjazmati

回答

7

解決!

的MAC地址仍然可以從路徑抓起:

"/sys/class/net/" + networkInterfaceName + "/address"; 

簡單地做一個文件的讀取,或該文件的貓會顯示了WIFI MAC地址。

網絡接口名稱通常是沿着「爲wlan0」或「eth1的」

+1

可能需要注意的是,在某些設備這是讀保護的,所以你可能需要root權限。 – showp1984

22

在版本的Android M的MACADDRESS將是WiFi和藍牙「不可讀」的線。 你可以得到的WiFi MACADDRESS用(的Android M預覽版2):

public static String getWifiMacAddress() { 
    try { 
     String interfaceName = "wlan0"; 
     List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); 
     for (NetworkInterface intf : interfaces) { 
      if (!intf.getName().equalsIgnoreCase(interfaceName)){ 
       continue; 
      } 

      byte[] mac = intf.getHardwareAddress(); 
      if (mac==null){ 
       return ""; 
      } 

      StringBuilder buf = new StringBuilder(); 
      for (byte aMac : mac) { 
       buf.append(String.format("%02X:", aMac)); 
      } 
      if (buf.length()>0) { 
       buf.deleteCharAt(buf.length() - 1); 
      } 
      return buf.toString(); 
     } 
    } catch (Exception ex) { } // for now eat exceptions 
    return ""; 
} 

(得到了這個Post這個代碼)

不知怎的,我heared從「讀取文件/ SYS /班/網/ 「+ networkInterfaceName +」/ address「;將不會工作,因爲Android N將被髮布,也可以有不同的製造商像三星等差異。

希望這個代碼仍然可以在以後的Android版本。

編輯:另外在Android的6發佈這個作品

+0

你認爲我們需要什麼權限來檢索'networkInterface'?以及這種方法與Android的官方解決方案有何不同?http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id? –

+2

沒有解決方案。要訪問 - >附近外部設備的硬件標識符< - 您的應用必須具有ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION權限。我不確定檢索networkInterfaces需要什麼權限。但要訪問智能手機WiFi-MAC地址,這是目前唯一的方式,它將會與未來版本的android – Informatic0re

+0

一起消失。看起來Mac地址是隨機的,即使你可以抓住它! https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id –

2

您可以從IPv6本地地址獲取MAC地址。例如,IPv6地址「fe80 :: 1034:56ff:fe78:9abc」對應於MAC地址「12-34-56-78-9a-bc」。請參閱下面的代碼。獲取WiFi IPv6地址只需要android.permission.INTERNET。

請參閱維基百科頁面IPv6 Address,特別是關於「本地地址」fe80 ::/64的註釋和關於「修改的EUI-64」的章節。

/** 
* Gets an EUI-48 MAC address from an IPv6 link-local address. 
* E.g., the IPv6 address "fe80::1034:56ff:fe78:9abc" 
* corresponds to the MAC address "12-34-56-78-9a-bc". 
* <p/> 
* See the note about "local addresses" fe80::/64 and the section about "Modified EUI-64" in 
* the Wikipedia article "IPv6 address" at https://en.wikipedia.org/wiki/IPv6_address 
* 
* @param ipv6 An Inet6Address object. 
* @return The EUI-48 MAC address as a byte array, null on error. 
*/ 
private static byte[] getMacAddressFromIpv6(final Inet6Address ipv6) 
{ 
    byte[] eui48mac = null; 

    if (ipv6 != null) { 
     /* 
     * Make sure that this is an fe80::/64 link-local address. 
     */ 
     final byte[] ipv6Bytes = ipv6.getAddress(); 
     if ((ipv6Bytes != null) && 
       (ipv6Bytes.length == 16) && 
       (ipv6Bytes[0] == (byte) 0xfe) && 
       (ipv6Bytes[1] == (byte) 0x80) && 
       (ipv6Bytes[11] == (byte) 0xff) && 
       (ipv6Bytes[12] == (byte) 0xfe)) { 
      /* 
      * Allocate a byte array for storing the EUI-48 MAC address, then fill it 
      * from the appropriate bytes of the IPv6 address. Invert the 7th bit 
      * of the first byte and discard the "ff:fe" portion of the modified 
      * EUI-64 MAC address. 
      */ 
      eui48mac = new byte[6]; 
      eui48mac[0] = (byte) (ipv6Bytes[8]^0x2); 
      eui48mac[1] = ipv6Bytes[9]; 
      eui48mac[2] = ipv6Bytes[10]; 
      eui48mac[3] = ipv6Bytes[13]; 
      eui48mac[4] = ipv6Bytes[14]; 
      eui48mac[5] = ipv6Bytes[15]; 
     } 
    } 

    return eui48mac; 
}