Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Android to Use Wifi network with no internet

I am building an android app that needs to communicate over a WiFi network that will not have any internet access. The problem is that even when the WiFi is connected android chooses to use cellular/mobile data when no connection internet is present on the wifi network.

I have read many posts on the issue many of which involve rooting the device but that is not possible with a production app (rooting devices is not an option). other solution (like my code bellow) suggest using bindProcessToNetwork() which works perfectly on my Sony Z2 but not on other devices I have tested on (all running 6.0.1)

private void bindToNetwork() {
    final ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        builder = new NetworkRequest.Builder();
        //set the transport type do WIFI
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
        connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


                    connectivityManager.bindProcessToNetwork(null);
                    if (barCodeData.getSsid().contains("ap-name")) {
                        connectivityManager.bindProcessToNetwork(network);
                    }

                } else {
                    //This method was deprecated in API level 23
                    ConnectivityManager.setProcessDefaultNetwork(null);
                    if (barCodeData.getSsid().contains("ap-name")) {

                        ConnectivityManager.setProcessDefaultNetwork(network);
                    }
                }

                connectivityManager.unregisterNetworkCallback(this);
            }
        });
    }
}
like image 209
Lonergan6275 Avatar asked Feb 27 '17 17:02

Lonergan6275


People also ask

How can I force my Android to connect to Wi-Fi without internet?

There are two choices - 1) Switch to mobile data or 2) Another network. If we select either option, we are disconnected from the wifi network without internet. If we do nothing (select neither option) and let the pop up disappear after 10 seconds, we remain connected to the wifi network without internet.

How do I force my phone to connect to Wi-Fi?

Go to the Policies tab, you can either create a new policy or edit an already existing one. Navigate to Android–> Restrictions–> Allow Network Settings. Enable the 'Force Bluetooth' option to prevent the users from turning OFF the blue tooth and the 'Force Wi-Fi' option to prevent turning OFF the Wi-Fi.


3 Answers

You can solve this by setting captive_portal_detection_enabled to 0 (false).

What's actually happening is that by default, everytime you connect to a wifi, the FW will test against a server (typically google) to see if it's a captive wifi (needs login). So if your wifi is not connected to google, this check will fail. After that, the device knows that wifi has no internet connection and simply will not autoconnect to it.

Setting this setting to 0 will avoid this check.

Programatically: Settings.Global.putInt(getContentResolver(), Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 0);

Edit: You may need to use the string "captive_portal_detection_enabled" directly, instead of the constant that's not visible depending on Android version.

like image 182
lax1089 Avatar answered Oct 19 '22 13:10

lax1089


you'd need to disable mobile data in the Settings (not certain, if this can be done programmatically, which might be a possible option) - or take out the USIM;

else the common behavior is, that it will always fall back to the best available connection (while a connection with internet gateway might be preferred, because it is used by most application).

also see this answer.

like image 2
Martin Zeitler Avatar answered Oct 19 '22 11:10

Martin Zeitler


Solution on Kotlin

class ConnectWithoutInternetTest constructor(
private val mContext: Context,
private val connectivityManager: ConnectivityManager,
private val wifiManager: WifiManager
) {

private val mWifiBroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        when (intent.action) {
            WifiManager.NETWORK_STATE_CHANGED_ACTION -> {
                val info = intent.getParcelableExtra<NetworkInfo>(WifiManager.EXTRA_NETWORK_INFO)
                val isConnected = info.isConnected

                val ssid: String? = normalizeAndroidWifiSsid(wifiManager.connectionInfo?.ssid)

                if (isConnected) {
                    val builder = NetworkRequest.Builder()
                    builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    connectivityManager.registerNetworkCallback(
                        builder.build(),
                        object : ConnectivityManager.NetworkCallback() {
                            override fun onAvailable(network: Network) {
                                super.onAvailable(network)
                                val networkInfo = connectivityManager.getNetworkInfo(network)
                                val networkSsid = networkInfo.extraInfo
                                if (networkSsid == ssid) {
                                    connectivityManager.unregisterNetworkCallback(this)
                                }
                            }
                        })
                }
            }
        }
    }
}

private fun init() {
    val intentFilter = IntentFilter()
    intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
    mContext.registerReceiver(mWifiBroadcastReceiver, intentFilter)
}

private fun destroy() {
    mContext.unregisterReceiver(mWifiBroadcastReceiver)
}

private fun normalizeAndroidWifiSsid(ssid: String?): String? {
    return ssid?.replace("\"", "") ?: ssid
}

fun connectToWifi(ssidParam: String, password: String?) {
    init()
    val ssid = "\"$ssidParam\""
    val config = wifiManager.configuredNetworks.find { it.SSID == ssid }
    val netId = if (config != null) {
        config.networkId
    } else {
        val wifiConfig = WifiConfiguration()
        wifiConfig.SSID = ssid
        password?.let { wifiConfig.preSharedKey = "\"$password\"" }
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
        wifiManager.addNetwork(wifiConfig)
    }

    wifiManager.disconnect()
    val successful = wifiManager.enableNetwork(netId, true)
}
like image 1
Vadym Avatar answered Oct 19 '22 11:10

Vadym