Получить текущую активность из Application.Context — MonoAndroid

В настоящее время я разрабатываю приложение с использованием Xamarin.Forms, которое будет доступно на платформах Android и iOS. Когда приложение впервые загружается на устройство, я проверяю, есть ли доступное интернет-соединение на устройстве. Я хочу отобразить диалоговое окно, если подключение к Интернету недоступно.

Вот следующий фрагмент кода, который я использую для проверки Интернета на Xamarin.Forms.ContentPage

if(App.Connectivity.IsNetworkConnectivityAvailable())
{
    App.Notification.DisplayLocalNotifications("No Internet", "You need an internet connection to access certain application content");
}

Я использую внедрение зависимостей для создания соответствующего модуля для обработки диалоговых окон для каждой соответствующей среды. Android выдает следующее исключение

Android.Views.WindowManagerBadTokenException: невозможно добавить окно — токен null не для приложения. Вот код метода DisplayLocalNotification на Android:

public void DisplayLocalNotification(string title, string content)
{        
     AlertDialog.Builder builder = new AlertDialog.Builder(Application.Context)
          .SetTitle(title)
          .SetMessage(content)
          .SetCancelable(true)
          .SetPositiveButton("OK", (EventHandler<DialogClickEventArgs>) null);

      AlertDialog alert = builder.Create();
      alert.Show();

      var okBtn = alert.GetButton((int)DialogButtonType.Positive);

      okBtn.Click += (sender, args) =>
      {
           alert.Dismiss();
      };
}

После некоторых исследований мне нужно передать текущую активность конструктору AlertDialog.Builder вместо Application.Context. Как получить текущий объект действия из контекста приложения, когда вам нужно действие вне контекста действия?


person Michael Kniskern    schedule 01.09.2014    source источник
comment
Разве в Xamarin нет базовой концепции передачи экземпляра объекта простым использованием this?   -  person Squonk    schedule 02.09.2014
comment
@Squonk - да, но этот код не вызывается из класса, который наследуется от объекта AndroidActivity. Он содержится в классе, который не знает текущий объект активности, но может получить доступ к объекту Application.Context.   -  person Michael Kniskern    schedule 02.09.2014
comment
Если у вас нет активного Activity, вы не можете гарантировать, что он существует. Что-то должно быть активным/видимым, чтобы создать AlertDialog, и в этом случае вы должны использовать этот Activity Context. Application в терминах Android не имеет видимости и представляет собой скелетную структуру.   -  person Squonk    schedule 02.09.2014
comment
Надеюсь, это поможет stackoverflow.com/a/28423385/185022   -  person AZ_    schedule 10.02.2015


Ответы (1)


Код платформы Android Xamarin.Forms должен назначать текущее действие свойству Forms.Context. Это статический класс Forms, и если вы отлаживаете его, вы увидите, что Forms.Context является действием.

public static class Forms
{
    public static Context Context { get; }
    public static bool IsInitialized { get; }

    public static event EventHandler<ViewInitializedEventArgs> ViewInitialized;

    public static void Init(Activity activity, Bundle bundle);
}
person SKall    schedule 02.09.2014
comment
Да, класс Xamarin.Forms.Forms имеет сигнатуру метода Init с Activity в качестве входного параметра, но он недоступен как свойство - person Michael Kniskern; 02.09.2014
comment
Это. Forms.Context — это текущая активность. - person SKall; 02.09.2014
comment
Спасибо! Замена этого AlertDialog.Builder builder = new AlertDialog.Builder(Application.Context) на этот AlertDialog.Builder builder = new AlertDialog.Builder(Forms.Context) работает - person Michael Kniskern; 02.09.2014
comment
Xamarin нуждается в лучшей документации по объекту Forms.Context. - person Timothy Lee Russell; 20.03.2015
comment
В общем, им нужна гораздо лучшая документация. - person SKall; 20.03.2015
comment
Я даже не хочу знать, как вы получили доступ к Forms.Context из обычного Xamarin. - person Reynevan; 30.05.2017
comment
Вы не получите к нему доступ из обычного Xamarin, поскольку это элемент, специфичный для Forms. Ближайшим, вероятно, будет Android.App.Application.Context - person SKall; 30.05.2017