प्रोग्राम को एंड्रॉइड डिवाइस का मैक प्राप्त करना


93

मुझे जावा का उपयोग करके अपने एंड्रॉइड डिवाइस के मैक पते को प्राप्त करने की आवश्यकता है। मैंने ऑनलाइन खोज की है, लेकिन मुझे कुछ भी उपयोगी नहीं मिला है।





कृपया इस समाधान की जाँच करें, यह मेरे लिए काम करता है stackoverflow.com/questions/31329733/…
गोरियो

एंड्रॉइड एम से यह एपि को हटा दिया गया है, इसे अभी के लिए उपयोग करें: stackoverflow.com/questions/31329733/…
एहूद

जवाबों:


115

जैसा कि टिप्पणी में पहले ही बताया गया था, मैक पते को 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 परिवर्तन देखें ।

उपयोगकर्ताओं को अधिक डेटा सुरक्षा प्रदान करने के लिए, इस रिलीज़ में शुरू होने पर, एंड्रॉइड वाई-फाई और ब्लूटूथ एपीआई का उपयोग करने वाले ऐप्स के लिए डिवाइस के स्थानीय हार्डवेयर पहचानकर्ता के लिए प्रोग्रामेटिक एक्सेस को हटा देता है। WifiInfo.getMacAddress () और BluetoothAdapter.getAddress () विधियाँ अब 02: 00: 00: 00: 00: 00 का निरंतर मान लौटाती हैं।

ब्लूटूथ और वाई-फाई स्कैन के जरिए आस-पास के बाहरी उपकरणों के हार्डवेयर पहचानकर्ताओं तक पहुंचने के लिए, आपके ऐप में अब ACCESS_FINE_LOCATION या ACCESS_COARSE_LOCATION अनुमतियां होनी चाहिए।


11
इसके अलावा सिर्फ एक नोट, कभी-कभी मैक पते को नहीं खींचा जा सकता क्योंकि वाईफाई डिवाइस पर बंद है
sbrichards

3
लिंक किए गए ब्लॉग में यह भी बताया गया है कि इस मैक पते को और अधिक सामान्य तरीके से कैसे खोजा जाए कि नेटवर्क इंटरफेस वाईफाई कनेक्शन का उपयोग न करे।
स्टीफन सी।

याद रखें कि getSystemService को कॉल करने के लिए संदर्भ का उपयोग करें।
टिटो लीवा

यह Wifi का उपयोग करने वाले एंड्रॉइड फोन और टैबलेट के लिए बहुत अच्छा है, लेकिन मैं एक पुराने जिंजरब्रेड एंड्रॉइड टैबलेट पर ईथरनेट मैक पते को प्राप्त करने की कोशिश कर रहा हूं जो कि वाईफाई या ईथरनेट का उपयोग कर सकते हैं। ईथरनेट मैक पते की जांच करने के बारे में कोई विचार? धन्यवाद।
सेठ

@sbrichards वाईफाई के बंद होने का क्या मतलब है?
पीटरचूला

34

मैक पते के माध्यम से WifiInfo.getMacAddress()मार्शमैलो और इसके बाद के संस्करण पर काम नहीं करेगा, इसे अक्षम कर दिया गया है और के निरंतर मूल्य02:00:00:00:00:00 को वापस कर देगा ।


3
क्या विकल्प है?
सैम

2
@SameerThigale निर्भर करता है कि आप क्या हासिल करने की कोशिश कर रहे हैं। इसके पीछे विचार यह है कि शायद आपको मैक एड्रेस प्राप्त करने की कोशिश नहीं करनी चाहिए।
मिनिफ़ाइफ़

मुझे यकीन नहीं है कि क्यों, लेकिन मुझे लिंक किए गए एपीके डॉक्टर में एक पदावनत नोट नहीं मिल सकता है। शायद उन्होंने इस बारे में अपना विचार बदल दिया?
DBX12

1
@ DBX12 विधि स्वयं को पदावनत के रूप में चिह्नित नहीं किया गया है, हालांकि यह प्रलेखित नहीं है। दूसरा लिंक इसके बारे में एक आधिकारिक नोट की ओर इशारा करता है।
मिनीपिफ

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

2
यह मुझे एंड्रॉइड 7.1 पर "02: 00: 00: 00: 00: 00" दिखाता रहता है।
Android डेवलपर

इसे एमुलेटर या वर्चुअल डिवाइस के बजाय फिजिकल डिवाइस पर टेस्ट किया जाना चाहिए
pm dubey

1
यह अभी भी काम करता है। मैनिफेस्ट फ़ाइल में इंटरनेट की अनुमति देना न भूलें।
पीएम दुबे

1
यह अब एंड्रॉइड मार्शमॉलो पर काम नहीं करता है और इसके बाद के संस्करण "02: 00: 00: 00: 00: 00"
SweArmy

1
यह काम करता हैं। मैं बहुत लंबे समय से इस कोड का उपयोग कर रहा हूं। यह अभी भी एंड्रॉइड Q.
रूपम दास

14

मैंने इस समाधान की स्थापना 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 "";
}

Im यह इसलिए है क्योंकि हमें अंतिम ":" वर्ण को निकालने की आवश्यकता है। यह कोड 2 साल पुराना है और शायद ऐसा करने का सबसे अच्छा तरीका नहीं है, आपको इसे अनुकूलित करना चाहिए
Tiziano Bruschetta

11
<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? यदि हाँ, तो किसी भी संदर्भ में काम करना चाहिए। डेवलपर
.android.com

8

मार्शमैलो के साथ इसका काम कर रहा है

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

धन्यवाद कादिर हुसैन
केशव गेरा

4

अब आप किसी Android डिवाइस का हार्डवेयर मैक एड्रेस प्राप्त नहीं कर सकते हैं। WifiInfo.getMacAddress () और BluetoothAdapter.getAddress () विधियाँ 02: 00: 00: 00: 00: 00 वापस आएँगी। यह प्रतिबंध Android 6.0 में पेश किया गया था।

लेकिन रॉब एंडरसन को एक समाधान मिला जो <Marshmallow: https://stackoverflow.com/a/35830358 के लिए काम कर रहा है


3

आप मैक पता प्राप्त कर सकते हैं:

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>

प्रश्न एंड्रॉइड डिवाइस के मैक के बारे में है, वाईफाई राउटर का नहीं।
हिना अब्बासी


2

यहां Android स्रोतों से लिया गया है । यह वास्तविक कोड है जो सिस्टम के सेटिंग ऐप में आपके मैक एड्रैस को दिखाता है।

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);) प्राप्त करने के लिए आपको एक संदर्भ की आवश्यकता होगी ।
fernandohur

5
अगर यह इस कोड को आज़माता है तो मुझे 02:00:00:00:00:00मैक एड्रेस मिल रहा है वास्तविक वाईफाई मैक आईडी नहीं
हंट

0

मुझे पता है कि यह एक बहुत पुराना सवाल है लेकिन ऐसा करने का एक और तरीका है। नीचे दिए गए कोड संकलित हैं, लेकिन मैंने इसकी कोशिश नहीं की है। मैक एड्रेस प्राप्त करने के लिए आप कुछ सी कोड लिख सकते हैं और जेएनआई (जावा नेटिव इंटरफ़ेस) का उपयोग कर सकते हैं। यहाँ उदाहरण मुख्य गतिविधि कोड है:

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>

Get_mac_addr फ़ंक्शन का 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;
}

और अंत में, 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)


-3

मुझे लगता है कि मुझे सिर्फ LOCATION अनुमति के बिना MAC पतों को पढ़ने का एक तरीका मिला: ip linkअपने आउटपुट को चलाएं और पार्स करें। (आप शायद इस बाइनरी सोर्स कोड को देखकर ऐसा ही कर सकते हैं)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.