I'm developing an app that gets the MAC address of the device, but since Android 6.0 my code doesn't work, giving me an incorrect value.
Here's my code...
public String ObtenMAC()
{
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
return(info.getMacAddress().toUpperCase());
}
Instead of the real MAC address, it returns an strange code: 02:00:00:00:00:00
.
Please refer to Android 6.0 Changes.
To provide users with greater data protection, starting in this release, Android removes programmatic access to the device’s local hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods now return a constant value of 02:00:00:00:00:00.
To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions.
Use below code to get Mac address in Android 6.0
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(Integer.toHexString(b & 0xFF) + ":");
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
//handle exception
}
return "";
}
I didn't get the above answer to work, but stumbled upon another answer.
Here is a complete and simple method on getting the IPv6 address and then getting the mac address from it.
How to get Wi-Fi Mac address in Android Marshmallow
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
}
return "02:00:00:00:00:00";
}
Tested it already and it works. Many thanks to Rob Anderson!
this is the complete 2 ways code of getting it successfully on Marshmallow , just copy past this and it will work !
//Android 6.0 : Access to mac address from WifiManager forbidden
private static final String marshmallowMacAddress = "02:00:00:00:00:00";
private static final String fileAddressMac = "/sys/class/net/wlan0/address";
public static String recupAdresseMAC(WifiManager wifiMan) {
WifiInfo wifiInf = wifiMan.getConnectionInfo();
if(wifiInf.getMacAddress().equals(marshmallowMacAddress)){
String ret = null;
try {
ret= getAdressMacByInterface();
if (ret != null){
return ret;
} else {
ret = getAddressMacByFile(wifiMan);
return ret;
}
} catch (IOException e) {
Log.e("MobileAccess", "Erreur lecture propriete Adresse MAC");
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
} else{
return wifiInf.getMacAddress();
}
return marshmallowMacAddress;
}
private static String getAdressMacByInterface(){
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (nif.getName().equalsIgnoreCase("wlan0")) {
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
}
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
return null;
}
private static String getAddressMacByFile(WifiManager wifiMan) throws Exception {
String ret;
int wifiState = wifiMan.getWifiState();
wifiMan.setWifiEnabled(true);
File fl = new File(fileAddressMac);
FileInputStream fin = new FileInputStream(fl);
StringBuilder builder = new StringBuilder();
int ch;
while((ch = fin.read()) != -1){
builder.append((char)ch);
}
ret = builder.toString();
fin.close();
boolean enabled = WifiManager.WIFI_STATE_ENABLED == wifiState;
wifiMan.setWifiEnabled(enabled);
return ret;
}
manifest :
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Summary : this code will try to get the MAC address first by Interface and if its failed it get it by file system.
Note:for file System way, you need to enable WIFI to access the file.
thnx to Sam's answer here https://stackoverflow.com/a/39288868/3818437
You can get the MAC address from the IPv6 local address. E.g., the IPv6 address "fe80::1034:56ff:fe78:9abc" corresponds to the MAC address "12-34-56-78-9a-bc". See the code below. Getting the WiFi IPv6 address only requires android.permission.INTERNET.
See the Wikipedia page IPv6 address, particularly the note about "local addresses" fe80::/64 and the section about "Modified 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;
}
I try to get mac address with 2 methods, first by Interface and if its failed, i get it by file system, but you need to enable wifi to access the file.
//Android 6.0 : Access to mac address from WifiManager forbidden
private static final String marshmallowMacAddress = "02:00:00:00:00:00";
private static final String fileAddressMac = "/sys/class/net/wlan0/address";
public static String recupAdresseMAC(WifiManager wifiMan) {
WifiInfo wifiInf = wifiMan.getConnectionInfo();
if(wifiInf.getMacAddress().equals(marshmallowMacAddress)){
String ret = null;
try {
ret= getAdressMacByInterface();
if (ret != null){
return ret;
} else {
ret = getAddressMacByFile(wifiMan);
return ret;
}
} catch (IOException e) {
Log.e("MobileAccess", "Erreur lecture propriete Adresse MAC");
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
} else{
return wifiInf.getMacAddress();
}
return marshmallowMacAddress;
}
private static String getAdressMacByInterface(){
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (nif.getName().equalsIgnoreCase("wlan0")) {
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
}
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
return null;
}
private static String getAddressMacByFile(WifiManager wifiMan) throws Exception {
String ret;
int wifiState = wifiMan.getWifiState();
wifiMan.setWifiEnabled(true);
File fl = new File(fileAddressMac);
FileInputStream fin = new FileInputStream(fl);
ret = convertStreamToString(fin);
fin.close();
boolean enabled = WifiManager.WIFI_STATE_ENABLED == wifiState;
wifiMan.setWifiEnabled(enabled);
return ret;
}
Add this line to your manifest.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
I recommend you to persist your mac address in your preferences like here
mac = activity.getSharedPreferences("MAC_ADDRESS", Context.MODE_PRIVATE).getString("MAC_ADDRESS", "");
if(mac == null || mac.equals("")){
WifiManager wifiMan = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
mac = MobileAccess.recupAdresseMAC(wifiMan);
if(mac != null && !mac.equals("")){
SharedPreferences.Editor editor = activity.getSharedPreferences("MAC_ADDRESS", Context.MODE_PRIVATE).edit();
editor.putString("MAC_ADDRESS", mac).commit();
}
}
First you need to add Internet user permission.
<uses-permission android:name="android.permission.INTERNET" />
Then you can find the mac over the NetworkInterfaces API.
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
}
return "02:00:00:00:00:00";
}
The answers are mostly correct, but keep care, that there is a change in android 7. You will need to use the
DevicePolicyManager and the Method getWifiMacAddress. The official docs has a typo, which means that you shouldnt copy/paste it from there.
DevicePolicyManager.getWifiMacAddress()
Refs: https://developer.android.com/about/versions/nougat/android-7.0-changes.html
Get Device mac adress in Android Nougat and O programmatically
Its Perfectly Fine
package com.keshav.fetchmacaddress;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("keshav","getMacAddr -> " +getMacAddr());
}
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(Integer.toHexString(b & 0xFF) + ":");
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
//handle exception
}
return "";
}
}
来源:https://stackoverflow.com/questions/33159224/getting-mac-address-in-android-6-0