Ray Tayek Ray Tayek - 17 days ago 5
Android Question

android 6.0.1 force wifi connection with no internet access

this has many similar questions (google for: "no internet access detected. won't automatically reconnect." or: android force wifi connection programmatically).

i thought i had a answer here, but it stopped working after installing 6.0.1 updates (i have may 1 security patches).

seems like this is a behaviour change.

i have some 2013 nexus 7's with 6.0.1 that run a kiosk type app and want to connect programmatically to a specific wireless network that has no internet connection. each tablet has a unique static ip address of the form: 192.168.0.xx. i use the normal java socket constructors and check to see if the interface is up using: NetworkInterface.getNetworkInterfaces().

a manual connection has been made. sometimes there is a dialog that asks whether or not you want to always connect. i always check yes.

but the wifi says: "no internet access detected. won't automatically reconnect" after the router cycles power.

doing a disconnect, enable, reconnect does not work. at best it gets: ip6-localhost/::1.

has anyone had any luck using a request object, or bindProcessToNetwork?

edit: related.

edit: the problem seems to be with: CAPTIVE_PORTAL_DETECTION_ENABLED - this string seems to be defined in the source:

public static final String
CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
...
MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED);


but throws" android.provider.Settings$SettingNotFoundException: captive_portal_detection_enabled when used explicitly and is not visible to android studio.

also, doing a settings list global does not contain the constant.

edit doing a adb shell settings put global captive_portal_detection_enabled 0 does seem to work, but this can not be done in the field when the router cycles power. this value seems to persist when the tablet cycles power. and now this value shows up in a settings list global. also, using the raw string: Settings.Global.getInt(getContentResolver(),"captive_portal_detection_enabled"); now returns 0.

edit: looks like setting it requires: android.permission.WRITE_SECURE_SETTINGS, but of course this fails when put into the manifest since we are not a system app.

edit: trying to exec the shell command throws: java.lang.SecurityException, so it looks like you need to issue the command from adb :(

thanks

Answer

Could you try and set the global 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);

You can do it through adb for testing purposes:

adb shell settings put global captive_portal_detection_enabled 0

And retrieve it's value like this:

adb shell settings list global | grep "captive"

IMHO this is not very nice thing to do, since you are changing a setting for the user and many FWs don't provide even an advanced setting to enable/disable this by the user itself. (Google doesn't). But maybe it suites your needs.

Hope it helps!