Proveedores de widgets web

Puede rellenar un widget de Windows con HTML servido desde una dirección URL en lugar de definir su cuerpo con Tarjetas adaptables. El proveedor sigue suministrando una carga JSON de tarjeta adaptable que especifica la dirección URL de contenido. Comience con Implementar un proveedor de widgets en un Aplicación de Windows de C# o Implemente un proveedor de widgets en una aplicación win32 (C++/WinRT) y agregue las funcionalidades de contenido web que se describen aquí.

Las API de recursos y mensajería de este artículo se introdujeron en SDK de Aplicaciones para Windows 1.6.3. Use una versión estable actualmente compatible de los canales de versión de SDK de Aplicaciones para Windows y pruebe en un dispositivo Windows 11 con un host de widgets que admita contenido web.

Los ejemplos de C# son fragmentos para un proveedor de widgets de escritorio empaquetado. Agregue using Microsoft.Windows.Widgets.Providers; y using Windows.Storage.Streams; al archivo de origen del proveedor. Continúe implementando IWidgetProvider al agregar IWidgetResourceProvider o IWidgetProviderMessage.

Especificar la dirección URL de contenido

Envíe la carga JSON con WidgetManager.UpdateWidget. Especifique un objeto de metadatos con un campo webUrl que apunte al contenido HTML. Incluya un body de Adaptive Card como contenido de reserva para hosts que no admitan la carga de contenido web, en lugar de dejar esos hosts con un widget vacío.

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.6",
    "body": [
        {
            "type": "TextBlock",
            "text": "Open the app to view this content.",
            "wrap": true
        }
    ],
    "metadata": {
        "webUrl": "https://contoso.com/widgetprovider.html"
    }
}

La $host.isWebSupported propiedad de plantilla indica si el host admite contenido web. Úselo cuando necesite adaptar aún más la presentación alternativa. Para obtener más información, consulte propiedades del host de widgets de Windows.

Gestión de solicitudes de recursos

Los proveedores de widgets pueden especificar una cadena de filtro de solicitud web para un widget en el atributo WebRequestFilter del elemento Definition del archivo de manifiesto del paquete del proveedor. Siempre que el contenido del widget solicite un recurso por URI que coincida con el filtro, la solicitud se interceptará y redirigirá a la implementación del proveedor del widget de IWidgetResourceProvider.OnResourceRequested.

El patrón de filtro usa el formato descrito en Patrones de coincidencia. Utilice Punycode cuando sea necesario. El filtro debe coincidir con el origen especificado por webUrl. Las solicitudes de todos los tipos de contenido se redirigen cuando coinciden, por lo que limita el filtro a los recursos que gestiona tu proveedor. Para obtener más información, consulte Formato XML del manifiesto del paquete del proveedor de widgets.

Para controlar las solicitudes de recursos, los proveedores de widgets deben implementar la interfaz IWidgetResourceProvider .

internal class WidgetProvider : IWidgetProvider, IWidgetResourceProvider

En OnResourceRequested, establezca WidgetResourceRequestedArgs.Response en un WidgetResourceResponse que contenga el recurso. En este ejemplo se asigna una dirección URL solicitada a una imagen empaquetada. Incluya Assets\image.png como contenido en el paquete de la aplicación. RandomAccessStreamReference.CreateFromUri admite el esquema ms-appx, por lo que puede crear la referencia de flujo sin tener que esperar a que se busque el archivo.

void IWidgetResourceProvider.OnResourceRequested(WidgetResourceRequestedArgs args)
{
    if (args.Request.Uri == "https://contoso.com/logo-image")
    {
        var imageUri = new System.Uri("ms-appx:///Assets/image.png");
        var content = RandomAccessStreamReference.CreateFromUri(imageUri);
        var response = new WidgetResourceResponse(content, "OK", 200);
        response.Headers.Add("Content-Type", "image/png");
        args.Response = response;
    }
}

Este ejemplo sincrónico no necesita un aplazamiento. Si la implementación espera a terminar un trabajo antes de establecer la respuesta, llame a GetDeferral antes de que la devolución de llamada retorne, y complételo en un bloque finally. Gestione y notifique los errores asincrónicos según la directiva de gestión de errores de su aplicación.

Si no establece una respuesta, el sistema recupera el recurso de la web. Puede modificar WidgetResourceRequest.Headers en args.Request antes de esa recuperación. Agregue solo credenciales a solicitudes de orígenes de confianza; Una coincidencia de filtro por sí sola no es autorización para enviar un token.

Controlar mensajes hacia y desde el contenido web

Para recibir mensajes de cadena del contenido del widget que se ha publicado mediante el método javaScript window.chrome.webview.postMessage , los proveedores de widgets pueden implementar la interfaz IWidgetProviderMessage e implementar el método OnMessageReceived .

internal class WidgetProvider : IWidgetProvider, IWidgetProviderMessage

Agregue el callback a la clase de proveedor:

public void OnMessageReceived(WidgetMessageReceivedArgs args)
{
    System.Console.WriteLine($"Message received from widget {args.WidgetContext.Id}: {args.Message}");
}

Envíe un mensaje al contenido web de un widget con WidgetManager.SendMessageToContent. Pase el identificador de instancia del widget de WidgetContext.Id, no el identificador de definición del manifiesto del paquete. Varias instancias de una definición tienen identificadores de instancia diferentes.

Llame al siguiente asistente desde una devolución de llamada de proveedor y pase el WidgetContext para la instancia de destino, como el contexto recibido por CreateWidget o OnActionInvoked. Serialice mensajes estructurados en lugar de construir JSON con interpolación de cadenas, por lo que los valores que contienen comillas o barras diagonales inversas siguen siendo válidos.

private static void SendLocationToWidget(WidgetContext widgetContext, string location)
{
    string message = System.Text.Json.JsonSerializer.Serialize(
        new { current_location = location });
    WidgetManager.GetDefault().SendMessageToContent(widgetContext.Id, message);
}

El contenido web recibe el mensaje como una cadena mediante el evento window.chrome.webviewmessage. Si serializa JSON como en este ejemplo, analice la cadena en su contenido web. Para obtener más información, vea PostWebMessageAsString y el API de JavaScript WebView2.

Limitaciones y requisitos

Importante

Esta característica solo está disponible para los usuarios del Espacio Económico Europeo (EEE).

Los proveedores de widgets web no son proveedores de fuentes. Para las fuentes de panel y sus requisitos regionales, vea Paneles y proveedores de fuentes. Para obtener el manifiesto PWA independiente y la ruta de implementación de service worker, consulte Crear widgets impulsados por PWA.