2015-10-15 2 views
33

Я разрабатываю приложение, которое получает MAC-адрес устройства, но с Android 6.0 мой код не работает, что дает мне неправильное значение.Получение MAC-адреса в Android 6.0

Вот мой код ...

public String ObtenMAC() 
{ 
    WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
    WifiInfo info = manager.getConnectionInfo(); 

    return(info.getMacAddress().toUpperCase()); 
} 

Вместо реального MAC-адреса, он возвращает странный код "02: 00: 00: 00: 00: 00".

Может ли кто-нибудь помочь мне решить эту проблему ?.

Заранее благодарен.

+0

ли вы убедились, что вы проверили на 'ACCESS_WIFI_STATE' до получения MAC-адрес? В M это не сработает, если вы только попросите об этом в манифесте, вы должны выполнить его в rumtime следующим образом: https://www.youtube.com/watch?v=C8lUdPVSzDk&index=3&list=PLWz5rJ2EKKc-lJo_RGGXL2Psr8vVCTWjM –

+0

Спасибо за ответ. У меня есть это разрешение в моем манифесте, но когда я иду проверить его программно, как показано на видео, Android Studio не распознает «checkSelfPermission», я не знаю, может ли быть, потому что я нацелен на API 21 Lollipop и hasn Установлен API 23 Marshmallow. – Mazinger

+0

Прежде чем вы позвоните в checkSelfPermission, вы должны проверить, не является ли версия SDK lass, чем API 23. Зефир, как здесь: http://stackoverflow.com/questions/3423754/retrieving-android-api-version-programmatically. –

ответ

31

См. Android 6.0 Changes.

Чтобы предоставить пользователям более полную защиту данных, начиная с этой версии, Android удаляет программный доступ к локальному идентификатору оборудования для приложений с использованием API Wi-Fi и Bluetooth. Теперь методы WifiInfo.getMacAddress() и BluetoothAdapter.getAddress() возвращают постоянное значение 02: 00: 00: 00: 00: 00.

Чтобы получить доступ к идентификаторам оборудования соседних внешних устройств через Bluetooth и сканирование Wi-Fi, ваше приложение должно иметь разрешения ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION.

+9

У меня есть права на мое приложение и все еще не работает. – Hrodger

+6

@ Hrodger, вы не можете получить свои собственные MAC-адреса, даже имеющие эти разрешения. Внимательно прочитайте. Говорят, что вы можете получить ** другие MAC-адреса устройств **, обладающие этими разрешениями, но не вашими –

+4

Таким образом, нет способа сделать это? – Hrodger

6

Вы можете получить MAC-адрес с локального адреса IPv6. Например, адрес IPv6 «fe80 :: 1034: 56ff: fe78: 9abc» соответствует MAC-адресу «12-34-56-78-9a-bc». См. Код ниже. Для получения IP-адреса WiFi требуется только андроид.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; 
} 
+0

Кажется, что адрес Mac рандомизирован, даже если вы его поймаете! https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id –

+0

API WifiManager был изменен в Android 6.0, чтобы вернуть поддельный MAC-адрес. Но вы все равно можете получить локальный адрес ссылки IPv6 для сети Wi-Fi, а затем извлечь MAC-адрес, как указано выше. Это работает на каждом устройстве, которое я пробовал. – Yojimbo

+0

Привет @Yojimbo, будет ли этот код возвращать MAC-адрес маршрутизатора или устройства? –

8

Я не получил вышеуказанный ответ на работу, но наткнулся на другой ответ.

Ниже приведен полный и простой способ получения адреса IPv6, а затем получения от него MAC-адреса.

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"; 
} 

Испытано это уже и работает. Большое спасибо Роба Андерсона!

+1

Спасибо, как указано в другом месте, для этого требуется работать. – lejonl

14

Используйте ниже код, чтобы получить Mac адрес в 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 ""; 
} 
+6

Вышеупомянутый ответ был взят из этого сообщения в блоге: http://robinhenniges.com/en/android6-get-mac-address-programmatically – zerobandwidth

+4

Этот ответ получил ошибку, в которой байт, который в шестнадцатеричной форме получил одну цифру, не будет появляются с «0» перед ним. Добавление к res1 должно быть изменено на res1.append (String.format ("% 02X:", b)); –

+1

Работает на Android 7. –

3

Я стараюсь, чтобы получить MAC-адрес с 2 способами, первый по интерфейсу, и если его не удалось, я получить его файловой системы, но вам нужно включить Wi-Fi для доступа к файлу.

//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; 
    } 

Добавьте эту строку в свой манифест.

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 

Я рекомендую вам упорствовать свой адрес макинтоша в ваших предпочтениях, как здесь

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(); 
        } 
       } 
0

Прежде всего, необходимо добавить разрешение пользователя Интернет.

<uses-permission android:name="android.permission.INTERNET" /> 

Затем вы можете найти mac через API NetworkInterfaces.

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"; 
} 
+1

Вышеупомянутый ответ был взят из этого сообщения в блоге: http://robinhenniges.com/en/android6-get-mac-address-programmatically – zerobandwidth

5

это полный 2 способа код получить его успешно на Зефир, просто скопируйте это в прошлом, и он будет работать!

//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; 
    } 

манифеста:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
  • Резюме: этот код будет пытаться получить МАС-адрес первого по интерфейсу, и если его не удалось его получить его файловой системой.

  • Примечание: для файлового системного пути вам необходимо активировать WIFI для доступа к файлу.

Thnx для ответа Сэма здесь https://stackoverflow.com/a/39288868/3818437

+0

Я знаю его немного поздно, но это полный эффективный ответ, он должен быть отмечен как Лучший ответ – mhdjazmati

0

Ответы в основном правильно, но держать заботу, что есть изменение в андроида 7. Вам нужно будет использовать

DevicePolicyManager и метод getWifiMacAddress. Официальные документы имеют опечатку, что означает, что вы не должны копировать/вставлять ее оттуда.

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

0

Его прекрасно

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 ""; 
    } 
} 
Смежные вопросы