问题
I'm writing a client application for my action camera. There's an issue using network connections when smartphone connected to wifi and mobile network: Android determines, that wifi does not connected to internet, so all requests passed to mobile network interface. I've already implemented the client API, that uses pre-bounded sockets to communicate with camera:
public class MainActivity extends AppCompatActivity {
private Network wifi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.requestNetwork(requestBuilder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
wifi = network;
}
@Override
public void onUnavailable() {
super.onUnavailable();
wifi = null;
}
});
}
Socket initSocket() {
Socket sock = new Socket();
if (wifi != null) {
wifi.bindSocket(sock);
}
else {
System.out.println("Warning: wifi network is null");
}
return sock;
}
}
Also, i've implemeneted simple http-client to work with. So, any API request looks like:
SomeCommandResult executeSomeCommand() {
Socket sock = initSocket();
HttpPacket res = API.performHttpRequest(sock, "GET /?command=some-command");
return (SomeCommandResult) parseXML(new String(res.body));
}
But i've faced some problems implementing other components, so now i'm looking for another way to bind all sockets to the wifi interface (including internal net usage: ImageView, VideoView, etc).
I've discovered Socket.setSocketImplFactory(...)
:
protected void onCreate(Bundle savedInstanceState) {
...
Socket.setSocketImplFactory(new SocketImplFactory() {
public SocketImpl createSocketImpl() {
return new MySocketImpl();
}
});
}
But i have no idea how to implement own MySocketImpl
.
All i need is to intercept all outgoing socket connections and bind them to the wifi iface before connection actually established (force use wifi). Need help imlementing MySocketImpl
. Or maybe someone have another idea how to achieve it?
回答1:
Thanks for ianhanniballake's answer and corresponding blog post (Connecting your App to a Wi-Fi Device), now I know, there's a ConnectivityManager.bindProcessToNetwork(Network network)
method.
So, this is how I've done:
public class MyApp extends Application {
@Override
protected void onCreate(Bundle savedInstanceState) {
NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
cm.requestNetwork(requestBuilder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
cm.bindProcessToNetwork(network);
}
@Override
public void onUnavailable() {
super.onUnavailable();
}
});
}
}
来源:https://stackoverflow.com/questions/54182966/bind-all-client-sockets-to-wifi-interface