Программно получить MAC устройства Android
Мне нужно получить MAC-адрес моего устройства Android с помощью Java. Я искал в Интернете, но я не нашел ничего полезного.
15 ответов
Как уже указывалось в комментарии, MAC-адрес можно получить через WifiManager.
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
String address = info.getMacAddress();
Также не забудьте добавить соответствующие разрешения в ваш AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
Пожалуйста, обратитесь к Android 6.0 Изменения.
Чтобы обеспечить пользователям более надежную защиту данных, начиная с этой версии, Android удаляет программный доступ к локальному идентификатору оборудования устройства для приложений, использующих API-интерфейсы Wi-Fi и Bluetooth. Методы WifiInfo.getMacAddress () и BluetoothAdapter.getAddress () теперь возвращают постоянное значение 02: 00: 00: 00: 00: 00.
Чтобы получить доступ к идентификаторам оборудования соседних внешних устройств через сканирование Bluetooth и Wi-Fi, ваше приложение должно теперь иметь разрешения ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION.
Получение MAC-адреса через WifiInfo.getMacAddress()
не будет работать на Зефир и выше, он был отключен и будет возвращать постоянное значение 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;
}
есть другие пути здесь
Его работа с зефиром
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.
Но Роб Андерсон нашел решение, которое работает для
Вы можете получить MAC-адрес:
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String mac = wInfo.getMacAddress();
Установить разрешение в Menifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
Я сам проверил этот код, и он даст вам WiFi или Ethernet mac-адрес, что доступно.
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) + ":");
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < macBytes.length; i++) {
sb.append(String.format("%02X%s", macBytes[i], (i < macBytes.length - 1) ? "-" : ""));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
//handle exception
}
return getMacAddress();
}
public static String loadFileAsString(String filePath) throws java.io.IOException{
StringBuffer data = new StringBuffer(1000);
BufferedReader reader = new BufferedReader(new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
data.append(readData);
}
reader.close();
return data.toString();
}
public static String getMacAddress(){
try {
return loadFileAsString("/sys/class/net/eth0/address")
.toUpperCase().substring(0, 17);
} catch (IOException e) {
e.printStackTrace();
return "02:00:00:00:00:00";
}
}
Используя этот простой метод
WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String WLANMAC = wm.getConnectionInfo().getMacAddress();
Взято из источников 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);
}
Я знаю, что это очень старый вопрос, но есть еще один способ сделать это. Код ниже компилируется, но я его не пробовал. Вы можете написать код на 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://stackru.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://stackru.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)
Please add in AndroidManifest
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
// Получить MAC-адрес в действии...String strMACAddress = getMacAddress_For_New_Tab(this);
public static String getMacAddress_For_New_Tab(Context context)
{
String macAddress=null;
WifiManager objwifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
boolean wifiEnabled = objwifiManager.isWifiEnabled();
int LoopCounter=0;
while (macAddress==null) // Required if HD Security is Enabled.
{
if (wifiEnabled)
{
objwifiManager.setWifiEnabled(false);
objwifiManager.reconnect();
objwifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) //M Means Marshmellow.
{
// Do something for lollipop and above versions
macAddress = getMacAddr();
} else
{
// do something for phones running an SDK before lollipop
macAddress = objwifiManager.getConnectionInfo().getMacAddress();
}
// Required if HD Security is Enabled.
LoopCounter++;
if (LoopCounter>2) break;
}
if (wifiEnabled)
{
objwifiManager.setWifiEnabled(wifiEnabled); // Retain Old.
objwifiManager.reconnect();
/*try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}*/
}
return macAddress; //Device don't have mac address or wi-fi is disabled if it is null.
}
public static String getMacAddr()
{
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all)
{
if (CurrentStatus.ModelName.toUpperCase().equals("LENOVO TB-8705X"))
{
Thread.sleep(50);
}
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) + ":");
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
}
return "";
}
Этот ip link | grep -A1 wlan0
команда работает на Android 9 из Как определить аппаратный адрес Wi-Fi в Termux
Я думаю, что я только что нашел способ читать MAC-адреса без разрешения LOCATION: Выполнить ip addr
и проанализировать его вывод. (вы могли бы сделать то же самое, посмотрев на исходный код этого двоичного файла)