问题
I'm developing an Android application which connects to an OBD2 device by Wifi and app can read Speed, RPM, Engine coolant temperature details etc. So wifi is used only for connecting with the OBD2 device(it doesn't have facility to connect with internet, only for communication with local clients). I also need an internet connection for web services. But after connecting my wifi I am not able to connect internet via my mobile data network in android.
The similar application is also developed for iOS. In iOS, I can use device over Wifi (Static Wifi setting) and Internet connection from my cellular network. It means configure my wifi with some static ip I am able to use mobile data network for Internet connection in iOS.
But in Android, If I use static wifi and check for Internet connection, it is not available.
How can I use Wifi and Internet connection both run parallel or any other way by configuring wifi settings in android ?
回答1:
connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
You can request for a certain hostAddress that it must use that type of connectivity. IF you use Hipri then it will take the mobile network. But this can fail ! If it works, then ALL connections to that address will go over that type of connectivity.
You might have to activate it first.
int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
This can take a couple of seconds, since the hardware modules has to start up.
I've use this on several projects and works great. On old device such as 2.2 it will react really unstable ! But I haven't found any problems on 4.0+
回答2:
Firstly, the problem we may face here is that because there is no internet connection on WiFi network, HTTP data will not go through that connection. See Send request over WiFi (without connection) even if Mobile data is ON (with connection) on Android M for solution
However, I have faced issue where sometimes no HTTP request is successful. To solve this problem, we can use ConnectivityManager.requestNetwork() and Network.openConnection() to achieve this.
Make sure that Mobile data and WiFi network is enabled and Android Manifest has proper connections:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
Variables:
private ConnectivityManager.NetworkCallback mWifiNetworkCallback, mMobileNetworkCallback;
private Network mWifiNetwork, mMobileNetwork;
Get the connectivity manager:
final ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
Build network callbacks:
if(mWifiNetworkCallback == null){
//Init only once
mWifiNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(final Network network) {
try {
//Save this network for later use
mWifiNetwork = network;
} catch (NullPointerException npe) {
npe.printStackTrace();
}
}
};
}
if(mMobileNetworkCallback == null){
//Init only once
mMobileNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(final Network network) {
try {
//Save this network for later use
mMobileNetwork = network;
} catch (NullPointerException npe) {
npe.printStackTrace();
}
}
};
}
Request networks:
NetworkRequest.Builder wifiBuilder;
wifiBuilder = new NetworkRequest.Builder();
//set the transport type do WIFI
wifiBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
manager.requestNetwork(wifiBuilder.build(), mWifiNetworkCallback);
NetworkRequest.Builder mobileNwBuilder;
mobileNwBuilder = new NetworkRequest.Builder();
//set the transport type do Cellular
mobileNwBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
manager.requestNetwork(mobileNwBuilder.build(), mMobileNetworkCallback);
Make the appropriate request like this:
public void makeHTTPRequest(final String httpUrl, final String payloadJson, final int timeout,
final boolean hasHeaders, final String header1, final String header2) {
try {
URL url = new URL(httpUrl);
HttpURLConnection conn = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
conn = (HttpURLConnection) mWifiNetwork.openConnection(url);
//Or use mMobileNetwork, if and when required
//conn = (HttpURLConnection) mMobileNetwork.openConnection(url);
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestProperty("Content-Type", "application/json");
conn.setReadTimeout(timeout * 1000);
conn.setConnectTimeout(timeout * 1000);
conn.setDoInput(true);
conn.setDoOutput(true);
if(hasHeaders){
conn.setRequestProperty("header1", header1);
conn.setRequestProperty("header2", header2);
}
conn.setRequestMethod("PUT");
OutputStream os = conn.getOutputStream();
os.write(payloadJson.getBytes());
os.close();
final int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
final String statusMessage = conn.getResponseMessage();
//Log this
}
} catch (SocketException se){
se.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
Note:
These functions are avaialble from Android Lollipop and above. So, it is necessary to use Build.Version.SDK_INT
at appropriate place, like this:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
来源:https://stackoverflow.com/questions/24429190/make-android-simultaneously-use-wifi-to-talk-to-a-device-and-mobile-data-to-talk