Java android p2p wifi

Creating P2P Connections with Wi-Fi

This lesson teaches you how to

You should also read

The Wi-Fi peer-to-peer (P2P) APIs allow applications to connect to nearby devices without needing to connect to a network or hotspot (Android’s Wi-Fi P2P framework complies with the Wi-Fi Direct™ certification program). Wi-Fi P2P allows your application to quickly find and interact with nearby devices, at a range beyond the capabilities of Bluetooth.

This lesson shows you how to find and connect to nearby devices using Wi-Fi P2P.

Set Up Application Permissions

In order to use Wi-Fi P2P, add the CHANGE_WIFI_STATE , ACCESS_WIFI_STATE , and INTERNET permissions to your manifest. Wi-Fi P2P doesn’t require an internet connection, but it does use standard Java sockets, which require the INTERNET permission. So you need the following permissions to use Wi-Fi P2P.

Set Up a Broadcast Receiver and Peer-to-Peer Manager

To use Wi-Fi P2P, you need to listen for broadcast intents that tell your application when certain events have occurred. In your application, instantiate an IntentFilter and set it to listen for the following:

WIFI_P2P_STATE_CHANGED_ACTION Indicates whether Wi-Fi P2P is enabled WIFI_P2P_PEERS_CHANGED_ACTION Indicates that the available peer list has changed. WIFI_P2P_CONNECTION_CHANGED_ACTION Indicates the state of Wi-Fi P2P connectivity has changed. WIFI_P2P_THIS_DEVICE_CHANGED_ACTION Indicates this device’s configuration details have changed.

At the end of the onCreate() method, get an instance of the WifiP2pManager , and call its initialize() method. This method returns a WifiP2pManager.Channel object, which you’ll use later to connect your app to the Wi-Fi P2P framework.

Now create a new BroadcastReceiver class that you’ll use to listen for changes to the System’s Wi-Fi P2P state. In the onReceive() method, add a condition to handle each P2P state change listed above.

Finally, add code to register the intent filter and broadcast receiver when your main activity is active, and unregister them when the activity is paused. The best place to do this is the onResume() and onPause() methods.

Initiate Peer Discovery

To start searching for nearby devices with Wi-Fi P2P, call discoverPeers() . This method takes the following arguments:

  • The WifiP2pManager.Channel you received back when you initialized the peer-to-peer mManager
  • An implementation of WifiP2pManager.ActionListener with methods the system invokes for successful and unsuccessful discovery.

Keep in mind that this only initiates peer discovery. The discoverPeers() method starts the discovery process and then immediately returns. The system notifies you if the peer discovery process is successfully initiated by calling methods in the provided action listener. Also, discovery will remain active until a connection is initiated or a P2P group is formed.

Fetch the List of Peers

Now write the code that fetches and processes the list of peers. First implement the WifiP2pManager.PeerListListener interface, which provides information about the peers that Wi-Fi P2P has detected. The following code snippet illustrates this.

Now modify your broadcast receiver’s onReceive() method to call requestPeers() when an intent with the action WIFI_P2P_PEERS_CHANGED_ACTION is received. You need to pass this listener into the receiver somehow. One way is to send it as an argument to the broadcast receiver’s constructor.

Читайте также:  Android разработка во весь экран

Now, an intent with the action WIFI_P2P_PEERS_CHANGED_ACTION intent will trigger a request for an updated peer list.

Connect to a Peer

In order to connect to a peer, create a new WifiP2pConfig object, and copy data into it from the WifiP2pDevice representing the device you want to connect to. Then call the connect() method.

The WifiP2pManager.ActionListener implemented in this snippet only notifies you when the initiation succeeds or fails. To listen for changes in connection state, implement the WifiP2pManager.ConnectionInfoListener interface. Its onConnectionInfoAvailable() callback will notify you when the state of the connection changes. In cases where multiple devices are going to be connected to a single device (like a game with 3 or more players, or a chat app), one device will be designated the «group owner».

Now go back to the onReceive() method of the broadcast receiver, and modify the section that listens for a WIFI_P2P_CONNECTION_CHANGED_ACTION intent. When this intent is received, call requestConnectionInfo() . This is an asynchronous call, so results will be received by the connection info listener you provide as a parameter.

