Как сначала подключиться к локальной сети вместо Интернета в приложении C # Xamarin для Android?

У меня есть приложение Xamarin для Android. Он подключается к «маршрутизатору Wi-Fi без Интернета» для некоторых устройств IOT. Но ему также необходимо использовать сотовые данные мобильного телефона для хранения некоторой информации в Dropbox.

Теперь это работает следующим образом:

  1. Могу программно включить / выключить Wifi соединение.
  2. Не могу включить / выключить сотовые данные (начиная с Android L). Это не разрешено на устройствах без рута.
  3. Когда мой телефон подключен к этому локальному маршрутизатору Wi-Fi и сотовые данные также включены, Android работает по умолчанию, он использует Интернет из сотового соединения, и все мои звонки в Dropbox работают без каких-либо проблем.
  4. Но это предпочтение сотовой связи, когда у локального Wi-Fi «нет Интернета», приводит к тому, что мое приложение никогда не подключается к локальным устройствам. Скажем, одно из моих устройств прослушивает IP 192.168.2.3 на порту 9000, когда я пытаюсь подключиться к нему, мой код ищет его через сотовые данные и возвращает хост, который не найден.
  5. Так есть ли способ подключиться к локальным устройствам в этом сценарии?
  6. В качестве обходного пути я вручную предоставил модальные всплывающие окна, чтобы проинструктировать пользователей отключить сотовую связь, когда требуются «не» вызовы Dropbox, такие как подключение к устройствам IOT. Но это не очень хороший пользовательский опыт, поскольку пользователям приходится постоянно менять сети вручную. Я хотел бы, чтобы код обрабатывал это более прозрачным образом.

Пожалуйста, порекомендуйте.


person Pawan Pillai    schedule 13.06.2019    source источник


Ответы (3)


После множества попыток и неудач мне удалось реализовать подход, представленный здесь: Ссылка на Stackoverflow

Я изменил этот код с Java на Xamarin C # и смог программно настроить сотовую связь или Wi-Fi в качестве предпочтительной сети.

Моя реализация:

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. Если мне нужно включить Wi-Fi, просто позвоните:

SomeClass.ForceWifiOverCellular ();

Надеюсь, это поможет другим.

person Pawan Pillai    schedule 14.06.2019

Решение, которое я могу придумать, заключается в том, что вы можете попробовать использовать Xamarin.Essentials и проверить профиль соединения и использовать это для принудительного выполнения запросов к вашему Wi-Fi и других запросов через сотовые данные.

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

Документацию можно найти здесь .

person Bruno Caceiro    schedule 13.06.2019
comment
Спасибо, но это просто говорит о том, к какому соединению подключено приложение. Это не помогло, так как я иногда хотел включить сотовую сеть и использовать локальный Wi-Fi для других функций. После долгих исследований я смог реализовать это в определенном смысле. Подробности см. В моем ответе ниже. - person Pawan Pillai; 14.06.2019

Используйте Plugin.Essentials (требуется проект NetStandard) и перейдите по этой ссылке:

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

попробуйте локальный доступ, а не сетевой.

person El andaloussi Ishrak    schedule 13.06.2019
comment
Спасибо за предложение, но, к сожалению, это не помогло, так как я иногда хотел включить сотовую сеть и принудительно использовать локальный Wi-Fi для других функций. После долгих исследований я смог реализовать это в определенном смысле. Подробности см. В моем ответе ниже. - person Pawan Pillai; 14.06.2019