0

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?

Bars
  • 194
  • 1
  • 7

1 Answers1

0

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();
            }
        });
    }
}

Bars
  • 194
  • 1
  • 7