Источник

История создания библиотеки для группового общения андроид-устройств через Wi-Fi Peer-to-Peer соединение

Предыстория

Мотивом написания данного приложения послужила курсовая работа по дисциплине «Компьютерные системы и сети». Честно говоря, эта одна из самых мной нелюбимых сторон в компьютерных технологиях, и я решил «подстраивать» курсовой проект под свои интересы, а именно, под Андроид-разработку.

Было решено создать библиотеку для соединения Андроид-устройств по средством Wi-Fi Direct технологии и передачи данных между ними (Wi-Fi Peer-to-Peer соединение осуществляется как раз с помощью технологии Wi-Fi Direct).

Почему Wi-Fi Direct?

После одобрения идеи о локальном соединении устройств передо мной встал вопрос: С помощью какой технологии собираюсь я это осуществить? Рассматривались следующие варианты:

  • Bluetooth
  • Wi-Fi Hotspot
  • Wi-Fi Direct или Wi-Fi Peer-to-Peer

Bluetooth

Wi-Fi Hotspot

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

Однако с помощью Wi-Fi Hotspot можно добиться максимальной скорости передачи данных (приложения Portal, SHAREit).

Wi-Fi Direct или Wi-Fi Peer-to-Peer

Данный подход решает все вышеупомянутые проблемы:

  1. неограниченное кол-во клиентов (если не так, прошу меня поправить)
  2. большой радиус действия
  3. соединение с устройствами по средством Wi-Fi без создания точки доступа
  4. технология поддерживается с API 14 (Android 4.0)

Но сразу закрадывается сомнение, мол Wi-Fi Peer-to-Peer, тогда как мы собираемся создать группу с владельцем и клентами, и тем более, чтобы все друг с другом общались. Это как раз-таки и является основной причиной написания данной статьи.

Wi-Fi Aware

Начнем с проблем

Скажу честно, предоставляемая документация by developer.android.com давалась мне нелегко. И я начал искать сэмплы. Перебрав кучу материала, наткнулся на наиболее интересный sample by Google.

Никогда не думал, что на официальном сайте от Google можно найти говнокод, но это как раз тот случай. Однако даже этому стоит отдать должное, так как благодаря данному ресурсу я реализовал то, что хотел.

В сэмпле продемонстрирован пример чата двух устройств, которые нашли друг друга в списке, отображающем рядом находящиеся Wi-Fi Direct устройства с запущенным приложением чата. При выборе партнера непосредственно открывается ChatActivity.

Очень важным моментом является поиск собеседников: в списке не будут отображаться такие Wi-Fi Direct устройства, как телевизор или какая-нибудь гарнитура. Отображаются только устройства с запущенным Chat-приложением.

Также присутствовала проблема с тестированием. Тестировать работоспособность приложения необходимо было исключительно на реальных устройствах.

Что было реализовано для демонстрации работоспособности библиотеки

Приложение представляет следующий функционал:

  1. выбор роли в процессе работы с приложением (для примера были созданы «Мафия» и «Мирный житель»)
  2. создание группы
  3. присоединение к существующей группе
  4. общение между устройствами (при нажатии на кнопку меняется ее цвет как у инициатора, так и у всех остальных, соответствующих текущей роли (либо broadcast))
Читайте также:  Как обновить карты семь дорог для андроид

Описание экранов слева-направо:

  • стартовый экран с выбором действия и роли
  • список присоединившихся устройств к текущему владельцу группы
  • список активных групп, к которым можно присоединиться
  • сеттинги приложения (логин устройства, название группы, пароль для вхождения в группу)
  • «игровой» экран


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

Основная концепция работы библиотеки

Логика построена на основе архитектуры клиент-сервер. Сервером является владелец группы, клиентами — подсоединившиеся пользователи.

В приложении присутствуют собственные Serializer/Deserializer для преобразования передаваемых данных в массив байтов и обратно. В передаваемых данных хранится следующая информация:

  • кому отправить (мафии, мирным жителям, всем)
  • какого рода данные (например: изменение цвета кнопки)
  • сами данные (сериализованный Object)

