Bind all client sockets to wifi interface

拜拜、爱过 提交于 2021-01-29 07:45:14

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!