獲取Mac地址實際項目中測試了如下幾種方法:
(1)設備開通Wifi連接,獲取到網卡的MAC地址(但是不開通wifi,這種方法獲取不到Mac地址,這種方法也是網絡上使用的最多的方法)
//根據Wifi信息獲取本地Mac public static String getLocalMacAddressFromWifiInfo(Context context){ WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifi.getConnectionInfo(); return info.getMacAddress(); }
(2)調用Linux的busybox,通過linux命令來獲取
//根據busybox獲取本地Mac 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); Log.i("test","Mac:"+Mac+" Mac.length: "+Mac.length()); /*if(Mac.length()>1){ Mac = Mac.replaceAll(" ", ""); result = ""; String[] tmp = Mac.split(":"); for(int i = 0;i<tmp.length;++i){ result +=tmp[i]; } }*/ result = Mac; Log.i("test",result+" result.length: "+result.length()); } 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); //執行命令cmd,只取結果中含有filter的這一行 while ((line = br.readLine ()) != null && line.contains(filter)== false) { //result += line; Log.i("test","line: "+line); } result = line; Log.i("test","result: "+result); } catch(Exception e) { e.printStackTrace(); } return result; }
(3)調用Android 的API: NetworkInterface. getHardwareAddress ()
該API的level為9,只有android 2.3以上才有該接口
//根據IP獲取本地Mac public static String getLocalMacAddressFromIp(Context context) { String mac_s= ""; try { byte[] mac; NetworkInterface ne=NetworkInterface.getByInetAddress(InetAddress.getByName(getLocalIpAddress())); mac = ne.getHardwareAddress(); mac_s = byte2hex(mac); } catch (Exception e) { e.printStackTrace(); } return mac_s; } public static String byte2hex(byte[] b) { StringBuffer hs = new StringBuffer(b.length); String stmp = ""; int len = b.length; for (int n = 0; n < len; n++) { stmp = Integer.toHexString(b[n] & 0xFF); if (stmp.length() == 1) hs = hs.append("0").append(stmp); else { hs = hs.append(stmp); } } return String.valueOf(hs); }
其中getLocalIpAddress是獲取本地IP地址
//獲取本地IP public 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) { Log.e("WifiPreference IpAddress", ex.toString()); } return null; }
獲取本地IP地址
在網絡上搜索一下,一般就有如下的代碼:
//獲取本地IP public 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) { Log.e("WifiPreference IpAddress", ex.toString()); } return null; }
但是經過測試該方法在android2.3, 2.2...較老版本有效,但是在android較新版本(例如4.0等)獲取的數據不正確。
獲取到了類似fe80::b607:f9ff:fee5:487e..這樣的IP地址。經過一番努力,終於找出原因。
上面的IP地址是IPV6的地址形式(大概這個意思,具體沒有太深入研究)。解決方法是,在上面代碼中的最內層的for循環的if語句中對inetAddress進行格式判斷,只有其是IPV4格式地址時,才返回值。修改后代碼如下:(下面的方法也是網絡上的方法,沒有結果驗證)
public String getLocalIpAddress() { try { String ipv4; List nilist = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface ni: nilist) { List ialist = Collections.list(ni.getInetAddresses()); for (InetAddress address: ialist){ if (!address.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipv4=address.getHostAddress())) { return ipv4; } } } } catch (SocketException ex) { Log.e(LOG_TAG, ex.toString()); } return null; }
網絡上還有一種方法來獲取本地IP地址(不過是在wifi狀態下)
通過WifiManager, DhcpInfo獲取IP地址以及網關等信息(在android4.0等版本也適用)
package com.jason.demo.androidip; import android.content.Context; import android.net.DhcpInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.text.format.Formatter; public class IPAddress { public String getIPAddress(Context ctx){ WifiManager wifi_service = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE); DhcpInfo dhcpInfo = wifi_service.getDhcpInfo(); WifiInfo wifiinfo = wifi_service.getConnectionInfo(); System.out.println("Wifi info----->"+wifiinfo.getIpAddress()); System.out.println("DHCP info gateway----->"+Formatter.formatIpAddress(dhcpInfo.gateway)); System.out.println("DHCP info netmask----->"+Formatter.formatIpAddress(dhcpInfo.netmask)); //DhcpInfo中的ipAddress是一個int型的變量,通過Formatter將其轉化為字符串IP地址 return Formatter.formatIpAddress(dhcpInfo.ipAddress); } }
加入permission
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
不過我自己在做項目過程中,用另外一種方法也解決了android4.0獲取IP錯誤的問題:
//獲取本地IP public 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() && !inetAddress.isLinkLocalAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { Log.e("WifiPreference IpAddress", ex.toString()); } return null; }
參考博文:
http://www.cnblogs.com/Amandaliu/archive/2011/11/06/2238177.html
Android獲取Mac地址
http://blog.csdn.NET/ccf0703/article/details/7451274
解決安卓4.0獲取本地IP地址問題。
http://blog.csdn.Net/garybook/article/details/7874456
通過WifiManager,DhcpInfo獲取android IP地址及網關等信息(兩種方式)
http://blog.csdn.net/lizzydarcymsp/article/details/5623302
利用InetAddress類確定特殊IP地址 (isLinkLocalAddress,isLoopbackAddress等)
轉自:http://www.cnblogs.com/lijunamneg/archive/2013/03/04/2943146.html
然后我自己弱弱說一句, 我用前面兩種方法的時候有空指針,最后采取的本地IP獲取mac地址。