以编程方式打开 on/off WiFi 热点
Turn on/off WiFi hotspot programmatically
我在创建 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 和密码时遇到问题。查看 documentation 后,我知道我必须用设置对象替换空值,但我完全不知道如何在 Unity 中执行此操作。
这些方法仅适用于 android 5.0 及更低版本!
简单方式:
先尝试实例化 WifiConfiguration
:
AndroidJavaObject wifiConfiguration = new AndroidJavaClass("android.net.wifi.WifiConfiguration");
现在您可以调用此对象中的方法和 set/get 字段 :
// to set SSID
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
设置所有必填字段后,只需调用您的 setWifiApEnabled
方法:
wifiManager.Call<bool>("setWifiApEnabled", wifiConfiguration, enabled);
也许您必须设置比这两个更多的字段,但要确认您应该检查 source 并确保 setWifiApEnabled
方法在内部执行的操作。
困难方式:
(使用反射代码)
步骤 6 不适用于 android 5.0+ !
在 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 上测试).
可能是什么情况(我在将近午夜时发现)是一个密码。
根据 this wikipedia article 关于 WPA-PSK
的部分
Also referred to as WPA-PSK (pre-shared key) mode, this is designed for home and small office networks and doesn't require an authentication server.[9] Each wireless network device encrypts the network traffic using a 256 bit key. This key may be entered either as a string of 64 hexadecimal digits, or as a passphrase of 8 to 63 printable ASCII characters.[10] If ASCII characters are used, the 256 bit key is calculated by applying the PBKDF2 key derivation function to the passphrase, using the SSID as the salt and 4096 iterations of HMAC-SHA1.[11] WPA-Personal mode is available with both WPA and WPA2.)
我的建议是使用与上面链接的文章中相同的密码以确保其有效。
另外需要注意的是 SSID 部分,它有一个简短但很好的描述 here on wikipedia.
A common, albeit incorrect assumption, is that an SSID is a string of human-readable characters (such as ASCII), terminated by a NUL character (as in a C-string). SSIDs must be treated and handled as what they are, a sequence of 0–32 octets, some of which may not be human-readable
根据我的检查,您不需要在 Java 或 C# 中以 null 终止您的字符串,因为它将由本机代码处理,但您仍然不应超过 31 个字符( 32 将是空字符 ).
我用 :
检查了这个
SSID:MeHotSpot
WPA-PSK:5260305714217573
我在创建 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 和密码时遇到问题。查看 documentation 后,我知道我必须用设置对象替换空值,但我完全不知道如何在 Unity 中执行此操作。
这些方法仅适用于 android 5.0 及更低版本!
简单方式:
先尝试实例化 WifiConfiguration
:
AndroidJavaObject wifiConfiguration = new AndroidJavaClass("android.net.wifi.WifiConfiguration");
现在您可以调用此对象中的方法和 set/get 字段 :
// to set SSID
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
设置所有必填字段后,只需调用您的 setWifiApEnabled
方法:
wifiManager.Call<bool>("setWifiApEnabled", wifiConfiguration, enabled);
也许您必须设置比这两个更多的字段,但要确认您应该检查 source 并确保 setWifiApEnabled
方法在内部执行的操作。
困难方式:
(使用反射代码)
步骤 6 不适用于 android 5.0+ !
在 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 上测试).
可能是什么情况(我在将近午夜时发现)是一个密码。
根据 this wikipedia article 关于 WPA-PSK
Also referred to as WPA-PSK (pre-shared key) mode, this is designed for home and small office networks and doesn't require an authentication server.[9] Each wireless network device encrypts the network traffic using a 256 bit key. This key may be entered either as a string of 64 hexadecimal digits, or as a passphrase of 8 to 63 printable ASCII characters.[10] If ASCII characters are used, the 256 bit key is calculated by applying the PBKDF2 key derivation function to the passphrase, using the SSID as the salt and 4096 iterations of HMAC-SHA1.[11] WPA-Personal mode is available with both WPA and WPA2.)
我的建议是使用与上面链接的文章中相同的密码以确保其有效。
另外需要注意的是 SSID 部分,它有一个简短但很好的描述 here on wikipedia.
A common, albeit incorrect assumption, is that an SSID is a string of human-readable characters (such as ASCII), terminated by a NUL character (as in a C-string). SSIDs must be treated and handled as what they are, a sequence of 0–32 octets, some of which may not be human-readable
根据我的检查,您不需要在 Java 或 C# 中以 null 终止您的字符串,因为它将由本机代码处理,但您仍然不应超过 31 个字符( 32 将是空字符 ).
我用 :
检查了这个
SSID:MeHotSpot
WPA-PSK:5260305714217573