Мне нужно получить MAC-адрес моего устройства Android с помощью Java. Я искал в Интернете, но не нашел ничего полезного.
java
android
mac-address
TSW1985
источник
источник
Ответы:
Как уже было указано в комментарии, MAC-адрес можно получить через WifiManager .
Также не забудьте добавить соответствующие разрешения в свой
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
См. Изменения в Android 6.0 .
источник
Получение MAC-адреса
WifiInfo.getMacAddress()
не будет работать в Marshmallow и более поздних версиях, он отключен и будет возвращать постоянное значение02:00:00:00:00:00
.источник
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"; }
источник
Я основал это решение с http://robinhenniges.com/en/android6-get-mac-address-programmatically, и оно работает для меня! Надежда помогает!
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 ""; }
источник
<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; }
есть другие пути здесь
источник
macAddress
нибудь будетnull
?Context context
? если да, любой контекст должен работать. developer.android.com/reference/android/content/…Его работа с 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 ""; } }
источник
Вы больше не можете получить аппаратный MAC-адрес устройства Android. Методы WifiInfo.getMacAddress () и BluetoothAdapter.getAddress () вернут 02: 00: 00: 00: 00: 00. Это ограничение было введено в Android 6.0.
Но Роб Андерсон нашел решение, которое работает для <Marshmallow: https://stackoverflow.com/a/35830358
источник
Вы можете получить MAC-адрес:
Установите разрешение в Menifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
источник
Используя этот простой метод
источник
Взято из исходников Android здесь . Это фактический код, который показывает ваш MAC-АДРЕС в приложении настроек системы.
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); }
источник
WifiManager
(т.е.WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
).02:00:00:00:00:00
MAC-адрес, а не фактический MAC-идентификатор Wi-FiЯ знаю, что это очень старый вопрос, но есть еще один способ сделать это. Код ниже компилируется, но я не пробовал. Вы можете написать код на C и использовать JNI (собственный интерфейс Java) для получения MAC-адреса. Вот пример кода основной деятельности:
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); }
И файл макета 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>
Файл манифеста, я не знал, какие разрешения добавить, поэтому добавил несколько.
<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>
C реализация функции get_mac_addr.
/* 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; }
И наконец, файл 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)
источник
Эта
ip link | grep -A1 wlan0
команда работает на Android 9 из раздела Как определить аппаратный адрес Wi-Fi в Termuxисточник
Думаю, я только что нашел способ читать MAC-адреса без разрешения LOCATION: запустить
ip link
и проанализировать его вывод. (вы, вероятно, могли бы сделать то же самое, посмотрев исходный код этого двоичного файла)источник