Tôi cần lấy địa chỉ MAC của thiết bị Android của mình bằng Java. Tôi đã tìm kiếm trực tuyến, nhưng tôi không tìm thấy bất cứ điều gì hữu ích.
Tôi cần lấy địa chỉ MAC của thiết bị Android của mình bằng Java. Tôi đã tìm kiếm trực tuyến, nhưng tôi không tìm thấy bất cứ điều gì hữu ích.
Câu trả lời:
Như đã được chỉ ra trong nhận xét, địa chỉ MAC có thể được nhận qua WifiManager .
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
String address = info.getMacAddress();
Cũng đừng quên thêm các quyền thích hợp vào AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
Vui lòng tham khảo các Thay đổi của Android 6.0 .
Để cung cấp cho người dùng khả năng bảo vệ dữ liệu tốt hơn, bắt đầu từ phiên bản này, Android sẽ xóa quyền truy cập có lập trình vào mã nhận dạng phần cứng cục bộ của thiết bị đối với các ứng dụng sử dụng API Wi-Fi và Bluetooth. Các phương thức WifiInfo.getMacAddress () và BluetoothAdapter.getAddress () hiện trả về một giá trị không đổi là 02: 00: 00: 00: 00: 00.
Để truy cập số nhận dạng phần cứng của các thiết bị bên ngoài lân cận qua Bluetooth và quét Wi-Fi, ứng dụng của bạn hiện phải có quyền ACCESS_FINE_LOCATION hoặc ACCESS_COARSE_LOCATION.
Việc lấy địa chỉ MAC thông qua WifiInfo.getMacAddress()
sẽ không hoạt động trên Marshmallow trở lên, nó đã bị vô hiệu hóa và sẽ trả về giá trị không đổi là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";
}
<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;
}
có những con đường khác ở đây
macAddress
bao giờ null
?
Context context
? nếu có, bất kỳ bối cảnh nào sẽ hoạt động. developer.android.com/reference/android/content/…
Tôi đã thành lập giải pháp này từ http://robinhenniges.com/en/android6-get-mac-address-programmatically và nó phù hợp với tôi! Hy vọng sẽ giúp!
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 "";
}
Hoạt động của nó với 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 "";
}
}
Bạn có thể lấy địa chỉ mac:
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String mac = wInfo.getMacAddress();
Đặt quyền trong Menifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
Bạn không thể lấy địa chỉ MAC phần cứng của thiết bị Android nữa. Các phương thức WifiInfo.getMacAddress () và BluetoothAdapter.getAddress () sẽ trả về 02: 00: 00: 00: 00: 00. Hạn chế này đã được giới thiệu trong Android 6.0.
Nhưng Rob Anderson đã tìm thấy một giải pháp đang hoạt động cho <Marshmallow: https://stackoverflow.com/a/35830358
Lấy từ các nguồn Android tại đây . Đây là mã thực tế hiển thị ĐỊA CHỈ MAC của bạn trong ứng dụng cài đặt của hệ thống.
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
(tức là WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
).
02:00:00:00:00:00
địa chỉ mac không phải là thực tế wifi mac id
Sử dụng phương pháp đơn giản này
WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String WLANMAC = wm.getConnectionInfo().getMacAddress();
Tôi biết đây là một câu hỏi rất cũ nhưng có một phương pháp nữa để làm điều này. Dưới đây biên dịch mã nhưng tôi chưa thử. Bạn có thể viết một số mã C và sử dụng JNI (Java Native Interface) để lấy địa chỉ MAC. Đây là ví dụ về mã hoạt động chính:
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);
}
Và tệp bố cục, 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>
Tệp kê khai, tôi không biết phải thêm quyền gì nên tôi đã thêm một số.
<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 thực hiện hàm 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;
}
Và cuối cùng, tệp 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
Lệnh này hoạt động trên Android 9 từ Cách xác định địa chỉ phần cứng wifi trong Termux