Привязать все клиентские сокеты к интерфейсу Wi-Fi - PullRequest
0 голосов
/ 14 января 2019

Я пишу клиентское приложение для моей экшн-камеры. Существует проблема с использованием сетевых подключений, когда смартфон подключен к Wi-Fi и мобильной сети: Android определяет, что Wi-Fi не подключен к Интернету, поэтому все запросы передаются на интерфейс мобильной сети. Я уже реализовал клиентский API, который использует предварительно ограниченные сокеты для связи с камерой:

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

Кроме того, я реализовал простой http-клиент для работы. Итак, любой запрос API выглядит так:

SomeCommandResult executeSomeCommand() {
    Socket sock = initSocket();
    HttpPacket res = API.performHttpRequest(sock, "GET /?command=some-command");
    return (SomeCommandResult) parseXML(new String(res.body));
}

Но я столкнулся с некоторыми проблемами при реализации других компонентов, поэтому сейчас я ищу другой способ привязки всех сокетов к интерфейсу wifi (включая использование внутренней сети: ImageView, VideoView и т. Д.). Я обнаружил Socket.setSocketImplFactory(...):

    protected void onCreate(Bundle savedInstanceState) {
        ...

        Socket.setSocketImplFactory(new SocketImplFactory() {
            public SocketImpl createSocketImpl() {
                return new MySocketImpl();
            }
        });
    }

Но я понятия не имею, как реализовать собственный MySocketImpl.

Все, что мне нужно, это перехватить все исходящие соединения сокетов и связать их с Wi-Fi до того, как соединение действительно установится (принудительно используйте Wi-Fi). Нужна помощь в реализации MySocketImpl. Или, может быть, у кого-то есть другая идея, как этого добиться?

1 Ответ

0 голосов
/ 15 января 2019

Спасибо за ответ ianhanniballake и соответствующий пост в блоге ( Подключение вашего приложения к устройству Wi-Fi ), теперь я знаю, что есть метод ConnectivityManager.bindProcessToNetwork(Network network).

Итак, вот как я это сделал:

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

...