Share via


Notificações de aplicativo da migração UWP para WinUI 3

A única diferença ao migrar o código de notificação do aplicativo da UWP para o WinUI 3 é lidar com a ativação de notificações. O envio e o gerenciamento de notificações de aplicativo permanecem exatamente iguais.

Observação

O termo "notificação do sistema" está sendo substituído por "notificação de aplicativo". Esses termos referem-se ao mesmo recurso do Windows, mas, ao longo do tempo, eliminaremos gradualmente o uso de "notificação do sistema" na documentação.

Observação

Algumas informações relacionam-se ao produto de pré-lançamento, o qual poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.

Diferenças de ativação

Categoria UWP WinUI 3
Ponto de entrada de ativação em primeiro plano OnActivated o método dentro App.xaml.cs é chamado OnLaunched o método dentro App.xaml.cs é chamado.
Ponto de entrada de ativação em segundo plano Tratado separadamente como uma tarefa em segundo plano O mesmo que a ativação em primeiro plano. OnLaunched o método dentro App.xaml.cs é chamado. Use GetActivatedEventArgs para determinar se o aplicativo deve iniciar totalmente ou apenas manipular a tarefa e encerrar.
Ativação da janela Sua janela é automaticamente trazida em primeiro plano quando ocorre a ativação em primeiro plano Você deve trazer sua janela para o primeiro plano, se desejado

Migração para aplicativos C#

Etapa 1: Instalar a biblioteca do NuGet

Para um aplicativo WinUI 3, você manipula a ativação de notificações usando a classe AppNotificationManager . Essa classe é fornecida pelo pacote Nuget Microsoft.WindowsAppSDK, que está incluído por padrão nos modelos de projeto do Visual Studio winui 3.

Etapa 2: Atualizar seu manifesto

Em seu Package.appxmanifest, adicione:

  1. Declaração para xmlns:com
  2. Declaração para xmlns:desktop
  3. No atributo IgnorableNamespaces, com e desktop
  4. desktop:Extension for windows.toastNotificationActivation to declare your toast activator CLSID (using a new GUID of your choice).
  5. SOMENTE MSIX: com:Extensão para o ativador COM usando o GUID da etapa nº 4. Certifique-se de incluir o Arguments="----AppNotificationActivated:" para que você saiba que seu lançamento foi de uma notificação
<!--Add these namespaces-->
<Package
  ...
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
  xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
  IgnorableNamespaces="... com desktop">
  ...
  <Applications>
    <Application>
      ...
      <Extensions>

        <!--Specify which CLSID to activate when app notification clicked-->
        <desktop:Extension Category="windows.toastNotificationActivation">
          <desktop:ToastNotificationActivation ToastActivatorCLSID="replaced-with-your-guid-C173E6ADF0C3" /> 
        </desktop:Extension>

        <!--Register COM CLSID LocalServer32 registry key-->
        <com:Extension Category="windows.comServer">
          <com:ComServer>
            <com:ExeServer Executable="YourProject.exe" Arguments="----AppNotificationActivated:" DisplayName="App notification activator">
              <com:Class Id="replaced-with-your-guid-C173E6ADF0C3" DisplayName="App notification activator"/>
            </com:ExeServer>
          </com:ComServer>
        </com:Extension>

      </Extensions>
    </Application>
  </Applications>
 </Package>

Etapa 3: manipular a ativação

No código de inicialização do aplicativo (normalmente App.xaml.cs), atualize o código usando as seguintes etapas:

  1. Em OnLaunched, obtenha a instância padrão da classe AppNotificationManager .
  2. Registre-se para o evento AppNotificationManager.NotificationInvoked .
  3. Chame Microsoft.Windows.AppNotifications.AppNotificationManager.Register para registrar seu aplicativo para receber eventos de notificação. É importante que você chame esse método depois de registrar o manipulador NotificationInvoked .
  4. Refatore o código de inicialização/ativação da janela em um método auxiliar dedicado LaunchAndBringToForegroundIfNeeded , para que você possa chamá-lo de vários locais.
  5. Crie um HandleNotification método auxiliar para que ele possa ser chamado de vários locais.
  6. Chame AppInstance.GetActivatedEventArgs e marcar a propriedade AppActivationArguments.Kind do objeto retornado para o valor ExtendedActivationKind.AppNotification.
  7. Se o tipo de ativação não for AppNotification , chame o método auxiliar LaunchAndBringToForegroundIfNeeded .
  8. Se o tipo de ativação for AppNotification , converta a propriedade AppActivationArguments.Data em um AppNotificationActivatedEventArgs e passe-a para o HandleNotification método auxiliar.
  9. No manipulador ApplicationManager.NotificationInvoked , chame o HandleNotification método auxiliar.
  10. Em seu HandleNotification método auxiliar, certifique-se de expedir para o dispatcher de Aplicativo ou Janela antes de executar qualquer código relacionado à interface do usuário, como mostrar uma janela ou atualizar a interface do usuário
  11. Migre seu código UWP OnActivated antigo que manipulava a ativação de notificação do aplicativo para seu novo HandleNotification método auxiliar.

