Ответ 1
Это похоже на ошибку в строке LineageOS, которую я использую, поскольку это происходит только тогда, когда планшет является владельцем группы. Когда телефон является владельцем группы, отсоединение не происходит.
Я создаю WifiP2pGroup
с WifiP2pManager.connect()
. Это работает отлично, но группа всегда расформирована через тридцать минут, независимо от того, передаются ли данные или нет. Кто-нибудь знает, почему это происходит, или если это можно предотвратить?
Я пробовал непрерывно передавать данные между устройствами и постоянно удерживать экраны с помощью блокировки слежения, но это не имеет никакого значения. Я убедился, что Wi-Fi настроен не спать, а также получил wifilock и отключил оптимизацию батареи для приложения и для Wi-Fi напрямую, но это тоже не помогает. Через тридцать минут (или, если быть конкретным, 29 м 18 с - это очень непротиворечиво) я получаю широковещательную передачу CONNECTION_STATE_CHANGE
, и устройства больше не спарены.
Устройствами являются Nexus 7
running Android 7 (LineageOS)
и Samsung Galaxy A5
running Android 6
.
Спасибо!
Изменить: я пробовал работать с отключенными мобильными данными и Wi-Fi не подключен. Приложение не приостанавливается или не уничтожается, и никакие другие приложения не имеют разрешения на изменение состояния wifi. В журналах wifi на одном из устройств я нашел это событие во время отключения:
E/DhcpStateMachine: DHCP renew failed on p2p-wlan0-0: Timed out waiting for DHCP Renew to finish
D/WifiP2pService: GroupCreatedState{ what=196613 }
E/WifiP2pService: DHCP failed
На другом устройстве я нашел это в начале процесса отключения:
552-813/system_process V/WifiHAL: event received NL80211_CMD_DEL_STATION
552-846/system_process D/WifiMonitor: Event [IFNAME=p2p-p2p0-11 AP-STA-DISCONNECTED b6:22:8b:b1:df:0f p2p_dev_addr=f2:62:6f:d1:5f:0c]
552-846/system_process D/WifiMonitor: p2p0 cnt=6442 dispatchEvent: AP-STA-DISCONNECTED b6:22:8b:b1:df:0f p2p_dev_addr=f2:62:6f:d1:5f:0c
552-629/system_process D/WifiP2pService: Client list empty, remove non-persistent p2p group
Это похоже на ошибку в строке LineageOS, которую я использую, поскольку это происходит только тогда, когда планшет является владельцем группы. Когда телефон является владельцем группы, отсоединение не происходит.
Ниже показано, что аренда DHCP для двух сверстников составляет 30 минут, а обновление не работает.
E/DhcpStateMachine: DHCP renew failed on p2p-wlan0-0: Timed out waiting for DHCP Renew to finish
D/WifiP2pService: GroupCreatedState{ what=196613 }
E/WifiP2pService: DHCP failed
Рекламодатель услуг и браузер услуг имеют IP-адреса, браузер, выданный DHCP рекламодателем. Если DHCP не обновляется, соединение теряется и устройства должны повторно подключаться. Похоже, что продление аренды производится в течение 29 минут 18 секунд, а время истекает через 30 минут аренды. В этот момент браузер должен повторно подключиться. Если DHCP-сервер не помнит IP-адрес браузера, или если структура всегда выдает новый IP-адрес, то то, что вы описываете, произойдет. Надеюсь, это поможет.
Изменить: этот пост, похоже, подтверждает, что владелец группы действует как DHCP-сервер: Получает IP-адрес однорангового устройства в wifi-direct p2p-подключении. Однако я не знаю, как можно увеличить время аренды на WiFi-Direct.
Изменить: эта ссылка рассказывает о некоторых проблемах с DHCP на Android: https://www.net.princeton.edu/android/android-stops-renewing-lease-keeps-using-IP-address-11236.html
Изменить: Возможное решение содержится в https://www.net.princeton.edu/android/android-11236-partial-workaround.html, добавленном ниже. Идея состоит в том, чтобы использовать настройки на устройстве владельца группы.
Процедура
Depending upon the version of Android on your device, there should be a "Wi-Fi sleep policy" setting, a "Wi-Fi disconnect policy" setting, or a "Keep Wi-Fi on during Sleep" setting. (Your device will have only one of these; the name varies.) It should be available at (only) one of the following locations:
Settings
-> Wireless & networks
-> Wi-Fi settings
-> Menu (button)
-> Advanced
-> Wi-Fi sleep policy
Settings
-> Wireless & networks
-> Wi-Fi settings
-> Wi-Fi disconnect policy
Settings
-> Wireless & networks
-> Wi-Fi settings
-> Menu (button)
-> Advanced
-> Keep Wi-Fi on during Sleep
If the Wi-Fi settings item is greyed-out, you may need to turn on Wi-Fi before you can select this item.
If your device has a "Wi-Fi sleep policy" or " Wi-Fi disconnect policy", it should offer several choices. These choices available vary among different versions of Android. At least one of the choices should be "After 15 mins" or "When screen turns off". Select that choice.
Otherwise, if your device has a "Keep Wi-Fi on during Sleep" setting, it should offer several choices. These choices available may vary among different versions of Android. At least one of the choices should be "Never". Select that choice.
If you have any software installed on your Android device which modifies the way Android turns Wi-Fi on or off, then reconfigure that software so it no longer controls the device Wi-Fi interface. Alternatively, disable or remove that software.
An example would be an application designed to keep your device Wi-Fi interface always turned on. Another would be an application configured to turn on your device Wi-Fi interface based on certain conditions (for example, location, time of day, or battery charge).
These applications are not the cause of the bugs. However, they can prevent this partial workaround from being effective, because these may be configured to override Android "Wi-Fi Sleep Policy" (or "Wi-Fi disconnect policy"), causing the Wi-Fi interface to remain connected to the wireless network for an extended period while the Android device is asleep.
Every time you upgrade the Android software/firmware in the future, verify that the setting you selected above (the "Wi-Fi sleep policy", "Wi-Fi disconnect policy", or "Keep Wi-Fi on during Sleep" setting) remains configured as described above. Such upgrades sometimes modify existing settings; you must make a point of checking (and if necessary, changing) this setting immediately after upgrading.
Take care that any software you install in the future does not modify the way Android turns on or off Wi-Fi.
Копаясь через источники для p2, нижняя строка состоит в том, что dhcp stuff для p2p выполняется ethernetworkfactory, минуя собственный сервер dhcp (см. http://book2s.com/java/src/package/com/android/server/ethernet/ethernetnetworkfactory.html#199b9c81a59238cafe64b4e28b0c71ce), а здесь интересный фрагмент кода:
/* Called by the NetworkFactory on the handler thread. */
public void onRequestNetwork() {
// TODO: Handle DHCP renew.
похоже, что аренда dhcp никогда не будет обновляться в рамках p2p (см. ниже). Честно говоря, я должен проверить это; это нетривиальная ошибка, если она истинна. Если это так, то решение повторного подключения каждые 25 минут в соответствии с вышеуказанным сообщением может быть единственным способом. Примечание. Обновление dhcp происходит в 48% от времени продления аренды, чтобы выполнить предыдущее обновление на родном dhcp (см. https://android.googlesource.com/platform/frameworks/base/+/c3a2858/core/java/android/net/DhcpStateMachine.java); соответствующие строки
//Do it a bit earlier than half the lease duration time
//to beat the native DHCP client and avoid extra packets
//48% for one hour lease time = 29 minutes
Итак, в p2pdirect, похоже, есть слой, который позволяет избежать обновления на родном dhcp, но не реализует его сам.
вы можете создать сервис. а затем повторно подключать каждые 25 минут программно.
или
public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMan.getActiveNetworkInfo();
if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI)
Log.d("WifiReceiver", "Have Wifi Connection");
else
Log.d("WifiReceiver", "Don't have Wifi Connection");
}
};
Чтобы получить доступ к активной информации о сети, вам необходимо добавить следующие разрешения - на AndroidManifest.xml:
И следующий приемник намерений (или вы можете добавить это программно...)
<receiver android:name=".WifiReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
[ссылка:] [Wifi Connect-Disconnect Listener 1
таким образом вы можете решить свою проблему.:)