23

I am developing a mobile application (iOS and Android) to control a device over Wi-Fi. The device creates a wireless network (SoftAP) but does not provide access to the internet.

On iOS, I can connect to the device and make requests to its IP address (192.168.70.1) but all other requests fall back to the mobile network. This allows the phone to maintain internet connectivity while connected to the device over Wi-Fi.

On Android, if I connect to the device wireless network, internet requests do not fall back to the mobile connection, they just fail.

In my Android app, I can use ConnectivityManager.requestRouteToHost to force requests from my app to use the mobile network. However, requests made by other apps still use the device wifi network and fail.

I have also tried to use the ConnectivityManager to change the network preference with :

ConnectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE)

This causes the phone to use the mobile network for all requests from all applications. Wi-Fi is disabled. It seems that in previous versions of Android Wi-Fi could still be used even if it is not the "preferred" network but this does not seem to work in KitKat. It is possibly related to a change in Android 4.2: https://code.google.com/p/android/issues/detail?id=73509 "ConnectivityManager since 4.2 tears down networks that are not the NetworkPreference"

Is there a solution that allows an Android app to use Wi-Fi for a specific IP address and the mobile network for everything else? Maybe this can be done via the NDK?

Halim Qarroum
  • 13,985
  • 4
  • 46
  • 71
Paul Greyson
  • 659
  • 6
  • 13
  • 1
    Did you find a solution to specify witch network you want to use on all android versions ? – DjimOnDev Apr 28 '15 at 08:00
  • 1
    No. It may be there is a solution for Lollipop but I have not had time to investigate it yet. – Paul Greyson Apr 28 '15 at 23:07
  • 1
    @PaulGreyson, how did you do this for iOS? I am looking for a similar solution to make http requests over the mobile network while the device is on wifi. – keno Jul 02 '15 at 18:44
  • 2
    on iOS it "just works" so long as the wifi router doesn't say it can route internet requests. In my case, the logic was all in udhcpd.conf on the device providing the AP where I did not provide the option subnet, domain and dns settings. iOS apparently recognizes that this means the AP is not a proper gateway and goes to LTE. – Paul Greyson Jul 03 '15 at 19:30

4 Answers4

10

Actually you can, but only since Lollipop (API 21).

From the Android API 21 Documentation:

    Android 5.0 provides new multi-networking APIs that let your app dynamically scan for available
networks with specific capabilities, and establish a connection to them. This functionality is useful
when your app requires a specialized network, such as an SUPL, MMS, or carrier-billing network, or if
you want to send data using a particular type of transport protocol.

So you can use the NetworkRequest.Builder class to create a NetworkRequest that sends the request over a certain Transport Type.

Use the following function:

NetworkRequest.Builder addTransportType(int transportType)

To set transport types (WIFI, ETHERNET or CELLULAR for example) for your requests.

Robin Eisenberg
  • 1,836
  • 18
  • 26
  • 1
    On second thought, I will need to test this to verify. The question is whether this new API can be used successfully in combination with ConnectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE) – Paul Greyson Nov 26 '14 at 15:20
  • 2
    The hope is that after requesting the wifi network, setNetworkPreference() would switch the rest of the device to the mobile network and leave the wifi network in place. – Paul Greyson Nov 26 '14 at 16:24
3

Android normally tears down the networks that are not network preference. A work-around you could use is create an AP through the mobile app and let the device connect to it. This way the mobile can maintain internet connectivity as well as communicate with the device.

Refer the following links for implementation details:

https://github.com/opengarden/android-tether

https://code.google.com/p/android-wifi-tether/

Shadab Mirza
  • 361
  • 1
  • 8
2

Similar Asked before as Enable simultaneously wifi and 3G interface on Android and quick answer was NO.

But it is actually possible and implemented in some software like SuperDownload ( see stackexchange )

That software require root.


(source: geeknizer.com)

Two channel download also is advertized in some new Android phone. (I cannot find link, they used new marketing term for WiFi+3G used together)

Is there a solution that allows an Android app to use Wi-Fi for a specific IP address and the mobile network for everything else? Maybe this can be done via the NDK?

Possibly because WiFi is needed only for local address, you could go way of making special WiFi driver, but that again, would not be simple.

And going further down into software:

this feature is TCP/IP packages routing. If you know how to implement so on Linux, you are half done. The next would be getting it work on Android. But I guess it would not be enable for non-system app, as this would be easy exploitable security whole (e.g. substitute bank server IP )

Community
  • 1
  • 1
Paul Verest
  • 60,022
  • 51
  • 208
  • 332
  • 1
    Requiring root is not an option for me nor is creating a special WiFi driver. Wrt working directly with TCP/IP routing, the question is really whether I can get the WiFi system to operate after using ConnectivityManager.setNetworkPreference to force the rest of the device over to the mobile network. – Paul Greyson Nov 26 '14 at 16:30
1

This might be a simple solution: set WiFi as preferred interface each time you need to control the device, and set mobile network preferred right after finishing the job. Doing this might interrupt concurrent Internet activities, but remind that TCP and most apps allow delay up to a few seconds (or even more). The interruption is negligible if the controlling job for your device is sporadic and never requires long-time waiting.

If the above situation is not the case, do the reverse: set WiFi as preferred interface as default, and set mobile network preferred whenever you don't have to control the device. But make sure you switch back to mobile network frequently, say every 3 seconds, to prevent timeout of your Internet activities.

Daniel
  • 619
  • 5
  • 14
  • 1
    Unfortunately this would not work in my scenario because I need to maintain a persistent TCP connection to the device. – Paul Greyson Nov 26 '14 at 16:26