Condividi tramite


Migrazione delle notifiche delle app dalla piattaforma UWP a WinUI 3

L'unica differenza durante la migrazione del codice di notifica dell'app da UWP a WinUI consiste nella gestione dell'attivazione delle notifiche. L'invio e la gestione delle notifiche delle app rimangono esattamente uguali.

Note

Il termine "notifica toast" viene sostituito con "notifica app". Questi termini si riferiscono entrambi alla stessa funzionalità di Windows, ma nel corso del tempo l'uso della "notifica di tipo avviso popup" verrà eliminato gradualmente nella documentazione.

Note

Alcune informazioni sono relative a un prodotto non definitivo, che potrebbe subire modifiche sostanziali prima del rilascio sul mercato. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Differenze di attivazione

Category UWP WinUI
Punto di ingresso di attivazione in primo piano OnActivated il metodo in App.xaml.cs viene chiamato OnLaunched viene chiamato il metodo all'interno di App.xaml.cs.
Punto di ingresso di attivazione in background Gestito separatamente come attività in background Uguale all'attivazione in primo piano. OnLaunched viene chiamato il metodo all'interno di App.xaml.cs. Usa GetActivatedEventArgs per determinare se l'app deve avviarsi completamente o semplicemente gestire l'attività e uscire.
Attivazione finestra Quando si verifica l'attivazione in primo piano ,la finestra viene automaticamente portata in primo piano Se lo si desidera, è necessario portare la finestra in primo piano

Migrazione per le app C#

Passaggio 1: installare la libreria NuGet

Per un'app WinUI, gestisci l'attivazione per le notifiche usando la classe AppNotificationManager . Questa classe viene fornita dal pacchetto Nuget Microsoft.WindowsAppSDK, che è incluso per impostazione predefinita nei modelli di progetto Visual Studio WinUI.

Passaggio 2: aggiornare il manifesto

In Package.appxmanifest aggiungere:

  1. Dichiarazione per xmlns:com
  2. Dichiarazione per xmlns:desktop
  3. Nell'attributo IgnorableNamespaces , com e desktop
  4. desktop:Extension per windows.toastNotificationActivation per dichiarare il CLSID dell'attivatore toast (usando un nuovo GUID di propria scelta).
  5. Solo MSIX: com:Extension per l'attivatore COM usando il GUID del passaggio 4. Assicurarsi di includere Arguments="----AppNotificationActivated:" in modo da sapere che il lancio è stato generato da una notifica
<!--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>

Passaggio 3: gestire l'attivazione

Nel codice di avvio dell'app (in genere App.xaml.cs), aggiornare il codice seguendo questa procedura:

  1. In OnLaunched, devi ottenere l'istanza predefinita della classe AppNotificationManager.
  2. Registrati all'evento invocato da AppNotificationManager.NotificationInvoked.
  3. Chiama Microsoft.Windows.AppNotifications.AppNotificationManager.Register per registrare l'app per ricevere gli eventi di notifica. È importante chiamare questo metodo dopo aver registrato il gestore NotificationInvoked .
  4. Rifattorizza il codice di avvio/attivazione della finestra in un metodo helper dedicato LaunchAndBringToForegroundIfNeeded, per poterlo chiamare da più punti.
  5. Creare un metodo helper HandleNotification in modo che possa essere chiamato da più posizioni.
  6. Chiamare AppInstance.GetActivatedEventArgs e controllare la proprietà AppActivationArguments.Kind dell'oggetto restituito per il valore ExtendedActivationKind.AppNotification.
  7. Se il tipo di attivazione non è AppNotification, utilizzare il metodo helper LaunchAndBringToForegroundIfNeeded.
  8. Se il tipo di attivazione è AppNotification eseguire il cast della proprietà AppActivationArguments.Data a AppNotificationActivatedEventArgs e passarlo al HandleNotification metodo helper.
  9. Nel gestore ApplicationManager.NotificationInvoked, chiama il metodo helper HandleNotification.
  10. Nel metodo helper HandleNotification, assicurarsi di inviare al dispatcher App o Window prima di eseguire codici relativi all'interfaccia utente, come la visualizzazione di una finestra o l'aggiornamento di un'interfaccia utente.
  11. Migra il codice UWP OnActivated precedente che gestiva l'attivazione delle notifiche dell'app al nuovo HandleNotification metodo di supporto.

Migrazione di App.xaml.cs


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
  {
      if (args.Argument.Contains("action"))
      {
          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;
          }
      }
      else
      {
          Debug.Print("Notification args is null");
      }
  });
}

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);
    }
}

Compilazione del contenuto delle notifiche dell'app

Con Windows App SDK è comunque possibile creare contenuto di notifica delle app usando xml non elaborato, ma è anche possibile creare contenuto di notifica dell'app usando la nuova classe AppNotificationsBuilder che sostituisce la classe ToastContentBuilder fornita da Windows Community Toolkit. Inviare la notifica dell'app chiamando AppNotificationManager.Show. Non è consigliabile combinare le API di Windows Community Toolkit e le API APP SDK.

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());