Первый пункт «кому отправить» не совсем корректен, т.к. отправляются данные всем. Сначала серверу, потом сервер отправляет этот пакет всем клиентам. А вот клиент уже сам решает, стоит ему обрабатывать эти данные или нет. Сделано это по той простой причине, что сервер не знает ролей его клиентов. Таким образом было достигнуто равноправие в группе. Владелец отличается от всех остальных только тем, что его обременили заниматься передачей данных всем его клиентам.

Компоненты библиотеки

Самая сложная проблема во время разработки

Когда проект дошел до стадии тестирования мультиплеера (> 2 устройств), тут-то и началась жара. Два устройства как и прежде у меня соединялись без проблем (для чего впрочем и создан Wi-Fi Peer-to-Peer), однако при подсоединении третьего звена почти всегда происходил треш. При нажатии на кнопку у «владельца» (позже поймете, почему в кавычках) цвет менялся только у того клиента, с которым «владелец» последний раз общался.

После долгих и упорных часов раздумий я решил соединить устройства через опцию Wi-Fi Direct в настройках Wi-Fi каждого, и заметил вещь, которая перевернула мое сознание и добавила всего одну строчку в код метода для установки соединения.

До этого я считал, что тот девайс, который подсоединяется к другому, всегда будет клиентом… а это далеко не так. При соединении устройств рандомно передавались права владельца одному из них, что и побудило меня на поиск настройки config’a, который бы исправил эту ситуацию, и сделал подсоединяемое устройство клиентом.

При соединении двух устройств прописывается специальный config, который в себе содержит:

  • адрес устройства, к которому мы хотим присоединиться
  • wps.setup позволяет установить, как мы будем соединяться: с паролем или просто по нажатию кнопки
  • groupOwnerIntent — вот он (споймал!), тот, кто решил мою проблему; целочисленное поле, значение которого варьируется от 0 до 15 (0 — хотим быть клиентом, 15 — хотим быть владельцем); по умолчанию -1, что дает системе право самой выбрать роль в этой связи

Status’ом (enum) выше является текущее положение устройства, если он создатель группы — GroupOwner, иначе — Client.

Необходимые доработки

Пока не существует решения по проблеме восстановления соединения. Например, при выходе из приложения, например, чтобы совершить звонок, после возвращения нас ждет… ничего. После дестроя активности необходимо опять подтягивать клиентов себе, а клиентам — владельца.
Также хочется ввести понятие по передаче прав владельца одному из клиентов на тот случай, если владельцу группы необходимо покинуть игру.

Защита. Для входа в определенную группу было бы неплохо реализовать авторизацию.

Заключение

Не думаю, что я реализовал что-то новое или революционное, однако данный проект послужил хорошим примером неординарного использования Wi-Fi Peer-to-Peer соединения. Мною была успешно построена сеть между устройствами с помощью Wi-Fi Direct, что позволило беспрепятственно общаться между ними.

Это моя первая статья, поэтому судить строго. Спасибо за внимание.

→ Ссылка на GitHub
(модуль wifidirect может быть без проблем перенесен в любой андроид-проект)

Читайте также:  Батареи для телефонов андроид

Источник

Создание P2P подключений через Wi-Fi

Этот урок научит вас

Вы также должны прочитать

API для одноранговых (P2P) Wi-Fi подключений позволяют приложениям подключаться к соседним устройствам без необходимости подключения к сети или точке доступа (Wi-Fi P2P платформы Android соответствует программе сертификации Wi-Fi Direct™ ). Wi-Fi P2P позволяет приложению быстро находить и взаимодействовать с другими устройствами, в диапазоне за пределами возможностей Bluetooth.

Этот урок покажет вам, как найти и подключиться к близлежащему устройству, используя Wi-Fi P2P.

Настройка разрешений приложения

Чтобы использовать Wi-Fi P2P, добавьте CHANGE_WIFI_STATE , ACCESS_WIFI_STATE , и INTERNET разрешения в манифест. Wi-Fi P2P не требует подключения к интернету, но оно использует стандартные Java сокеты, которые требуют INTERNET разрешение. Поэтому вам нужны следующие разрешения для использования Wi-Fi P2P.

