Android開發(fā)獲取手機(jī)Mac地址適配所有Android版本
最近由于項(xiàng)目需要MAC地址的記錄,搞了一個(gè)通用的適配類,目前經(jīng)過測(cè)試可以適配Android所有版本,我測(cè)試過的設(shè)備系統(tǒng)Android 4 5 6 7 7+都可以獲取到,廢話不多說直接上代碼,簡(jiǎn)潔:
該類分為三類:Android6.0以下、6.0以上7.0以下、7.0以上
首先是獲取MAC的整合方法:
public static String getMac(Context context) { String strMac = null; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { Log.e("=====", "6.0以下"); Toast.makeText(context, "6.0以下", Toast.LENGTH_SHORT).show(); strMac = getLocalMacAddressFromWifiInfo(context); return strMac; } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Log.e("=====", "6.0以上7.0以下"); Toast.makeText(context, "6.0以上7.0以下", Toast.LENGTH_SHORT).show(); strMac = getMacAddress(context); return strMac; } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Log.e("=====", "7.0以上"); if (!TextUtils.isEmpty(getMacAddress())) { Log.e("=====", "7.0以上1"); Toast.makeText(context, "7.0以上1", Toast.LENGTH_SHORT).show(); strMac = getMacAddress(); return strMac; } else if (!TextUtils.isEmpty(getMachineHardwareAddress())) { Log.e("=====", "7.0以上2"); Toast.makeText(context, "7.0以上2", Toast.LENGTH_SHORT).show(); strMac = getMachineHardwareAddress(); return strMac; } else { Log.e("=====", "7.0以上3"); Toast.makeText(context, "7.0以上3", Toast.LENGTH_SHORT).show(); strMac = getLocalMacAddressFromBusybox(); return strMac; } } return "02:00:00:00:00:00"; }
6.0以下方法,Google提供的公有方法,需要權(quán)限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
/** * 根據(jù)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 。
然而我開發(fā)的sdk就是通過wifimanager獲取的mac。
android sdk后來做了6.0適配,通過cat /sys/class/net/wlan0/address,可以在6.0上獲取mac地址。
/** * android 6.0及以上、7.0以下 獲取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地址。
經(jīng)過調(diào)研和測(cè)試,7.0上仍有辦法回去mac地址:
總共分為三種方式:
- 通過ip地址來獲取綁定的mac地址
- 掃描各個(gè)網(wǎng)絡(luò)接口獲取mac地址
- 通過busybox獲取本地存儲(chǔ)的mac地址
代碼如下:
/** * 根據(jù)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; } /** * 獲取移動(dòng)設(shè)備本地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();// 得到下一個(gè)元素 Enumeration<InetAddress> en_ip = ni.getInetAddresses();// 得到一個(gè)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; }
/** * android 7.0及以上 (2)掃描各個(gè)網(wǎng)絡(luò)接口獲取mac地址 * */ /** * 獲取設(shè)備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; if (interfaces == null) { return null; } while (interfaces.hasMoreElements()) { iF = interfaces.nextElement(); try { hardWareAddress = bytesToString(iF.getHardwareAddress()); if (hardWareAddress != null) break; } catch (SocketException e) { e.printStackTrace(); } } return hardWareAddress; } /*** * byte轉(zhuǎn)為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(); }
/** * android 7.0及以上 (3)通過busybox獲取本地存儲(chǔ)的mac地址 * */ /** * 根據(jù)busybox獲取本地Mac * * @return */ public static String getLocalMacAddressFromBusybox() { String result = ""; String Mac = ""; result = callCmd("busybox ifconfig", "HWaddr"); // 如果返回的result == null,則說明網(wǎng)絡(luò)不可取 if (result == null) { return "網(wǎng)絡(luò)異常"; } // 對(duì)該行數(shù)據(jù)進(jìn)行解析 // 例如: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; }
本文主要講解了Android獲取手機(jī)Mac地址的實(shí)例源碼,更多關(guān)于Android獲取手機(jī)Mac地址的技巧請(qǐng)查看下面的相關(guān)鏈接
- Android 版本、權(quán)限適配相關(guān)總結(jié)
- Android 圖片保存到相冊(cè)不顯示的解決方案(兼容Android 10及更高版本)
- Android Studio 2020新版本卡在Gradle downloading/sync failed/下載緩慢/下載超時(shí)的問題
- 詳解如何在Android studio中更新sdk版本和build-tools版本
- Android Studio下載、安裝和配置+SDK+tools下載(無敵超級(jí)詳細(xì)版本)
- Android Studio3.6.3 當(dāng)前最新版本數(shù)據(jù)庫(kù)查找與導(dǎo)出方法(圖文詳解)
- 詳解Android studio 3+版本apk安裝失敗問題
- android studio 打包自動(dòng)生成版本號(hào)與日期,apk輸入路徑詳解
- Android實(shí)現(xiàn)懸浮窗全系統(tǒng)版本
- 詳解Android版本適配:9.0 Pie
- Android ProductFlavor的使用詳解
相關(guān)文章
Android單片機(jī)與藍(lán)牙模塊通信實(shí)例代碼
這篇文章主要介紹了Android單片機(jī)與藍(lán)牙模塊通信實(shí)例代碼,非常實(shí)用,特此分享給大家,需要的朋友可以參考下2016-05-05Android自定義控件實(shí)現(xiàn)九宮格解鎖
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)九宮格解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06Android 利用方向傳感器實(shí)現(xiàn)指南針具體步驟
Android利用方向傳感器實(shí)現(xiàn)指南針功能,聽起來還不錯(cuò)吧,下面與大家分享下具體的實(shí)現(xiàn)步驟,感興趣的朋友可以參考下哈2013-06-06Android Java實(shí)現(xiàn)余弦匹配算法示例代碼
這篇文章主要介紹了Android Java實(shí)現(xiàn)余弦匹配算法示例代碼的相關(guān)資料,這里通過java 算法實(shí)現(xiàn)余弦匹配算法實(shí)現(xiàn)比較的實(shí)例,需要的朋友可以參考下2016-11-11通過WIFI(不用數(shù)據(jù)線)連接Android手機(jī)調(diào)試
本文主要介紹WIFI 鏈接手機(jī)調(diào)試,這里詳細(xì)介紹了WIFI 鏈接Android手機(jī)實(shí)現(xiàn)調(diào)試的過程,有需要的小伙伴可以參考下2016-08-08Android實(shí)現(xiàn)快速滾動(dòng)FastScrollView效果
這篇文章主要介紹了Android實(shí)現(xiàn)快速滾動(dòng)FastScrollView效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08Android判斷當(dāng)前App是在前臺(tái)還是在后臺(tái)
這篇文章主要為大家詳細(xì)介紹了Android判斷當(dāng)前App是在前臺(tái)還是在后臺(tái)的方法,感興趣的小伙伴們可以參考一下2016-08-08