Udostępnij za pośrednictwem


Moduł uruchamiania

Przeglądaj przykład. Przeglądanie przykładu

W tym artykule opisano sposób używania interfejsu użytkownika aplikacji wieloplatformowej platformy .NET (.NET MAUI). ILauncher Ten interfejs umożliwia aplikacji otwieranie identyfikatora URI przez system. Ten sposób otwierania aplikacji jest często używany przy korzystaniu z głębokich linków do niestandardowych schematów URI innej aplikacji.

Domyślna implementacja interfejsu ILauncher jest dostępna za pośrednictwem właściwości Launcher.Default. Zarówno interfejs ILauncher, jak i klasa Launcher znajdują się w przestrzeni nazw Microsoft.Maui.ApplicationModel.

Ważne

Aby otworzyć przeglądarkę w witrynie internetowej, zamiast tego użyj interfejsu API przeglądarki.

Rozpocznij

Aby uzyskać dostęp do funkcji uruchamiania, wymagana jest następująca konfiguracja specyficzna dla platformy.

Jeśli chcesz używać linków bezpośrednich do otwierania innych aplikacji systemu Android, należy zdefiniować filtr intencji w aplikacji. Można to osiągnąć, dodając następujący kod XML do pliku 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>

Elementy <data> to schematy identyfikatorów URI wstępnie zarejestrowane w aplikacji. Nie można używać schematów, które nie są zdefiniowane w filtrze intencji.

Aby umożliwić przeglądanie aplikacji z innych aplikacji, zadeklaruj element <data> za pomocą atrybutu android:scheme:

<data android:scheme="appName"/>

Otwieranie innej aplikacji

Aby użyć funkcji Launchera, wywołaj metodę ILauncher.OpenAsync i przekaż String lub Uri reprezentujących aplikację do otwarcia. Opcjonalnie można użyć metody ILauncher.CanOpenAsync(Uri), aby sprawdzić, czy schemat identyfikatora URI może być obsługiwany przez aplikację na urządzeniu. Poniższy kod pokazuje, jak sprawdzić, czy schemat identyfikatora URI jest obsługiwany, czy nie, a następnie otwiera identyfikator URI:

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

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

Poprzedni przykład kodu można uprościć przy użyciu TryOpenAsync(Uri), który sprawdza, czy schemat identyfikatora URI można otworzyć przed jego otwarciem:

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

if (launcherOpened)
{
    // Do something fun
}

Otwieranie innej aplikacji za pośrednictwem pliku

Launcher może również służyć do otwierania aplikacji z wybranym plikiem. Program .NET MAUI automatycznie wykrywa typ pliku (MIME) i otwiera domyślną aplikację dla tego typu pliku. Jeśli dla typu pliku zarejestrowano więcej niż jedną aplikację, użytkownikowi zostanie wyświetlone wyskakujące okno wyboru aplikacji.

Poniższy przykład kodu zapisuje tekst w pliku i otwiera plik tekstowy za pomocą modułu uruchamiania:

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

Kontrolowanie lokalizacji plików

Ważne

Ta sekcja dotyczy tylko systemu Android.

W niektórych scenariuszach na Androidzie, na przykład gdy plik znajduje się w prywatnej pamięci, można go skopiować do pamięci podręcznej aplikacji, która jest następnie udostępniana za pośrednictwem systemu Android FileProvider. Może to jednak przypadkowo odsłonić całą pamięć podręczną i dane aplikacji atakującemu. Można temu zapobiec, dodając do aplikacji plik z zastąpionymi ścieżkami plików dostawcy, oraz upewniając się, że pliki są kopiowane do lokalizacji określonej w tym pliku przed ich udostępnieniem.

Aby dodać plik, który zastępuje ścieżki plików dostawcy w Twojej aplikacji, dodaj plik o nazwie microsoft_maui_essentials_fileprovider_file_paths.xml do folderu Platforms\Android\Resources\xml w aplikacji. W związku z tym pełna względna nazwa pliku projektu powinna być Platformy\Android\Resources\xml\microsoft_maui_essentials_fileprovider_file_paths.xml. Następnie dodaj kod XML do pliku dla wymaganych ścieżek:

 <?xml version="1.0" encoding="UTF-8" ?>
 <paths>
    <external-path name="external_files" path="sharing-root" />
    <cache-path name="internal_cache" path="sharing-root" />
    <external-cache-path name="external_cache" path="sharing-root" />  
 </paths>

Aby uzyskać więcej informacji na temat ścieżek dostawcy plików, zobacz FileProvider w developer.android.com.

Przed udostępnieniem pliku upewnij się, że został on najpierw zapisany w folderze sharing-root w jednej z lokalizacji wymienionych w pliku zastąpienia:

// Write into the specific sub-directory
var dir = Path.Combine(FileSystem.CacheDirectory, "sharing-root");  
Directory.CreateDirectory(dir);
var file = Path.Combine(dir, "mydata.txt");
await File.WriteAllTextAsync(file, $"My data: {count}");

// Share the file
await Launcher.OpenAsync(new OpenFileRequest
{
   Title = "My data",
   File = new ReadOnlyFile(file),
});

Możesz sprawdzić, czy plik jest poprawnie udostępniany, jeśli udostępniony identyfikator URI wyklucza katalog główny udostępniania. Jeśli na przykład udostępnisz plik <CacheDirectory>/sharing-root/mydata.txt, a udostępniony identyfikator URI jest content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/sharing-root/mydata.txt, dostawca plików nie używa prawidłowej ścieżki. Jeśli udostępniony identyfikator URI jest content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/mydata.txt, dostawca plików używa poprawnej ścieżki.

Ostrzeżenie

Jeśli podczas udostępniania pliku otrzymasz Java.Lang.IllegalArgumentExceptionz komunikatem podobnym do "Nie można odnaleźć ustawionego katalogu głównego zawierającego /data/data/com.companyname.overwritefileproviderpaths/cache/some-non-sharing-path/mydata.txt", najprawdopodobniej udostępniasz plik znajdujący się poza katalogiem root udostępniania.

Ustawianie lokalizacji uruchamiania

Ważne

Ta sekcja dotyczy tylko systemu iPadOS.

Podczas żądania udostępnienia lub otwierania aplikacji uruchamiającej w systemie iPadOS można ją przedstawić w popover. Określa, gdzie pojawi się okno pop-up i wskazuje miejsce, do którego będzie skierowana strzałka. Ta lokalizacja jest często kontrolką uruchamiającą akcję. Lokalizację można określić przy użyciu właściwości 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
    });

Wszystkie opisane tutaj elementy działają równie dobrze dla Share i Launcher.

Oto metoda rozszerzenia, która pomaga obliczyć granice widoku:

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

Można go następnie użyć podczas wywoływania 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
    }
}

Można przekazać element wywołujący, kiedy Command zostanie wyzwolony.

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

Aby zapoznać się z przykładem klasy ViewHelpers, zobacz przykład .NET MAUI hostowany w witrynie GitHub.

Różnice między platformami

W tej sekcji opisano różnice specyficzne dla platformy w API uruchamiania.

Task zwrócony z CanOpenAsync kończy się natychmiastowo.