如何编程连接到Android中的WiFi

发布于 2025-02-07 22:55:58 字数 1344 浏览 1 评论 0原文

我已经对此进行了很长时间的搜索,并找到了许多最终使用Android GUI促使最终用户进行连接/确认的解决方案。我们想向用户提供表单,然后直接连接到指定的网络。从安全角度来看,我了解为什么需要这是必要的,但是在我们的情况下,它是一个系统应用程序,可以在完全管理的Android设备上进行。它不打算在Play商店中使用。我们正在使用Xamarin,但是我可以调整任何Java/Kotlin代码。

到目前为止,我发现的最接近的是以下(使用C#):

        public void ConnectToWifi(string ssid, string password = "") {
            var wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder().SetSsid(ssid);

            if (!string.IsNullOrEmpty(password))
                wifiNetworkSpecifier.SetWpa2Passphrase(password);
                    
            var networkRequest = new NetworkRequest.Builder().AddTransportType(TransportType.Wifi)?
                .SetNetworkSpecifier(wifiNetworkSpecifier.Build())?.Build();

            if (networkRequest is null)
                return;

            var theNetworkCallback = new TheNetworkCallback();
            var connectivityManager = (ConnectivityManager?)MainActivity.Current.ApplicationContext?
                .GetSystemService(Context.ConnectivityService);
            connectivityManager?.RequestNetwork(networkRequest, theNetworkCallback);
        }

它有效,但确实提示了最终用户,并且我的理解是,这种方法是弃用的,并且在较新版本的Android版本中效果不佳。我们希望有一个在Android 11中起作用的解决方案。

如果有一个直接写入OS上的WiFi文件的解决方案,我甚至可以。我已经看到了各种通过ADB手动填充条目的解决方案,但是我很难适应Xamarin/java(似乎无法访问/data/MISC/WIFI目录)。同样,这旨在仅在我们自己的托管设备上使用。

I've been searching on this for quite some time, and have found lots of solutions that ultimately use the Android GUI to prompt the end-user for connection/confirmation. We would like to present a user with a form and directly connect to the specified network. I understand from a security perspective why this is necessary, but in our case, it is a system app going on a fully managed Android device. It is not intended for general use in the Play store. We are using Xamarin, but I can adapt any Java/Kotlin code.

The closest I've found thus far is the following (using C#):

        public void ConnectToWifi(string ssid, string password = "") {
            var wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder().SetSsid(ssid);

            if (!string.IsNullOrEmpty(password))
                wifiNetworkSpecifier.SetWpa2Passphrase(password);
                    
            var networkRequest = new NetworkRequest.Builder().AddTransportType(TransportType.Wifi)?
                .SetNetworkSpecifier(wifiNetworkSpecifier.Build())?.Build();

            if (networkRequest is null)
                return;

            var theNetworkCallback = new TheNetworkCallback();
            var connectivityManager = (ConnectivityManager?)MainActivity.Current.ApplicationContext?
                .GetSystemService(Context.ConnectivityService);
            connectivityManager?.RequestNetwork(networkRequest, theNetworkCallback);
        }

It sorta works, but does prompt the end-user, and my understanding, this approach is deprecated and doesn't work well in newer versions of Android. We're hoping for a solution that works in Android 11.

I'm even fine if there's a solution to write directly to wifi files on the OS. I've seen various solutions to manually populate entries via ADB, but I'm having a tough time adapting that to Xamarin/Java (can't seem to access the /data/misc/wifi directories). Again, this is intended for use exclusively on our own managed devices.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

素食主义者 2025-02-14 22:55:58

我在此处有有关此主题的博客文章: https:https:https:// blog。 ostebaronen.dk/2020/11/android-11-wifi.html

Android网络API并不是最重要的事情,因为有PITFALS取决于代码运行的API级别。

从Android 10起,由于“隐私”原因,许多网络的内容都受到限制,因此您无法处理不询问用户输入的问题,除非设备已植根或将您的应用程序设置为设备管理。

对于Android 11,有一个新的API提出一个系统对话框,并允许用户保存并连接到网络。这看起来像:

您可以通过称为android.settings.wifi_add_networks的意图启动此功能:

var intent = new Intent(
    "android.settings.WIFI_ADD_NETWORKS");
var bundle = new Bundle();
bundle.PutParcelableArrayList(
    "android.provider.extra.WIFI_NETWORK_LIST",
    new List<IParcelable>
    {
        new WifiNetworkSuggestion.Builder()
            .SetSsid(ssid)
            .SetWpa2Passphrase(password)
            .Build()
    });

intent.PutExtras(bundle);

StartActivityForResult(intent, AddWifiSettingsRequestCode);

然后,您可以在活动中获取结果onactivityResult并获取结果是这样:

if (requestCode == AddWifiSettingsRequestCode)
{
    if (data != null && data.HasExtra(
        "android.provider.extra.WIFI_NETWORK_RESULT_LIST"))
    {
        var extras =
            data.GetIntegerArrayListExtra(
                "android.provider.extra.WIFI_NETWORK_RESULT_LIST")
                ?.Select(i => i.IntValue()).ToArray() ?? new int[0];

        if (extras.Length > 0)
        {
            var ok = extras
                .Select(GetResultFromCode)
                .All(r => r == Result.Ok);
            // if ok is true, BINGO!
            return;
        }
    }
}

我在这里有一个存储库,上面有完整的样本: https://github.com/github.com/cheesebarub.com/cheesebaron/androidbaron/android11wifi < /a>

通过在野外使用它,我发现此API与OnePlus和Huawei等OEM的某些OEM无法很好地工作。其中一些要么限制或系统设置应用程序只是由于其配置错误而崩溃。对于那些,我回到了Android 10中引入的API。

I have a blog post about this topic here: https://blog.ostebaronen.dk/2020/11/android-11-wifi.html

Android Network API is not the greatest thing to work with as there are pitfals depending on the API level the code runs on.

From Android 10 and up a lot of the Network stuff has been restricted for "privacy" reasons, so you cannot work around not asking the user for input, unless the device is rooted or your App is set up as Device Admin.

For Android 11, there is a new API to present a system dialog and allow the user to save and connect to a network. This will look something like:
screenshot of system dialog

You can launch this through an Intent called android.settings.WIFI_ADD_NETWORKS:

var intent = new Intent(
    "android.settings.WIFI_ADD_NETWORKS");
var bundle = new Bundle();
bundle.PutParcelableArrayList(
    "android.provider.extra.WIFI_NETWORK_LIST",
    new List<IParcelable>
    {
        new WifiNetworkSuggestion.Builder()
            .SetSsid(ssid)
            .SetWpa2Passphrase(password)
            .Build()
    });

intent.PutExtras(bundle);

StartActivityForResult(intent, AddWifiSettingsRequestCode);

You can then get the result in your Activity overriding OnActivityResult and fetching the result like so:

if (requestCode == AddWifiSettingsRequestCode)
{
    if (data != null && data.HasExtra(
        "android.provider.extra.WIFI_NETWORK_RESULT_LIST"))
    {
        var extras =
            data.GetIntegerArrayListExtra(
                "android.provider.extra.WIFI_NETWORK_RESULT_LIST")
                ?.Select(i => i.IntValue()).ToArray() ?? new int[0];

        if (extras.Length > 0)
        {
            var ok = extras
                .Select(GetResultFromCode)
                .All(r => r == Result.Ok);
            // if ok is true, BINGO!
            return;
        }
    }
}

I have a repository here with the full sample: https://github.com/Cheesebaron/Android11WiFi

From using this in the wild, I've found that this API does not work nicely with some OEMs such as OnePlus and Huawei. Some of these either restrict or the System Settings App simply crashes due to a misconfiguration on their part. For those I fall back to the API's introduced in Android 10.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文