安卓WIFI如何检测特定WIFI连接是否可用

29

我需要检测我是否连接上了一个特定的WIFI网络。

例如:当您进入家门,手机自动连接上您家中的WiFi网络时,我希望能够收到一条通知,提示“您目前不在家中网络范围内,是否想要连接到您的家庭网络?”但我只希望在我特定的房子里发生这种情况。

我应该监听什么以及应该进行什么测试来确保它是我的特定家庭网络,而不是其他网络?


代码片段可以提取连接的WiFi、设备上存储的网络以及设备“视野”中可用的网络。 - tony gil
4个回答

30

您可以使用BroadcastReceiver来检测Wi-Fi网络是否已更改:

BroadcastReceiver broadcastReceiver = new WifiBroadcastReceiver();

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
context.registerReceiver(broadcastReceiver, intentFilter);

BroadcastReceiver可能看起来像这样。 要检查特定的MAC地址,请参见下面的checkConnectedToDesiredWifi()方法。

public class WifiBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION .equals(action)) {
            SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
            if (SupplicantState.isValidState(state) 
                    && state == SupplicantState.COMPLETED) {

                boolean connected = checkConnectedToDesiredWifi();
            }
        }
    }

    /** Detect you are connected to a specific network. */
    private boolean checkConnectedToDesiredWifi() {
        boolean connected = false;

        String desiredMacAddress = "router mac address";

        WifiManager wifiManager = 
            (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

        WifiInfo wifi = wifiManager.getConnectionInfo();
        if (wifi != null) {
            // get current router Mac address
            String bssid = wifi.getBSSID();
            connected = desiredMacAddress.equals(bssid);
        }

        return connected;
    }
}

12

只要我们不像“为免费服务而编写需要的代码”那样,我只能建议您在创建这种应用程序时尽可能阅读有关Android及其网络/Wifi功能的所有内容。

  • 您应该阅读和学习的资源

http://developer.android.com/reference/android/net/wifi/package-summary.html
如何查看Android是否已连接Wifi
如何在当前Android系统中获取我的Wifi热点SSID
如何通过Android API从Android中获取Wifi网络的名称?
在Android上获取Wifi接口名称

  • 在创建应用程序清单时应请求的权限

AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

(如果你希望它检测你的位置以防止不必要的调用,那么它只会获取最后一个。)

  • 你还应该声明,你的应用程序需要设备上有可用的Wi-Fi才能正常工作:

AndroidManifest.xml

<uses-feature android:name="android.hardware.wifi" />

1
嘿,非常感谢。我会仔细阅读这些内容。这是我在stackoverflow上的第一个问题。感谢您的回复。 - ECH5030
1
@ECH5030 您好,不用客气。请记得将一些答案标记为已接受,这是您可以执行的操作。这是关闭问答社区帖子常见的方式 :) - Marek Sebera

4
使用标准代码列出所有可用网络:
  • start the scan

    String connectivity_context = Context.WIFI_SERVICE;
                final WifiManager wifi = (WifiManager) getSystemService(connectivity_context);  
    if (wifi.isWifiEnabled()) {
                            wifi.startScan();
                        }
    
  • register a receiver for the data

    IntentFilter i = new IntentFilter();
    i.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent i) {
            // TODO Auto-generated method stub
            ScanWiFiActivity a = ScanWiFiActivity.instance();
            WifiManager w = (WifiManager) context
                    .getSystemService(Context.WIFI_SERVICE);
            List<ScanResult> l = w.getScanResults();
            a.Clear();
            for (ScanResult r : l) {
                                  //use r.SSID or r.BSSID to identify your home network and take action
                a.setText(r.SSID + "" + r.level + "\r\n");
            }
        }
    };
    registerReceiver(receiver, i);
    
在FOR循环块中发挥你的魔力,当你通过SSID或BSSID识别出你的网络时采取行动。

4

我曾经为我的一个项目遇到了完全相同的问题,花费了一些时间才找到解决方案。

首先,“连接到WiFi”是非常抽象的事情,这是正确的。实际上,人们通常指以下所有内容:

  • 使用WiFi接入点进行身份验证
  • 与接入点相关联
  • 从网络中获取IP地址

所有这些阶段(以及更多)都与不同的Android事件相关联。因此,没有多余的话,这是我(稍作修改)的代码:

public class MyService extends Activity { // or Service

    //... Other stuff

    BroadcastReceiver awaitIPAddress = null;
    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
                if (intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE) == SupplicantState.COMPLETED) {
                    //WiFi is associated
                    WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                    WifiInfo wi = wifiManager.getConnectionInfo();
                    if (wi != null) {
                        // Wifi info available (should be, we are associated)
                        if (wi.getIpAddress() != 0) {
                            // Lucky us, we already have an ip address.
                            // This happens when a connection is complete, e.g. after rekeying
                            if (wi.getBSSID().equals("c0:ff:ee:c0:ff:ee")) {
                                // ... Do your stuff here
                                // ...
                                // ...
                            }
                        } else {
                            // No ip address yet, we need to wait...
                            // Battery friendly method, using events
                            if (awaitIPAddress == null) {
                                awaitIPAddress = new BroadcastReceiver() {
                                    @Override
                                    public void onReceive(Context ctx, Intent in) {
                                        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                                        WifiInfo wi = wifiManager.getConnectionInfo();
                                        if (wi != null) {
                                            if (wi.getIpAddress() != 0) {
                                                if (wi.getBSSID().equals("c0:ff:ee:c0:ff:ee")) {
                                                    // ... Do your stuff here
                                                    // ...
                                                    // ...
                                                }
                                            }
                                        } else {
                                            ctx.unregisterReceiver(this);
                                            awaitIPAddress = null;
                                        }
                                    }
                                };
                                // We register a new receiver for connectivity events
                                // (getting a new IP address for example)
                                context.registerReceiver(awaitIPAddress, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
                            }
                        }
                    }
                } else {
                    // wifi connection not complete, release ip address receiver if registered
                    if (awaitIPAddress != null) {
                        context.unregisterReceiver(awaitIPAddress);
                        awaitIPAddress = null;
                    }
                }
            }
        }
    };

    //... Other stuff

    @Override
    public void onCreate() {
        super.onCreate();
        //... Other stuff
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        registerReceiver(receiver, filter);
        //... Other stuff
    }

    //... Other stuff

}

另外,不要忽略授予清单文件适当的权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

我强烈怀疑你也需要以下内容:
<uses-permission android:name="android.permission.INTERNET"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接