簡體   English   中英

如何獲取連接到wifi熱點的客戶端設備詳細信息?

[英]How to get the client device details which is connected to wifi hotspot?

我在我的 android 應用程序中以編程方式將不同的設備與 wifi 熱點 AP 連接,如何以編程方式檢測客戶端連接和斷開連接以及到 wifi 熱點 AP? Android API 中是否有任何回調事件來提供有關單個設備的連接或斷開連接事件的信息? 提前致謝。

不幸的是,沒有公共 API 可以提供有關此信息的信息……但是您可以閱讀 /proc/net/arp 文件並查看連接到您的接入點的客戶端。

/proc/net/arp 文件有 6 個字段: IP 地址硬件類型標志硬件地址掩碼設備

問題是當客戶端斷開連接時,因為它不會從文件中消失。 一個解決方案可能是對每個客戶端執行ping並等待響應,但對我來說這不是一個好的解決方案,因為有些客戶端不響應ping 如果您喜歡此解決方案,請在 GitHub 上查看此項目 --> https://github.com/nickrussler/Android-Wifi-Hotspot-Manager-Class/tree/master/src/com/whitebyte

我所做的是:讀取 /proc/net/arp 並檢查FLAGS字段,當值為 0x2 時表示站已連接而 0x0 已斷開連接,但要刷新此字段,我需要不時清除 ARP 緩存,並且我用這個命令做到了: ip neigh flush all

我希望我能幫助你

這種方法對我有用,但這只檢測到 4.0 及更高版本; 無法找到連接熱點的2.2或2.3版本的設備。

public void getClientList() {
    int macCount = 0;
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null) {
            String[] splitted = line.split(" +");
            if (splitted != null ) {
                // Basic sanity check
                String mac = splitted[3];
                System.out.println("Mac : Outside If "+ mac );
                if (mac.matches("..:..:..:..:..:..")) {
                    macCount++;
                   /* ClientList.add("Client(" + macCount + ")");
                    IpAddr.add(splitted[0]);
                    HWAddr.add(splitted[3]);
                    Device.add(splitted[5]);*/
                    System.out.println("Mac : "+ mac + " IP Address : "+splitted[0] );
                    System.out.println("Mac_Count  " + macCount + " MAC_ADDRESS  "+ mac);
                Toast.makeText(
                        getApplicationContext(),
                        "Mac_Count  " + macCount + "   MAC_ADDRESS  "
                                + mac, Toast.LENGTH_SHORT).show();

                }
               /* for (int i = 0; i < splitted.length; i++)
                    System.out.println("Addressssssss     "+ splitted[i]);*/

            }
        }
    } catch(Exception e) {

    }               
}

Android 10限制了訪問/proc/net目錄的權限,所以上面的一些解決方案不再可行,但'ip'命令仍然可用

private fun getARPIps(): List<Pair<String, String>> {
    val result = mutableListOf<Pair<String, String>>()
    try {
//        val args = listOf("ip", "neigh")
//        val cmd = ProcessBuilder(args)
//        val process: Process = cmd.start()
      val process = Runtime.getRuntime().exec("ip neigh")
        val reader = BufferedReader(InputStreamReader(process.inputStream))
        reader.forEachLine {
            if (!it.contains("FAILED")) {
                val split = it.split("\\s+".toRegex())
                if (split.size > 4 && split[0].matches(Regex("([0-9]{1,3}\\.){3}[0-9]{1,3}"))) {
                    result.add(Pair(split[0], split[4]))
                }
            }
        }
        val errReader = BufferedReader(InputStreamReader(process.errorStream))
        errReader.forEachLine {
            Log.e(TAG, it)
            // post the error message to server
        }
        reader.close()
        errReader.close()
        process.destroy()
    } catch (e: Exception){
        e.printStackTrace()
        // post the error message to server
    }
    return result
}
@SuppressWarnings("ConstantConditions")
public static String getClientMacByIP(String ip)
{
    String res = "";
    if (ip == null)
        return res;

    String flushCmd = "sh ip -s -s neigh flush all";
    Runtime runtime = Runtime.getRuntime();
    try
    {
        runtime.exec(flushCmd,null,new File("/proc/net"));
    }

    BufferedReader br;
    try
    {
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null)
        {
            String[] sp = line.split(" +");
            if (sp.length >= 4 && ip.equals(sp[0]))
            {Assistance.Log(sp[0]+sp[2]+sp[3],ALERT_STATES.ALERT_STATE_LOG);
                String mac = sp[3];
                if (mac.matches("..:..:..:..:..:..") && sp[2].equals("0x2"))
                {
                    res = mac;
                    break;
                }
            }
        }

        br.close();
    }
    catch (Exception e)
    {}

    return res;
}

//------------------------------------------------ --------

@SuppressWarnings("ConstantConditions")
public static String getClientIPByMac(String mac)
{
    String res = "";
    if (mac == null)
        return res;

    String flushCmd = "sh ip -s -s neigh flush all";
    Runtime runtime = Runtime.getRuntime();
    try
    {
        runtime.exec(flushCmd,null,new File("/proc/net"));
    }

    BufferedReader br;
    try
    {
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null)
        {
            String[] sp = line.split(" +");
            if (sp.length >= 4 && mac.equals(sp[3]))
            {
                String ip = sp[0];
                if (ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}") && sp[2].equals("0x2"))
                {
                    res = ip;
                    break;
                }
            }
        }

        br.close();
    }
    catch (Exception e)
    {}

    return res;
}

您可以使用 BroadcastReciever "android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED" 來檢測客戶端連接。 在您的 AndroidManifest 中:

<receiver
            android:name=".WiFiConnectionReciever"
            android:enabled="true"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED" />
            </intent-filter>
        </receiver>

在你的活動中

IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED");
                        rcv = new WiFiConnectionReciever();
                        registerReceiver(rcv,
                                mIntentFilter);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM