Compartir a través de


Launcher

Browse sample. Examinar el ejemplo

En este artículo se describe cómo puedes usar la interfaz ILauncher de .NET Multi-Platform App UI (.NET MAUI). Esta interfaz permite que el sistema abra una aplicación con un URI. Esta forma de abrir una aplicación a menudo se usa al vincular en profundidad en los esquemas de URI personalizados de otra aplicación.

La implementación predeterminada de la interfaz ILauncher está disponible a través de la propiedad Launcher.Default. Tanto la interfaz ILauncher como la clase Launcher están contenidas en el espacio de nombres Microsoft.Maui.ApplicationModel.

Importante

Para abrir el explorador en un sitio web, usa la API del explorador en su lugar.

Introducción

Para acceder a la funcionalidad de Launcher, se requiere la siguiente configuración específica para la plataforma.

Si deseas usar vínculos profundos para abrir otras aplicaciones Android, debes definir un filtro de intención en la aplicación. Esto se puede lograr agregando el siguiente XML al archivo Platforms/Android/AndroidManifest.xml:

<activity android:name="appName" android:exported="true">
    <intent-filter>
       <action android:name="android.intent.action.VIEW" />
       <category android:name="android.intent.category.DEFAULT" />
       <category android:name="android.intent.category.BROWSABLE" />
       <data android:scheme="lyft"/>
       <data android:scheme="fb"/>
       </intent-filter>
</activity>

Los elementos <data> son los esquemas de URI registrados previamente con la aplicación. No puedes usar esquemas que no estén definidos en el filtro de intención.

Para que la aplicación se pueda examinar desde otras aplicaciones, declara un elemento <data> con el atributo android:scheme:

<data android:scheme="appName"/>

Apertura de otra aplicación

Para usar la funcionalidad de Launcher, llama al método ILauncher.OpenAsync y pasa un String o Uri que represente la aplicación a abrir. Una opción es usar el método ILauncher.CanOpenAsync(Uri) para comprobar si el esquema de URI se puede manejar desde una aplicación del dispositivo. En el código siguiente se muestra cómo comprobar si se admite o no un esquema de URI y, luego, abre el URI:

bool supportsUri = await Launcher.Default.CanOpenAsync("lyft://");

if (supportsUri)
    await Launcher.Default.OpenAsync("lyft://ridetype?id=lyft_line");

El ejemplo de código anterior se puede simplificar mediante TryOpenAsync(Uri), que comprueba si se puede abrir el esquema de URI antes de abrirlo:

bool launcherOpened = await Launcher.Default.TryOpenAsync("lyft://ridetype?id=lyft_line");

if (launcherOpened)
{
    // Do something fun
}

Apertura de otra aplicación a través de un archivo

Launcher también se puede usar para abrir una aplicación con un archivo seleccionado. .NET MAUI detecta automáticamente el tipo de archivo (MIME) y abre la aplicación predeterminada para ese tipo de archivo. Si se registra más de una aplicación con el tipo de archivo, se muestra una ventana emergente de selección de la aplicación al usuario.

En el ejemplo de código siguiente se escribe texto en un archivo y se abre el archivo de texto con Launcher:

string popoverTitle = "Read text file";
string name = "File.txt";
string file = System.IO.Path.Combine(FileSystem.CacheDirectory, name);

System.IO.File.WriteAllText(file, "Hello World");

await Launcher.Default.OpenAsync(new OpenFileRequest(popoverTitle, new ReadOnlyFile(file)));

Establecimiento de la ubicación del iniciador

Importante

Esta sección solo se aplica a iPadOS.

Al solicitar un recurso compartido o abrir el iniciador en iPadOS, tienes la posibilidad de presentar un elemento emergente. Esto especifica dónde aparecerá el elemento emergente y le apuntará directamente una flecha. Esta ubicación suele ser el control que inició la acción. Puede especificar la ubicación con la propiedad PresentationSourceBounds:

await Share.RequestAsync(new ShareFileRequest
    {
        Title = Title,
        File = new ShareFile(file),
        PresentationSourceBounds = DeviceInfo.Platform == DevicePlatform.iOS && DeviceInfo.Idiom == DeviceIdiom.Tablet
                                ? new Rect(0, 20, 0, 0)
                                : Rect.Zero
    });
await Launcher.OpenAsync(new OpenFileRequest
    {
        File = new ReadOnlyFile(file),
        PresentationSourceBounds = DeviceInfo.Platform == DevicePlatform.iOS && DeviceInfo.Idiom == DeviceIdiom.Tablet
                                ? new Rect(0, 20, 0, 0)
                                : Rect.Zero
    });

Todo lo que se describe aquí funciona igual para Share y Launcher.

Este es un método de extensión que ayuda a calcular los límites de una vista:

public static class ViewHelpers
{
    public static Rect GetAbsoluteBounds(this Microsoft.Maui.Controls.View element)
    {
        Element looper = element;

        var absoluteX = element.X + element.Margin.Top;
        var absoluteY = element.Y + element.Margin.Left;

        // Add logic to handle titles, headers, or other non-view bars

        while (looper.Parent != null)
        {
            looper = looper.Parent;
            if (looper is Microsoft.Maui.Controls.View v)
            {
                absoluteX += v.X + v.Margin.Top;
                absoluteY += v.Y + v.Margin.Left;
            }
        }

        return new Rect(absoluteX, absoluteY, element.Width, element.Height);
    }
}

Después, se puede usar al llamar a RequestAsync:

public Command<Microsoft.Maui.Controls.View> ShareCommand { get; } = new Command<Microsoft.Maui.Controls.View>(Share);

async void Share(Microsoft.Maui.Controls.View element)
{
    try
    {
        await Share.Default.RequestAsync(new ShareTextRequest
        {
            PresentationSourceBounds = element.GetAbsoluteBounds(),
            Title = "Title",
            Text = "Text"
        });
    }
    catch (Exception)
    {
        // Handle exception that share failed
    }
}

Puede pasar el elemento que realiza la llamada cuando se desencadene Command:

<Button Text="Share"
        Command="{Binding ShareWithFriendsCommand}"
        CommandParameter="{Binding Source={RelativeSource Self}}"/>

Para obtener un ejemplo de la clase ViewHelpers, consulta el ejemplo de .NET MAUI hospedado en GitHub.

Diferencias entre plataformas

En esta sección se describen las diferencias específicas de la plataforma con la API del iniciador.

El Task devuelto desde CanOpenAsync se completa de inmediato.