14

Is it possible to force an Android application to use only the mobile radio connection (3g/4g/etc), disallowing the use of WiFi?

I think I want to use a HIPRI connection: (ex: WIFI turned on, use HIPRI 3G): http://groups.google.com/group/android-developers/browse_thread/thread/d41f85505484d29b

neteinstein
  • 17,529
  • 11
  • 93
  • 123
wuntee
  • 12,170
  • 26
  • 77
  • 106
  • Possible duplicate of [How to use 3G Connection in Android Application instead of Wi-fi?](https://stackoverflow.com/questions/2513713/how-to-use-3g-connection-in-android-application-instead-of-wi-fi) – rogerdpack Sep 23 '17 at 13:13

5 Answers5

10

I don't believe you can "force" the connection path without explicitly turning off the Wi-Fi radio temporarily (not recommended). However, you could try setting the network preference during the period you want this to occur:

ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
//Prefer mobile over wifi
cm.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);

//Do your work

//Remove your preference
cm.setNetworkPreference(ConnectivityManager.DEFAULT_NETWORK_PREFERENCE);

Hope that Helps!

devunwired
  • 62,780
  • 12
  • 127
  • 139
  • 2
    As far as my testing has seen. In the source for ConnectivityService, you can see that setting this preference causes the system to attempt to teardown any non-preferred networks that are connected, so it's doing what we'd expect to happen. http://codesearch.google.com/codesearch#uX1GffpyOZk/services/java/com/android/server/ConnectivityService.java – devunwired Nov 07 '11 at 20:38
  • This example is a bit old. Updated to use the proper constant for resetting the preference back to defaults. – devunwired Nov 07 '11 at 20:39
  • This flip-flops connections whatever. Sad thing or I need more tryings? I need use a TCP connection? Because the system sends me an answer into another socket! I send request thru one, and receive reply thru another! Seems like Android changes IP address of an explicitly binded socket. Hate all those people who hates UDP and binds their sockets on 0.0.0.0. :-) Google, they are bad coders, not mine! Why do you hear them but not me? Sad times. Apocalypse. – Brian Cannard Apr 30 '15 at 23:55
  • 3
    setNetworkPreference() is deprecated in API level 21 http://developer.android.com/reference/android/net/ConnectivityManager.html#setNetworkPreference(int) – Code_Yoga Mar 23 '16 at 09:53
4

In Android 2.2 you can use high-priority mobile data at the same time as WiFi. The value of the "feature" parameter is "enableHIPRI", and is hidden in the Phone API.

Method: ConnectivityManager.startUsingNetworkFeature(int networkType, String feature) of http://developer.android.com/reference/android/net/ConnectivityManager.html

Source: http://code.google.com/p/android/issues/detail?id=5885

You could check this other answer: https://stackoverflow.com/a/4756630/327011

This is NOT a good policy...use it if REALLY needed!

Community
  • 1
  • 1
neteinstein
  • 17,529
  • 11
  • 93
  • 123
  • As a user you expect the phone to only access Mobile data when if WiFi is disconnected. If this works correctly you may increase mobile data costs without the user knowing it, or being able to prevent it. – neteinstein Apr 22 '15 at 09:34
  • No, incorrect -- as a user, I expect that my SIP *actually works*, and WiFi cannot guarantee it, so, I choose the option to only use 3G. However, as per http://android.stackexchange.com/questions/61554/is-there-a-way-for-3g-to-not-disconnect-when-connecting-to-wifi, I now don't have any SIP at all when WiFi is connected. Is it a bug in the app, or is it something that cannot be fixed within an app? – cnst Apr 22 '15 at 14:41
  • It doesn't work. It flip-flops and just allows those sockets which were opened and binded on 3G IPs to continue work on ANOTHER, Wi-Fi IPs. Those crazy mad bandits in Google thinks that it is great to broke CLASSIC BERKELEY SOCKETS. hackers, look what you may crack here! ;-) – Brian Cannard Apr 30 '15 at 23:59
1

ConnectivityManager.setNetworkPreference() is close to be obsoleted. But what is more important, if you do getNetworkPreference() before changing, it will return ConnectivityManager.TYPE_MOBILE. Setting it there does not make any difference. As for HIPRI itself, it works in pretty strange mode. First, it allows connections to all hosts, not only to those explicitly requested. Second, when you turn it off with stopUsingFeature...() call, it will not be turned off and will be still active. Third, all device applications start using it even if wifi is available, which contradicts to what is said in documentation.

Cynichniy Bandera
  • 5,991
  • 2
  • 29
  • 33
0

Try to look at this, it has a lot of info and may have solution you are looking for: How to use 3G Connection in Android Application instead of Wi-fi?

It has working service example that sets up the HIPRI mobile connection and keeps it running. AFAIK this is the only more or less straightforward way to have working wifi and 3g in android. The only drawback is that, this connection will allow only data transmission to servers that routing was explicitly requested to. This basically means that you cannot route to many servers because lookup host by name to get ip address takes time and doing it for 10 servers will take 30-60 sec, which makes it start slowly. So you should know exactly what servers should be available via mobile connection.

Community
  • 1
  • 1
Cynichniy Bandera
  • 5,991
  • 2
  • 29
  • 33
  • Note that [link-only answers are discouraged](http://meta.stackoverflow.com/tags/link-only-answers/info), SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference. – kleopatra Dec 22 '13 at 10:00
0

(I answered this same question here)

You can't explicitly force the communications channel on a per-app basis (you can request to use a preferred mode via ConnectivityManager.setNetworkPreference(...), but that's not "forcing").

Though it's probably terrible UX, you can inform the user that your app disallows use of WiFi, then disable their WiFi if they want to continue. To do so, you need the ACCESS_WIFI_STATE and CHANGE_WIFI_STATE permissions. The code would look something like this:

manager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);

if(manager.isWifiEnabled()) {
    manager.setWifiEnabled(false);
}
// and to be sure:
ConnectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);
Community
  • 1
  • 1
Chris Cashwell
  • 22,308
  • 13
  • 63
  • 94
  • ConnectivityManager.setNetworkPreference() is close to be obsoleted. But what is more important, if you do getNetworkPreference() before changing, it will return ConnectivityManager.TYPE_MOBILE. Setting it there does not make any difference. – Cynichniy Bandera Nov 26 '13 at 15:41