Включить / выключить точку доступа WiFi программно
Мне нужна помощь в создании сценария C#, который устанавливает Android-WiFi в режиме точки доступа. Вот код, который мне удалось создать.
public bool setAPEnabled(bool enabled)
{
using (AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"))
{
try
{
if(isWifiEnabled()==true){
setWifiEnabled(false);
}
using (var wifiManager = activity.Call<AndroidJavaObject>("getSystemService", "wifi"))
{
return wifiManager.Call<bool>("setWifiApEnabled",null, enabled);
}
}
catch (Exception e)
{
}
}
return false;
}
Все работает хорошо - но у меня проблема с настройкой SSID и пароля. Изучив документацию, я знаю, что мне нужно заменить свое нулевое значение на объект настроек, но я совершенно не знаю, как это сделать в Unity.
1 ответ
ПРОСТОЙ способ:
Попробуйте создать экземпляр WifiConfiguration
первый:
AndroidJavaObject wifiConfiguration = new AndroidJavaClass("android.net.wifi.WifiConfiguration");
Теперь вы можете вызывать методы и устанавливать / получать поля внутри этого объекта:
// to set SSID
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
После настройки всех обязательных полей просто позвоните setWifiApEnabled
метод:
wifiManager.Call<bool>("setWifiApEnabled", wifiConfiguration, enabled);
Возможно, вам придется установить больше полей, чем эти два, но для подтверждения того, что вы должны проверить источник и убедиться, что setWifiApEnabled
метод делает внутренне.
Твердый путь:
(используя код отражения)
Используя отражение с AndroidJavaObject
может быть немного сложнее, потому что вы должны помнить, чтобы располагать каждый объект.
Итак, с самого начала:
// android code for that should look like :
// wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
// but in Unity C# you have to split this into few chunks:
// 1. Get calling class :
using ( AndroidJavaObject classObj = wifiManager.Call<AndroidJavaObject>("getClass") )
{
// classObj should contains your class object
// 2. call get WifiConfiguration class details :
using ( AndroidJavaObject wifiConfiguration = new AndroidJavaObject("setWifiApEnabled") )
{
// 3. Fill that object :
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
// 4. Get WifiConfiguration class definition
using (AndroidJavaObject wifiCfgClass = wifiConfiguration.Call<AndroidJavaObject>("getClass") )
{
// 5. Get boolean definition
using ( AndroidJavaObject booleanObj = new AndroidJavaObject("java.lang.Boolean") )
{
using ( AndroidJavaObject booleanClass = booleanObj.Call<AndroidJavaObject>("getClass") )
// 6. Get method definition
using ( AndroidJavaObject methodObj = classObj.Call<AndroidJavaObject>("getMethod", "setWifiApEnabled", wifiCfgClass , booleanClass)
{
// 7. Call that method :)
methodObj.Call("invoke", wifiManager, wifiConfiguration, enabled);
}
}
}
}
}
Конфигурация Wifi:
Я пытался выяснить, почему приведенный выше код может не работать, но у меня он работал нормально (проверено на некоторых виртуальных машинах и Samsung Galaxy S5 Neo).
Что может быть случай (который я узнал почти в полночь) является парольная фраза.
Согласно этой статье в Википедии в разделе о WPA-PSK
Также называется режимом WPA-PSK (предварительный общий ключ), он предназначен для домашних и небольших офисных сетей и не требует сервера аутентификации.[9] Каждое беспроводное сетевое устройство шифрует сетевой трафик с использованием 256-битного ключа. Этот ключ может быть введен либо в виде строки из 64 шестнадцатеричных цифр, либо в виде пароля от 8 до 63 печатных символов ASCII.[10] Если используются символы ASCII, 256-битный ключ вычисляется путем применения функции получения ключа PBKDF2 к ключевой фразе с использованием SSID в качестве соли и 4096 итераций HMAC-SHA1.[11] Персональный режим WPA доступен как для WPA, так и для WPA2.)
Я бы предложил использовать ту же фразу-пароль, что и в статье, приведенной выше, чтобы убедиться, что она действительна.
Еще одна вещь, которую стоит отметить, это часть SSID, которая имеет краткое, но хорошее описание здесь, в Википедии.
Распространенным, хотя и неверным предположением, является то, что SSID - это строка читаемых человеком символов (таких как ASCII), оканчивающаяся символом NUL (как в C-строке). SSID должны обрабатываться и обрабатываться как то, что они представляют собой последовательность из 0–32 октетов, некоторые из которых могут не читаться человеком
Из того, что я проверил, вам не нужно заканчивать нулем вашу строку в Java или C#, потому что она будет обрабатываться собственным кодом, но все равно вы не должны превышать 31 символ ( 32 будет нулевым символом).
Я проверил это с:
SSID: MeHotSpot
WPA-PSK: 5260305714217573