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) {
ConnectivityManager
andNetwork
, such asopenConnection()
. Note that using multiple processes seems to be simpler (e.g.,bindProcessToNetwork()
), though you seem to prefer to avoid that solution. – Acidhead