【问题标题】:Turn on/off WiFi hotspot programmatically以编程方式打开/关闭 WiFi 热点
【发布时间】:2017-03-09 14:19:29
【问题描述】:

我需要帮助来创建一个在热点模式下设置安卓 WiFi 的 C# 脚本。这是我设法创建的代码。

    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 中做到这一点。

【问题讨论】:

  • 你很亲密。参数略有错误。检查问题。
  • @Programmer 这不是重复的。 OP 询问是否打开热点 ( AP ) 而不是 WiFi。
  • 我的错。没有看到热点部分。

标签: c# android unity3d hotspot


【解决方案1】:

这些方法仅适用于 android 5.0 及更低版本!

EASY 方式:

尝试先实例化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);

也许您必须设置比这两个更多的字段,但要确认您应该检查 source 并确保 setWifiApEnabled 方法在内部执行什么操作。


HARD方式:
(使用反射代码)

第 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配置:

我试图找出为什么上面的代码可能不起作用,但对我来说它工作正常(在一些虚拟机和三星 Galaxy S5 Neo 上测试)

可能是什么情况(我几乎是在午夜发现的)是一个密码短语。
根据关于 WPA-PSK

部分的this wikipedia article

也称为 WPA-PSK(预共享密钥)模式,专为家庭和小型办公网络而设计,不需要身份验证服务器。[9]每个无线网络设备都使用 256 位密钥对网络流量进行加密。该密钥可以作为 64 个十六进制数字的字符串输入,也可以作为 8 到 63 个可打印 ASCII 字符的密码短语输入。[10]如果使用 ASCII 字符,则通过将 PBKDF2 密钥派生函数应用于密码短语,使用 SSID 作为盐和 HMAC-SHA1 的 4096 次迭代来计算 256 位密钥。 [11] WPA-Personal 模式适用于 WPA 和 WPA2。)

我的建议是使用与上面链接的文章中相同的密码以确保其有效。

另外需要注意的是 SSID 部分,它有一个简短但很好的描述here on wikipedia

一个常见但不正确的假设是,SSID 是一串人类可读的字符(如 ASCII),以 NUL 字符结尾(如在 C 字符串中)。 SSID 必须按原样处理和处理,即 0-32 个八位字节的序列,其中一些可能不是人类可读的

根据我的检查,您不需要在 Java 或 C# 中以空值终止您的字符串,因为它将由本机代码处理,但您仍然不应超过 31 个字符(32 将是空字符)。

我通过以下方式进行了检查:
SSID:MeHotSpot
WPA-PSK:5260305714217573

【讨论】:

  • 值得知道为什么有人不赞成这个。
  • 我明白你为什么投了反对票。这不应该工作。 setWifiApEnabled 是一个隐藏函数,甚至没有记录。它需要反思才能起作用,因此您现在拥有的东西将不起作用。我可能错了,但要完成这项工作,还需要执行更多的流程,例如使用 Method 类...
  • @Programmer 这可能是正确的,但我相应地回答了this source。但是,如果它真的需要反思,仍然等待一些反馈。我会在需要时编辑我的答案。
  • @m.rogalski 非常感谢您的帮助。我根据您的说明修改了代码-统一没有错误,但是在安装应用程序后启动热点后关闭。 link
  • 您是否指定了写入设置和更改连接的权限? &lt;uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /&gt; &lt;uses-permission android:name="android.permission.WRITE_SETTINGS" /&gt;这应该可以在项目设置中更改。
猜你喜欢
  • 2011-09-17
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多