我需要帮助创建一个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之后,我知道我必须用settings对象替换空值,但我完全不知道如何在unity中进行。

最佳答案

简单的方法:
首先尝试实例化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方法在内部执行的操作。
艰难的道路:
(使用反射代码)
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);
                }
            }
        }
    }
}

接线配置:
我试图找出为什么上面的代码可能无法工作,但对我来说,它工作正常(在一些虚拟机和三星galaxy s5 neo上测试)。
可能的情况(我在午夜发现)是一个密码短语。
根据WPA-PSK章节中的this wikipedia article
也称为wpa-psk(预共享密钥)模式,专为家庭和小型办公室网络设计,不需要验证服务器。[9]每个无线网络设备都使用256位密钥加密网络流量。此密钥可以作为64个十六进制数字的字符串输入,也可以作为8到63个可打印的ascii字符的密码短语输入。[10]如果使用ascii字符,则通过对密码短语应用pbkdf2密钥派生函数来计算256位密钥,使用ssid作为salt和hmac-sha1的4096次迭代。[11]wpa personal mode对wpa和wpa2都可用。)
我的建议是使用与上面链接的文章中相同的密码短语,以确保它是有效的。
另一个需要注意的是ssid部分,它有一个简短但很好的描述here on wikipedia
一个常见的,尽管不正确的假设是,ssid是一个人类可读字符字符串(如ascii),以nul字符(如c字符串)结尾。ssid必须按原样对待和处理,一个由0到32个八位字节组成的序列,其中一些可能不可读
根据我所检查的,您不需要在Java或C中使用空终止字符串,因为它将由本机代码处理,但您仍然不应超过31个字符(32个字符将是空字符)。
我查过了:
ssid:mehotspot
WPA-PSK:5260305714217573

关于c# - 以编程方式打开/关闭WiFi热点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42697725/

10-11 20:04