如何在 C# Xamarin Android 应用程序中先连接到本地网络而不是互联网?

How to connect to local network first instead of internet in C# Xamarin Android app?

我有一个 Xamarin Android 应用程序。它连接到某些 IOT 设备的“无基于互联网的 Wifi 路由器”。但它也需要使用手机的蜂窝数据在 Dropbox 上存储一些信息。

现在工作如下:

  1. 我可以通过编程方式打开 on/off Wifi 连接。
  2. 我无法打开 on/off 蜂窝数据(因为 Android L)。它不允许在非根设备上使用。
  3. 当我的 phone 连接到这个本地 Wifi 路由器并且蜂窝数据也打开时,Android 默认工作方式,它使用来自蜂窝连接的互联网和我对 Dropbox 的所有调用工作没有任何问题。
  4. 但是,当本地 Wifi“没有互联网”时,这种对蜂窝网络的偏好导致我的应用程序永远无法连接到本地设备。假设我的一个设备正在侦听端口 9000 上的 IP 192.168.2.3,当我尝试连接到它时,我的代码通过蜂窝数据搜索它并且找不到 returns 主机。
  5. 那么在这种情况下有没有办法连接到本地设备?
  6. 作为解决方法,我手动提供了模式弹出窗口,以指示用户在需要“非”Dropbox 调用(例如连接到 IOT 设备)时禁用 Cellular。但这不是一个好的用户体验,因为用户必须不断地手动更改网络。我希望代码以更透明的方式处理这个问题。

请指教。

我能想到的解决方案是,您可以尝试使用 Xamarin.Essentials 并检查连接配置文件,并使用它强制将请求发送到您的 Wifi,而其他请求则通过蜂窝数据

var profiles = Connectivity.ConnectionProfiles;
if (profiles.Contains(ConnectionProfile.WiFi))
{
    // Active Wi-Fi connection.
}

可以找到文档 here

使用Plugin.Essentials(需要一个NetStandard项目)并参考这个link:

https://docs.microsoft.com/en-us/xamarin/essentials/connectivity?tabs=android

尝试本地访问而不是网络。

经过多次尝试和失败后,我能够实施此处提供的方法:

我将此代码从 Java 更改为 Xamarin C#,并且能够以编程方式强制将蜂窝网络或 Wifi 作为首选网络。

我的实现:

using Android.Net;
public SomeClass{
    public static Context _context = Android.App.Application.Context;

    ....

    /// <summary>
    /// Forces the wifi over cellular.
    /// </summary>
    public static void ForceWifiOverCellular()
    {
        ConnectivityManager connection_manager = (ConnectivityManager)_context.GetSystemService(Context.ConnectivityService);

        NetworkRequest.Builder request = new NetworkRequest.Builder();
        request.AddTransportType(TransportType.Wifi);

        var callback = new ConnectivityManager.NetworkCallback();
        connection_manager.RegisterNetworkCallback(request.Build(), new CustomNetworkAvailableCallBack());

    }

    /// <summary>
    /// Forces the cellular over wifi.
    /// </summary>
    public static void ForceCellularOverWifi()
    {
        ConnectivityManager connection_manager = (ConnectivityManager)_context.GetSystemService(Context.ConnectivityService);

        NetworkRequest.Builder request = new NetworkRequest.Builder();
        request.AddTransportType(TransportType.Cellular);

        connection_manager.RegisterNetworkCallback(request.Build(), new CustomNetworkAvailableCallBack());
    }
}


/// <summary>
/// Custom network available call back.
/// </summary>
public class CustomNetworkAvailableCallBack : ConnectivityManager.NetworkCallback
{
    public static Context _context = Android.App.Application.Context;

    ConnectivityManager connection_manager = (ConnectivityManager)_context.GetSystemService(Context.ConnectivityService);

    public override void OnAvailable(Network network)
    {
        //ConnectivityManager.SetProcessDefaultNetwork(network);    //deprecated (but works even in Android P)
        connection_manager.BindProcessToNetwork(network);           //this works in Android P
    }
}

用法:

  1. 我需要强制移动电话的地方,只需拨打:

SomeClass.ForceCellularOverWifi();

  1. 需要强制Wifi的地方,拨打:

SomeClass.ForceWifiOverCellular();

希望这对其他人有帮助。