Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify wifi network with NetworkRequest.Builder().setNetworkSpecifier(string)

I am searching for a way to let an Android 5.0 tablet connect to an intranet which does not have internet connection for security reasons.

Problem is the captive portal protection that Google build in android since 4.4/5.0. A call is done to android connectivitycheck to check for internet connection, when this call fails the wifi network is marked as not working and avoided. Pretty lame.

Others have run into the same issue and some suggest using a new API introduced in android 5, see: Android 5.0 Lollipop and 4.4 KitKat ignores my WiFi network, enableNetwork() is useless

The documentation on this is very vague:

NetworkRequest.Builder.setNetworkSpecifier(String  networkSpecifier)

"The interpretation of this String is bearer specific and bearers that use it should document their particulars. For example, Bluetooth may use some sort of device id while WiFi could used ssid and/or bssid. Cellular may use carrier spn"

I tried this and it does not work. Main problem is that once I use setNetworkSpecifier() no network is found. I tried using the bssid (mac) and the ssid of the AP.

It looks like the filter is working but its not clear how it should work. If I leave out the setNetworkSpecifier() call 1 network is found, but it is not possible to determine which. At least it shows my code works.

So what should I put in here if ssid and bssid does not work?

Here is my code.

 private void connect(String ssid, Context context) {
    Log.i(TAG, "try connect to! " + ssid);
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).
                removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED).
                removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET

                setNetworkSpecifier(ssid). //<--- here is the problem
                build();
        ConnectivityManager.NetworkCallback callback 
             = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        Log.i(TAG, "onAvailable " + network.toString() + " " + network.getClass().getName());
                }
            }

            @Override
            public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        Log.i(TAG, "onCapabilitiesChanged " + networkCapabilities.getLinkDownstreamBandwidthKbps());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        Log.i(TAG, "onLinkPropertiesChanged " + linkProperties.getInterfaceName());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        Log.i(TAG, "requestNetwork ");
        // cm.requestNetwork(nr, callback);
        cm.registerNetworkCallback(nr, callback);
    }
}
like image 797
bluevoid Avatar asked Dec 23 '15 10:12

bluevoid


1 Answers

I debugged the following code running on a Samsung S5 (SM-G900V), API 23 (6.0.1) in Android Studio.

void inspectNetworks() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ConnectivityManager connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        Network[] ns = connectivity.getAllNetworks();
        for (Network n : ns) {
            NetworkCapabilities c = connectivity.getNetworkCapabilities(n);
            Log.i(TAG, "inspectNetworks: network="+n+" capabilities="+c); // <- breakpoint
        }
    }
}

I found that Wi-Fi networks didn't have any networkSpecifier at all:

in Android Studio Debug view, mNetworkSpecifier = null

Maybe networkSpecifiers for WIFI-transport networks will be implemented in the future... For the record, I found that networkSpecifier was set to 1 on this particular phone for both existing CELLULAR-transport networks.

As for now, it seems like being as specific as possible with calls to addCapability is the best option when requesting a Wi-Fi network.

like image 178
EricRobertBrewer Avatar answered Sep 20 '22 14:09

EricRobertBrewer