I have been working in this for quite some time and i am able to make it work in all the makes and devices except in some of the Samsung devices that run Marshmallow and above.
Here is the flow. I have an OBD which can be connected through wifi and once connected i can start reading the data through my application by opening a socket/telnetclient to its ip which will be like 192.168.4.1 and port is 23. This is the goal. Point to be noted is that this OBD doesn't have an internet connection.
Here is what happens.
I connect to the OBD through the WifiManager.
Now I try to open a socket to the IP 192.168.4.1 and Port 23.
Here is the code:
import java.net.Socket;
Socket socket = new Socket("192.168.4.1", 23);
At this time if the mobile data is enabled, the socket connection will try to find the ip through the mobile data gateway since now the wifi will not be having an internet connection and only the mobile data has the possibility of an internet connection it will have the higher priority.
Since the IP is reachable only thorugh the wifi, I point the gateway of the ConnectivityManager through the following code as openWifiPort(true):
public void openWifiPort(boolean openState){
final ConnectivityManager connectivityManager
= (ConnectivityManager) AppController.getInstance().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (SDK_INT >= LOLLIPOP) {
NetworkRequest.Builder request = new NetworkRequest.Builder();
if(openState) {
request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
} else {
request.addTransportType(ConnectivityManager.TYPE_MOBILE);
request.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
}
connectivityManager.registerNetworkCallback(request.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (SDK_INT >= LOLLIPOP && SDK_INT < M) {
//noinspection deprecation
ConnectivityManager.setProcessDefaultNetwork(network);
} else if (SDK_INT >= M) {
connectivityManager.bindProcessToNetwork(network);
}
}
});
}
}
Now the getway gets pointed to Wifi and I am able to open the socket to the OBD and I am able to interact with the device from my application. Since the gateway has been pointed to the wifi and the OBD doesn't have an internet access I will not be able to use the internet even though mobile data is switched on.
To enable this, once the socket gets connected, I switch the gateway back to mobile by calling the same method but this time the parameter is false ie. openWifiPort(false).
This is what it gets tricky. This switch is working in all the mobile devices irrespective of the make, model and android versions. But this switch is not working in some devices of Samsung.
Any advice on this really appriciated. Thanks in advance.