Muszę uzyskać adres MAC mojego urządzenia z systemem Android za pomocą języka Java. Szukałem w Internecie, ale nie znalazłem nic przydatnego.
java
android
mac-address
TSW1985
źródło
źródło
Odpowiedzi:
Jak już wskazano w komentarzu, adres MAC można odebrać za pośrednictwem WifiManagera .
Nie zapomnij również dodać odpowiednich uprawnień do pliku
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
Zapoznaj się ze zmianami w systemie Android 6.0 .
źródło
Przekazanie adresu MAC
WifiInfo.getMacAddress()
nie będzie działać na Marshmallow i nowszych wersjach, zostało wyłączone i zwróci stałą wartość02:00:00:00:00:00
.źródło
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"; }
źródło
Założyłem to rozwiązanie ze strony http://robinhenniges.com/en/android6-get-mac-address-programmatically i działa dla mnie! Nadzieja pomaga!
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) { String hex = Integer.toHexString(b & 0xFF); if (hex.length() == 1) hex = "0".concat(hex); res1.append(hex.concat(":")); } if (res1.length() > 0) { res1.deleteCharAt(res1.length() - 1); } return res1.toString(); } } catch (Exception ex) { } return ""; }
źródło
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> public String getMacAddress(Context context) { WifiManager wimanager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); String macAddress = wimanager.getConnectionInfo().getMacAddress(); if (macAddress == null) { macAddress = "Device don't have mac address or wi-fi is disabled"; } return macAddress; }
mają inne drogi tutaj
źródło
macAddress
kiedykolwiek będzienull
?Context context
? jeśli tak, każdy kontekst powinien działać. developer.android.com/reference/android/content/ ...Działa z Marshmallow
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 ""; } }
źródło
Nie można już uzyskać sprzętowego adresu MAC urządzenia z systemem Android. Metody WifiInfo.getMacAddress () i BluetoothAdapter.getAddress () zwrócą 02: 00: 00: 00: 00: 00. To ograniczenie zostało wprowadzone w systemie Android 6.0.
Ale Rob Anderson znalazł rozwiązanie, które działa dla <Marshmallow: https://stackoverflow.com/a/35830358
źródło
Możesz uzyskać adres MAC:
Ustaw uprawnienia w Menifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
źródło
Używając tej prostej metody
źródło
Zaczerpnięte ze źródeł Androida tutaj . To jest rzeczywisty kod, który pokazuje Twój ADRES MAC w aplikacji ustawień systemu.
private void refreshWifiInfo() { WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS); String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress(); wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress : getActivity().getString(R.string.status_unavailable)); Preference wifiIpAddressPref = findPreference(KEY_CURRENT_IP_ADDRESS); String ipAddress = Utils.getWifiIpAddresses(getActivity()); wifiIpAddressPref.setSummary(ipAddress == null ? getActivity().getString(R.string.status_unavailable) : ipAddress); }
źródło
WifiManager
(tjWifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
.).02:00:00:00:00:00
adres mac, a nie rzeczywisty identyfikator mac wifiWiem, że to bardzo stare pytanie, ale jest jeszcze jedna metoda, aby to zrobić. Poniższy kod kompiluje się, ale nie próbowałem tego. Możesz napisać kod w C i użyć JNI (Java Native Interface), aby uzyskać adres MAC. Oto przykładowy kod głównej aktywności:
package com.example.getmymac; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class GetMyMacActivity extends AppCompatActivity { static { // here we are importing native library. // name of the library is libnet-utils.so, in cmake and java code // we just use name "net-utils". System.loadLibrary("net-utils"); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_screen); // some debug text and a TextView. Log.d(NetUtilsActivity.class.getSimpleName(), "Starting app..."); TextView text = findViewById(R.id.sample_text); // the get_mac_addr native function, implemented in C code. byte[] macArr = get_mac_addr(null); // since it is a byte array, we format it and convert to string. String val = String.format("%02x:%02x:%02x:%02x:%02x:%02x", macArr[0], macArr[1], macArr[2], macArr[3], macArr[4], macArr[5]); // print it to log and TextView. Log.d(NetUtilsActivity.class.getSimpleName(), val); text.setText(val); } // here is the prototype of the native function. // use native keyword to indicate it is a native function, // implemented in C code. private native byte[] get_mac_addr(String interface_name); }
I plik układu, main_screen.xml:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/sample_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
Plik manifestu, nie wiedziałem, jakie uprawnienia dodać, więc dodałem kilka.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.getmymac"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".GetMyMacActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
Implementacja funkcji get_mac_addr w C.
/* length of array that MAC address is stored. */ #define MAC_ARR_LEN 6 #define BUF_SIZE 256 #include <jni.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <net/if.h> #include <sys/ioctl.h> #include <unistd.h> #define ERROR_IOCTL 1 #define ERROR_SOCKT 2 static jboolean cstr_eq_jstr(JNIEnv *env, const char *cstr, jstring jstr) { /* see [this](https://stackoverflow.com/a/38204842) */ jstring cstr_as_jstr = (*env)->NewStringUTF(env, cstr); jclass cls = (*env)->GetObjectClass(env, jstr); jmethodID method_id = (*env)->GetMethodID(env, cls, "equals", "(Ljava/lang/Object;)Z"); jboolean equal = (*env)->CallBooleanMethod(env, jstr, method_id, cstr_as_jstr); return equal; } static void get_mac_by_ifname(jchar *ifname, JNIEnv *env, jbyteArray arr, int *error) { /* see [this](https://stackoverflow.com/a/1779758) */ struct ifreq ir; struct ifconf ic; char buf[BUF_SIZE]; int ret = 0, sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { *error = ERROR_SOCKT; return; } ic.ifc_len = BUF_SIZE; ic.ifc_buf = buf; ret = ioctl(sock, SIOCGIFCONF, &ic); if (ret) { *error = ERROR_IOCTL; goto err_cleanup; } struct ifreq *it = ic.ifc_req; /* iterator */ struct ifreq *end = it + (ic.ifc_len / sizeof(struct ifreq)); int found = 0; /* found interface named `ifname' */ /* while we find an interface named `ifname' or arrive end */ while (it < end && found == 0) { strcpy(ir.ifr_name, it->ifr_name); ret = ioctl(sock, SIOCGIFFLAGS, &ir); if (ret == 0) { if (!(ir.ifr_flags & IFF_LOOPBACK)) { ret = ioctl(sock, SIOCGIFHWADDR, &ir); if (ret) { *error = ERROR_IOCTL; goto err_cleanup; } if (ifname != NULL) { if (cstr_eq_jstr(env, ir.ifr_name, ifname)) { found = 1; } } } } else { *error = ERROR_IOCTL; goto err_cleanup; } ++it; } /* copy the MAC address to byte array */ (*env)->SetByteArrayRegion(env, arr, 0, 6, ir.ifr_hwaddr.sa_data); /* cleanup, close the socket connection */ err_cleanup: close(sock); } JNIEXPORT jbyteArray JNICALL Java_com_example_getmymac_GetMyMacActivity_get_1mac_1addr(JNIEnv *env, jobject thiz, jstring interface_name) { /* first, allocate space for the MAC address. */ jbyteArray mac_addr = (*env)->NewByteArray(env, MAC_ARR_LEN); int error = 0; /* then just call `get_mac_by_ifname' function */ get_mac_by_ifname(interface_name, env, mac_addr, &error); return mac_addr; }
I na koniec plik CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1) add_library(net-utils SHARED src/main/cpp/net-utils.c) target_link_libraries(net-utils android log)
źródło
To
ip link | grep -A1 wlan0
polecenie działa na Androidzie 9 od Jak określić adres sprzętowy Wi-Fi w Termuxźródło
Myślę, że właśnie znalazłem sposób na odczytanie adresów MAC bez pozwolenia na LOKALIZACJĘ: Uruchom
ip link
i przeanalizuj jego wyjście. (prawdopodobnie możesz zrobić podobnie, patrząc na kod źródłowy tego pliku binarnego)źródło