App.xaml.cs migrado


protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    m_window = new MainWindow();

    // To ensure all Notification handling happens in this process instance, register for
    // NotificationInvoked before calling Register(). Without this a new process will
    // be launched to handle the notification.
    AppNotificationManager notificationManager = AppNotificationManager.Default;
    notificationManager.NotificationInvoked += NotificationManager_NotificationInvoked;
    notificationManager.Register();

    var activatedArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
    var activationKind = activatedArgs.Kind;
    if (activationKind != ExtendedActivationKind.AppNotification)
    {
        LaunchAndBringToForegroundIfNeeded();
    } else
    {
        HandleNotification((AppNotificationActivatedEventArgs)activatedArgs.Data);
    }

}

private void LaunchAndBringToForegroundIfNeeded()
{
    if (m_window == null)
    {
        m_window = new MainWindow();
        m_window.Activate();

        // Additionally we show using our helper, since if activated via a app notification, it doesn't
        // activate the window correctly
        WindowHelper.ShowWindow(m_window);
    }
    else
    {
        WindowHelper.ShowWindow(m_window);
    }
}

private void NotificationManager_NotificationInvoked(AppNotificationManager sender, AppNotificationActivatedEventArgs args)
{
    HandleNotification(args);
}

private void HandleNotification(AppNotificationActivatedEventArgs args)
{
  // Use the dispatcher from the window if present, otherwise the app dispatcher
  var dispatcherQueue = m_window?.DispatcherQueue ?? DispatcherQueue.GetForCurrentThread();


  dispatcherQueue.TryEnqueue(async delegate
  {

      switch (args.Arguments["action"])
      {
          // Send a background message
          case "sendMessage":
              string message = args.UserInput["textBox"].ToString();
              // TODO: Send it

              // If the UI app isn't open
              if (m_window == null)
              {
                  // Close since we're done
                  Process.GetCurrentProcess().Kill();
              }

              break;

          // View a message
          case "viewMessage":

              // Launch/bring window to foreground
              LaunchAndBringToForegroundIfNeeded();

              // TODO: Open the message
              break;
      }
  });
}

private static class WindowHelper
{
    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    public static void ShowWindow(Window window)
    {
        // Bring the window to the foreground... first get the window handle...
        var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window);

        // Restore window if minimized... requires DLL import above
        ShowWindow(hwnd, 0x00000009);

        // And call SetForegroundWindow... requires DLL import above
        SetForegroundWindow(hwnd);
    }
}

Criando conteúdo de notificação do aplicativo

Com SDK do Aplicativo Windows, você ainda pode criar conteúdo de notificação de aplicativo usando xml bruto, mas também pode criar conteúdo de notificação de aplicativo usando a nova API AppNotificationsBuilder que substitui a classe ToastContentBuilder fornecida pelo Kit de Ferramentas da Comunidade do Windows. Envie a notificação do aplicativo chamando AppNotificationManager.Show. Não é recomendável misturar APIs do SDK do Windows Community Toolkit e do SDK do Aplicativo.

using Microsoft.Windows.AppNotifications;
using Microsoft.Windows.AppNotifications.Builder;

...

var builder = new AppNotificationBuilder()
    .AddText("Send a message.")
    .AddTextBox("textBox")
    .AddButton(new AppNotificationButton("Send")
        .AddArgument("action", "sendMessage"));

var notificationManager = AppNotificationManager.Default;
notificationManager.Show(builder.BuildNotification());