20

I'm working on an application that will run on a phone where the phone will be a station on a private Wi-Fi network. The phone will be a station, not an access point, and the private Wi-Fi network does not route to the Internet. My application needs to communicate with servers on the Internet as well as devices on the local Wi-Fi network, so it needs to have connections on both networks at the same time. I've been trying to figure out how to do this.

I've been trying the technique described in the discussion on the Google Android developers group titled "Can Android 2.X connect to 3G and Wifi data networks simultaneously?", but it is not working well. What I find is that, when I enable the cellular network by calling ConnectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE), any sockets I have open on the Wi-Fi network are closed. I haven't tried it, but I suspect the same thing will happen to sockets on the cellular network when I switch back to Wi-Fi.

Another problem is that, these calls operate on a global level, changing the network settings for the entire phone, not just the application. Switching the network set up globally like this will interfere with any other app that happens to be running on the phone. Even after my application exits, the phone continues to run with the last network configuration it set.

I'm looking for a way to have connections open on both the cellular data and Wi-Fi networks at the same time, and without interfering with other applications running on the phone.

  1. Does anyone know how to do this?
  2. Does anyone know if this is possible?
Nimantha
  • 6,405
  • 6
  • 28
  • 69
digiGuy
  • 201
  • 1
  • 2
  • 3

9 Answers9

2

This is actually pretty simple. You need to file two requests; one for a network with the cellular transport type and an additional request with the wifi transport type. Then, with whatever networks are returned from those requests, you can use them as needed (e.g. only do work on the internal resources with the network returned from the wifi request).

Here is an example to keep both Wi-Fi and Cellular up at the same time:

final ConnectivityManager connectivityManager = (ConnectivityManager)
  context.getSystemService(Context.CONNECTIVITY_SERVICE);

final NetworkRequest requestForWifi =
  new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
  .build();

final NetworkRequest requestForCellular =
  new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
  .build();

final NetworkCallback cbWifi = new NetworkCallback() {
  @Override
  void onAvailable(Network network) {
      // Triggers when this network is available so you can bind to it.
      
      // Examples of how to bind to it include 
      // (uncomment the best option for your use-case):
      
      // If you want to set connections for the entire app
      // connectivityManager.bindProcessToNetwork(network);

      // If you want to open a specific connection:
      // By socket:
      // try (Socket socket = new Socket()) {
      //     Network network = getNetwork();
      //     network.bindSocket(socket);
      // }
      // Or by URL:
      // URLConnection conn = network.openConnection(URL url);
  }
};

final NetworkCallback cbCellular = new NetworkCallback() {
  @Override
  void onAvailable(Network network) {
      // Triggers when this network is available so you can bind to it.
  }
};

connectivityManager.requestNetwork(requestForWifi, cbWifi);
connectivityManager.requestNetwork(requestForCellular, cbCellular);

As long as there are requests for a particular network type (i.e. Wi-Fi or Cellular), ConnectivityService (service that ConnectivityManager relies on) will keep those networks up if available. Therefore using the above pattern but tweaking the NetworkRequest object to meet your needs, you can keep any number of networks up.

Always Learning
  • 2,623
  • 3
  • 20
  • 39
1

This thread Android: Force data to be sent over radio vs WiFi mentions two possible approaches to the problem.

  1. Set the network preference whenever you want your app to use a specific connection:

    ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    cm.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);
    
  2. Enable high priority mobile data connection:

    connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
    

For the second approach it is specifically stated it works with Android 2.2, no idea if this works in actual versions as well. However as far as I found out, enableHIPRI is more or less a hidden network setting, so I would prefer the first method if possible.

Community
  • 1
  • 1
nanoquack
  • 949
  • 2
  • 9
  • 26
0

Without root access the app cannot influence much.

With Android API what you can do at most is just turn on WiFi in hope that the device will switch to it and turn WiFi off to make the device switch to 3G (if it's there, the APN is correct etc.).

Anything else is not guaranteed to work. E.g. setting preferred connectivity type doesn't guarantee that the device will switch to that type.

The usual behavior is that as soon as WiFi becomes available, the device will have both 3G and WiFi on for a short while (3-5 secs) and then turn off 3G. As soon as WiFi is turned off by the user or your app, and the device attempts to connect to the Internet, it will turn on 3G after a short while.

Starting with Android 2.3 you can't event disable/enable 3G anymore. One used to spoil/restore APN settings to enable/disable 3G, but starting with 4.0 you can't change APN settings programmatically.

iseeall
  • 3,381
  • 9
  • 34
  • 43
  • Not quite - it is still possible to manually disable 3G. Just open the dialer and enter `*#*#4636#*#*`. Then tap "Phone Information" and "Turn off radio". – Nathan Osman Mar 17 '16 at 01:14
0

I think only one service is possible at a time. Either you can use WiFi or you can use use Cellular 3G Data. Both can't work simultaneously at a time.

Sumit Sharma
  • 1,847
  • 1
  • 22
  • 25
0

The 3G and Wifi data networks can not connect at the same time, but 3G and Wifi can be connected simultaneously if the operator support and the android framework also change for the operator. Now some operators already have this feature but some can not.

lqsohu
  • 1
  • 1
0

Using both network at a time is not possible in Android App at present but you can do this in PC.
Connect one from your WIFI router and one from LAN or USB Internet Stick.
So create APp and use on PC. If you do not know how to run Android on PC than google it.

Andre Silva
  • 4,782
  • 9
  • 52
  • 65
0

If I am not mistaken, if both Wi-Fi and 3G/4G is available, Wi-Fi will take the precedence.

Only when Wi-Fi is not available, it will switch to 3G/4G. Of course this provided both are switched on at the same time.

Instead of using a private Wi-Fi thus limiting your choice you may consider having a internet facing VPN, so that the device will connect to the VPN from 3G/4G and than subsequently access the data if security is your concern for using private Wi-Fi.

And VPN clients are inbuilt in Android and there are also third party clients available.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
aandroidtest
  • 1,493
  • 8
  • 41
  • 68
0

You might want to look into ad-hoc wifi networks. It connects to devices over wifi even if the droid is already using wifi for internet (does not use the ip stack, though).

Dont confuse wifi (IEEE 802.11x) connections with internet (IP) connections. IP can run on wifi, mobile, ethernet, DSL, dailup or homing pigeons, but only one network at a time.

For more information on ad-hoc wifi networks, have a look at the following link.

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

Please note that many carriers forbid multicasting (sharing) their IP connections. Nice.

Dominic Cerisano
  • 3,522
  • 1
  • 31
  • 44
0

If you can't make it using API calls and if you are willing to get your hands dirty with the lower level, some linux knowledge may help. Basically what you have to do is to bring up both interfaces and have the default route set on the 3g interface. You will have to use system commands with root privileges for this kind of task. The reason for the close sockets is probably the interface that goes down and up again because of the API call.

ApriOri
  • 2,618
  • 29
  • 48