Настройка приемника широковещательных запросов и P2P менеджера

Для использования Wi-Fi P2P, вы должны слушать рассылку намерений, которые говорят вашему приложению, когда произошли определенные события. В вашем приложении, создайте экземпляр IntentFilter и настройте его для прослушивания следующего:

WIFI_P2P_STATE_CHANGED_ACTION Показывает включен ли Wi-Fi P2P WIFI_P2P_PEERS_CHANGED_ACTION Указывает, что список доступных узлов изменился. WIFI_P2P_CONNECTION_CHANGED_ACTION Указывает, что состояние Wi-Fi P2P соединения изменилось. WIFI_P2P_THIS_DEVICE_CHANGED_ACTION Указывает, что детали конфигурации этого устройства изменились.

В конце onCreate() метода, получить экземпляр WifiP2pManager , и вызовите его initialize() метод. Этот метод возвращает WifiP2pManager.Channel объект, который вы будете использовать позже для подключения вашего приложения к Wi-Fi P2P платформе.

Теперь создайте новый BroadcastReceiver класс, который вы будете использовать для прослушивания изменений состояния системы Wi-Fi P2P. В onReceive() методе, добавьте условие для обработки каждого изменения состояния P2P перечисленных выше.

В конце, добавьте код для регистрации фильтра намерений и обработчика широковещательный запросов, когда ваша основная деятельность является активной, и отменяет их регистрацию, когда деятельность приостанавливается. Лучшее место сделать это в onResume() и onPause() методах.

Инициирование обнаружения устройств

Чтобы начать поиск близлежащих устройств с Wi-Fi P2P, вызовите discoverPeers() . Этот метод имеет следующие аргументы:

  • WifiP2pManager.Channel , который вы получили обратно при инициализации P2P mManager
  • Реализация WifiP2pManager.ActionListener с методами, которые система вызывает для успешного и неудачного обнаружения.

Имейте в виду, что это только инициирует обнаружение узлов. discoverPeers() метод запускает процесс обнаружения и затем сразу же возвращает управление. Система уведомляет вас, когда процесс обнаружения узлов успешно инициирован посредством вызова методов предоставленного обработчика действий. Кроме того, обнаружение будет оставаться активным, пока не будет установлено соединение или пока не будет образована P2P группа.

Выборка списка узлов

Теперь напишем код, который извлекает и обрабатывает список узлов сети. Вначале реализуйте WifiP2pManager.PeerListListener интерфейс, который предоставляет информацию об узлах, которые обнаружил Wi-Fi P2P. Это иллюстрирует следующий фрагмент кода.

Теперь измените метод вашего широковещательного приемника onReceive() и вызовите requestPeers() когда получено намерение с действием WIFI_P2P_PEERS_CHANGED_ACTION . Вам необходимо как-то передать этот обработчик в приемник. Один из способов это передать его в качестве аргумента в конструктор широковещательного приемника.

Теперь, намерение с действием WIFI_P2P_PEERS_CHANGED_ACTION запустит запрос на обновленный списка узлов.

Подключение к узлу

Для подключения к узлу, создайте новый WifiP2pConfig объект, и скопируйте в него данные из WifiP2pDevice , представляющий устройство, к которому необходимо подключиться. Затем вызовите connect() метод.

WifiP2pManager.ActionListener реализованный в этом фрагменте уведомляет вас только когда инициирование завершилось успешно или потерпело неудачу. Чтобы прослушивать изменения состояния соединения, реализуйте WifiP2pManager.ConnectionInfoListener интерфейс. Его onConnectionInfoAvailable() метод обратного вызова сообщает вам, когда изменяется состояние подключения. В случаях, когда вы хотите подключить несколько устройств к одному устройству (например, игры с 3 или более игроков, или чат-приложение), одно устройство будет назначено «владельцем группы».

Теперь вернемся к onReceive() методу широковещательного приемника, и изменим раздел, который ожидает WIFI_P2P_CONNECTION_CHANGED_ACTION намерение. Когда это намерение будет получено, вызовите requestConnectionInfo() . Это асинхронный вызов, поэтому результаты будут получены обработчиком информации о подключении, который вы передали в качестве параметра.

Источник

Оцените статью