Как автоматически принимать Wi-Fi Direct запросы на соединение в Android

У меня есть 2 устройства Android, использующих WiFi Direct. На одном устройстве я могу получить информацию о другом устройстве, используя WifiP2pManager класс и запросить соединение с другим устройством. Однако, когда я запрашиваю соединение, другое устройство выскакивает маленькое окно и спрашивает пользователя, хотят ли они принять запрос на соединение.

Можно ли автоматически принимать эти запросы на подключение? IE, чтобы иметь возможность подключиться к другому устройству без подтверждения пользователя?

4 ответа

Решение

Основываясь на комментариях, вам действительно нужно подключаться к устройствам, если вы просто хотите отслеживать и регистрировать транспортные средства вокруг вас?

Я не знаю масштаб проекта, но вы можете просто использовать WifiP2pDeviceList, который вы получаете, когда запрашиваете пиров в WifiP2pManager. Вы можете получить список устройств (~= транспортных средств) вокруг вас и можете войти в него.

Подключение полезно, если вы хотите отправить более подробную информацию, я думаю.

Это легко сделать с помощью фреймворка Xposed. Вам просто нужно заменить один метод внутри одного из классов Android Java (см. Ссылку из ответа Снихалани). Но, конечно, для использования Xposed ваше устройство должно быть рутировано. Основная идея может быть выражена в следующем коде (используя Xposed)

@Override
public void handleLoadPackage(LoadPackageParam lpparam) {
    try {
        Class<?> wifiP2pService = Class.forName("android.net.wifi.p2p.WifiP2pService", false, lpparam.classLoader);
        for (Class<?> c : wifiP2pService.getDeclaredClasses()) {
            //XposedBridge.log("inner class " + c.getSimpleName());
            if ("P2pStateMachine".equals(c.getSimpleName())) {
                XposedBridge.log("Class " + c.getName() + " found");
                Method notifyInvitationReceived = c.getDeclaredMethod("notifyInvitationReceived");
                final Method sendMessage = c.getMethod("sendMessage", int.class);

                XposedBridge.hookMethod(notifyInvitationReceived, new XC_MethodReplacement() {
                    @Override
                    protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                        final int PEER_CONNECTION_USER_ACCEPT = 0x00023000 + 2;
                        sendMessage.invoke(param.thisObject, PEER_CONNECTION_USER_ACCEPT);
                        return null;
                    }
                });

                break;
            }
        }
    } catch (Throwable t) {
        XposedBridge.log(t);
    }
}

Я тестировал его на стоковой ПЗУ SGS4 4.2.2, и он работал. Я думаю, что то же самое можно сделать с помощью субстрата для Android.

Исходя из моего нынешнего понимания API, вы не можете автоматически принимать соединения без вмешательства пользователя. Вы можете инициировать соединение, которое не требует вмешательства пользователя. Если оба ваших устройства являются мобильными, вам нужно будет принять запрос на соединение на одном конце.

Я поместил это как запрос функции в хостинге проекта Android. Вы можете отслеживать их ответ здесь: https://code.google.com/p/android/issues/detail?id=30880

Если вы можете изменить структуру, вы можете игнорировать окно принятия и напрямую отправить "PEER_CONNECTION_USER_ACCEPT".

Основан на Android 5.0, "frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java".

Вы должны найти "notifyInvitationReceived" и изменить на...

private void notifyInvitationReceived() {
    /*Direct sends the accept message.*/
    sendMessage(PEER_CONNECTION_USER_ACCEPT);
/*
... old code
*/
}
Другие вопросы по тегам