Поделиться через


Ссылки на приложения Android

Часто желательно подключить веб-сайт и мобильное приложение, чтобы ссылки на веб-сайт запускали мобильное приложение и отображали содержимое в мобильном приложении. Связывание приложений, которое также называется глубоким связыванием, — это метод, позволяющий мобильному устройству реагировать на URI и запускать содержимое в мобильном приложении, представленном универсальным кодом ресурса (URI).

Android обрабатывает ссылки приложений через систему намерений. При нажатии ссылки в мобильном браузере браузер будет отправлять намерение, которое Android будет делегировать зарегистрированным приложениям. Эти ссылки могут быть основаны на пользовательской схеме, например myappname://, или могут использовать схему HTTP или HTTPS. Например, щелкнув ссылку на веб-сайте рецепта, откроется мобильное приложение, связанное с этим веб-сайтом, а затем отобразится конкретный рецепт для пользователя. Если для обработки намерения зарегистрировано несколько приложений, Android отобразит диалоговое окно диамбигуации, которое просит пользователя, какое приложение выбрать для обработки намерения. Пользователи, у которых нет установленного приложения, принимают содержимое на веб-сайте.

Android классифицирует ссылки приложений на три категории:

  • Глубокие ссылки — это URI любой схемы, которая принимает пользователей к определенному содержимому в приложении. При щелчке глубокой ссылки может появиться диалоговое окно диамбигуации, которое просит пользователя выбрать приложение для обработки глубокой ссылки.
  • Веб-ссылки — это глубокие ссылки , использующие схему HTTP или HTTPS. В Android 12 и более поздних версиях веб-ссылка всегда отображает содержимое в веб-браузере. В предыдущих версиях Android, если приложение может обработать веб-ссылку, появится диалоговое окно дизамбигуации, которое просит пользователя выбрать приложение для обработки веб-ссылки.
  • Ссылки приложений Android, доступные в API 23+, — это веб-ссылки, использующие схему HTTP или HTTPS и содержащие autoVerify атрибут. Этот атрибут позволяет приложению стать обработчиком по умолчанию для ссылки на приложение. Поэтому при щелчке ссылки на приложение открывается без отображения диалогового окна диамбигуации.

Приложения Android для .NET MAUI могут поддерживать все три категории ссылок приложений. Однако в этой статье основное внимание уделяется ссылкам приложений Android. Для этого требуется подтверждение владения доменом, а также размещение файла JSON-файла ссылок цифровых ресурсов в домене, описывающего связь с приложением. Это позволяет Android убедиться, что приложение, пытающееся обработать URI, имеет право владения доменом URI, чтобы предотвратить перехват вредоносных приложений ссылок приложения.

Процесс обработки ссылок приложений Android в приложении .NET MAUI Android выглядит следующим образом:

  1. Проверьте владение доменом. Дополнительные сведения см. в разделе "Проверка владения доменом".
  2. Создайте и разместите файл ссылок на цифровые ресурсы на веб-сайте. Дополнительные сведения см. в статье "Создание и размещение файла ссылок на цифровые ресурсы".
  3. Настройте фильтр намерений в приложении для URI веб-сайта. Дополнительные сведения см. в разделе "Настройка фильтра намерений".
  4. Считывает данные из входящего намерения. Дополнительные сведения см. в разделе "Чтение данных из входящего намерения".

Внимание

Чтобы использовать ссылки на приложения Android, выполните приведенные ниже действия.

  • Версия приложения должна жить в Google Play.
  • Веб-сайт-компаньон должен быть зарегистрирован в приложении в консоли разработчика Google. После связи приложения с веб-сайтом URI можно индексировать, которые работают как для веб-сайта, так и для приложения, которые затем можно обслуживать в результатах поиска. Дополнительные сведения см. в разделе "Индексирование приложений в поиске Google" на support.google.com.

Дополнительные сведения о ссылках на приложения Android см. в разделе "Обработка ссылок приложений Android".

Проверка владения доменом

Вам потребуется проверить владение доменом, который вы обслуживаете ссылки приложений из консоли поиска Google. Проверка владения означает, что вы владеете определенным веб-сайтом. Консоль поиска Google поддерживает несколько подходов к проверке. Дополнительные сведения см. в разделе "Проверка владения сайтом" на support.google.com.

Для ссылок приложений Android требуется, чтобы Android проверил связь между приложением и веб-сайтом, прежде чем задать приложение в качестве обработчика по умолчанию для URI. Эта проверка будет происходить при первой установке приложения. Файл ссылок цифровых ресурсов — это JSON-файл, который должен размещаться соответствующим веб-доменом в следующем расположении: https://domain.name/.well-known/assetlinks.json

Файл цифрового ресурса содержит метаданные, необходимые для проверки связи Android. Для этого файла требуются следующие пары "ключ-значение".

  • namespace — пространство имен приложения Android.
  • package_name — имя пакета приложения Android.
  • sha256_cert_fingerprints — отпечатки пальцев SHA256 подписанного приложения, полученные из файла .keystore . Сведения о поиске подписи хранилища ключей см. в разделе "Поиск подписи хранилища ключей".

В следующем примере assetlinks.json файл предоставляет права на открытие ссылок приложению com.companyname.myrecipeapp Android:

[
   {
      "relation": [
         "delegate_permission/common.handle_all_urls"
      ],
      "target": {
         "namespace": "android_app",
         "package_name": "com.companyname.myrecipeapp",
         "sha256_cert_fingerprints": [
            "14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
         ]
      }
   }
]

Можно зарегистрировать несколько отпечатков пальцев SHA256 для поддержки различных версий или сборок приложения. Следующий assetlinks.json файл предоставляет права на открытие ссылок как приложениям Android, так и com.companyname.mycookingapp приложениям com.companyname.myrecipeapp Android:

[
   {
      "relation": [
         "delegate_permission/common.handle_all_urls"
      ],
      "target": {
         "namespace": "android_app",
         "package_name": "com.companyname.myrecipeapp",
         "sha256_cert_fingerprints": [
            "14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
         ]
      }
   },
   {
      "relation": [
         "delegate_permission/common.handle_all_urls"
      ],
      "target": {
         "namespace": "android_app",
         "package_name": "com.companyname.mycookingapp",
         "sha256_cert_fingerprints": [
            "14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
         ]
      }
   }
]

Совет

Используйте средство генератора списков инструкций и средства тестирования, чтобы создать правильный JSON и проверить его.

При публикации файла https://domain.name/.well-known/assetlinks.jsonпроверки JSON необходимо убедиться в следующем:

  • Файл обслуживается с типом application/jsonконтента.
  • Файл должен быть доступен по протоколу HTTPS независимо от того, используется ли приложение HTTPS в качестве схемы.
  • Файл должен быть доступен без перенаправлений.
  • Если ссылки приложения поддерживают несколько доменов, необходимо опубликовать файл assetlinks.json на каждом домене.

Вы можете убедиться, что файл цифровых активов правильно отформатирован и размещен с помощью API ссылок цифровых активов Google:

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=
  https://<WEB SITE ADDRESS>:&relation=delegate_permission/common.handle_all_urls

Дополнительные сведения см. в разделе "Объявление связей веб-сайтов" на developer.android.com.

Настройка фильтра намерений

Фильтр намерений должен быть настроен, который сопоставляет универсальный код ресурса (URI) или набор URI из веб-сайта в действие в приложении Android. В .NET MAUI это можно сделать, добавив IntentFilterAttribute его в действие. Фильтр намерений должен объявлять следующую информацию:

  • ActionView — это зарегистрирует фильтр намерений для реагирования на запросы на просмотр сведений.
  • Categories — фильтр намерений должен регистрировать оба CategoryDefault и CategoryBrowsable иметь возможность правильно обрабатывать веб-URI.
  • DataScheme — фильтр намерений должен объявлять пользовательскую схему, а также HTTPS и/или HTTPS.
  • DataHost — это домен, из которого будут исходить URI.
  • DataPathPrefix — это необязательный путь к ресурсам на веб-сайте, который должен начинаться с /.
  • AutoVerify — это сообщает Android проверить связь между приложением и веб-сайтом. Оно должно быть установлено в true противном случае Android не проверяет связь между приложением и веб-сайтом, поэтому не будет устанавливать приложение в качестве обработчика по умолчанию для URI.

В следующем примере показано, как использовать IntentFilterAttribute ссылки для обработки ссылок из https://www.recipe-app.com/recipes:

using Android.App;
using Android.Content;
using Android.Content.PM;

namespace MyNamespace;

[Activity(
    Theme = "@style/Maui.SplashTheme",
    MainLauncher = true,
    ConfigurationChanges = ConfigChanges.ScreenSize |
        ConfigChanges.Orientation |
        ConfigChanges.UiMode |
        ConfigChanges.ScreenLayout |
        ConfigChanges.SmallestScreenSize |
        ConfigChanges.KeyboardHidden |
        ConfigChanges.Density)]
[IntentFilter(
    new string[] { Intent.ActionView },
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
    DataScheme = "https",
    DataHost = "recipe-app.com",
    DataPath = "/recipe",
    AutoVerify = true,)]    
public class MainActivity : MauiAppCompatActivity
{
}

Примечание.

В фильтре намерений можно указать несколько схем и узлов. Дополнительные сведения см. в статье "Создание глубоких ссылок на содержимое приложения" на developer.android.com.

Android проверяет каждый узел, который определен в фильтрах намерений по файлу цифровых активов на веб-сайте, прежде чем зарегистрировать приложение в качестве обработчика по умолчанию для URI. Все фильтры намерений должны пройти проверку, прежде чем Android применит приложение как обработчик по умолчанию. После добавления фильтра намерений с универсальным кодом ресурса (URI) для содержимого действия Android может направлять любое намерение, соответствующее URI приложению во время выполнения.

Также может потребоваться пометить действие как экспортируемое, чтобы ваше действие можно было запустить другими приложениями. Это можно сделать, добавив Exported = true в существующий ActivityAttribute. Дополнительные сведения см. в разделе "Элемент Activity" в developer.android.com.

При вызове намерения веб-URI Android выполняет следующие действия до тех пор, пока запрос не завершится успешно:

  1. Открывает предпочтительное приложение для обработки URI.
  2. Открывает единственное доступное приложение для обработки URI.
  3. Позволяет пользователю выбрать приложение для обработки URI.

Дополнительные сведения о намерениях и фильтрах намерений см. в разделе "Намерения" и "Фильтры намерений" на developer.android.com.

Чтение данных из входящего намерения

Когда Android запускает действие с помощью фильтра намерений, можно использовать данные, предоставленные намерением, чтобы определить, что делать. Это должно выполняться в делегате раннего жизненного цикла, в идеале OnCreate. Делегат OnCreate вызывается при создании действия. Дополнительные сведения о делегатах жизненного цикла см. в разделе "События жизненного цикла платформы".

Чтобы ответить на вызываемый делегат жизненного цикла Android, вызовите ConfigureLifecycleEvents метод MauiAppBuilder объекта в методе CreateMauiapp класса MauiProgram . Затем вызовите ILifecycleBuilderAddAndroid метод и укажите Action обработчик для требуемого делегата:

using Microsoft.Maui.LifecycleEvents;
using Microsoft.Extensions.Logging;

namespace MyNamespace;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .ConfigureLifecycleEvents(lifecycle =>
            {
#if ANDROID
                lifecycle.AddAndroid(android =>
                {
                    android.OnCreate((activity, bundle) =>
                    {
                        var action = activity.Intent?.Action;
                        var data = activity.Intent?.Data?.ToString();

                        if (action == Android.Content.Intent.ActionView && data is not null)
                        {
                            Task.Run(() => HandleAppLink(data));
                        }
                    });
                });
#endif
            });

#if DEBUG
        builder.Logging.AddDebug();
#endif

        return builder.Build();
    }

    static void HandleAppLink(string url)
    {
        if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
            App.Current?.SendOnAppLinkRequestReceived(uri);
    }
}

Свойство Intent.Action извлекает действие, связанное с входящим намерением, и Intent.Data свойство извлекает данные, связанные с входящим намерением. При условии, что для действия намерения задано ActionViewзначение, данные намерения можно передать App в класс с SendOnAppLinkRequestReceived помощью метода.

Предупреждение

Ссылки приложений предлагают потенциальный вектор атаки в приложение, поэтому убедитесь, что вы проверяете все параметры URI и дис карта любые неправильные URI.

App В классе переопределите OnAppLinkRequestReceived метод для получения и обработки данных намерения:

namespace MyNamespace;

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();
    }

    protected override async void OnAppLinkRequestReceived(Uri uri)
    {
        base.OnAppLinkRequestReceived(uri);

        // Show an alert to test that the app link was received.
        await Dispatcher.DispatchAsync(async () =>
        {
            await Windows[0].Page!.DisplayAlert("App link received", uri.ToString(), "OK");
        });

        Console.WriteLine("App link: " + uri.ToString());
    }
}

В приведенном выше OnAppLinkRequestReceived примере переопределение отображает URI ссылки приложения. На практике ссылка приложения должна принимать пользователей непосредственно к содержимому, представленному URI, без каких-либо запросов, имен входа или других прерываний. OnAppLinkRequestReceived Поэтому переопределение — это расположение, из которого необходимо вызвать навигацию к содержимому, представленному URI.

Если файл цифрового ресурса размещен правильно, вы можете использовать мост отладки Android с adbпомощью средства диспетчера действий, amчтобы имитировать открытие URI, чтобы убедиться, что ссылки приложения работают правильно. Например, следующая команда пытается просмотреть действие целевого приложения, связанное с URI:

adb shell am start -W -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d YOUR_URI_HERE

Эта команда отправляет намерение, которое Android должен направлять в мобильное приложение, которое должно запускать и отображать действие, зарегистрированное для URI.

Примечание.

Вы можете работать adb с эмулятором или устройством.

Кроме того, можно отобразить существующие политики обработки ссылок для приложений, установленных на устройстве:

adb shell dumpsys package domain-preferred-apps

Эта команда отобразит следующие сведения:

  • Пакет — имя пакета приложения.
  • Домен — домены, разделенные пробелами, веб-ссылки которых будут обрабатываться приложением.
  • Состояние — текущее состояние обработки ссылок для приложения. Значение always означает, что приложение установлено AutoVerifytrue и прошло проверку системы. За ним следует шестнадцатеричное число, представляющее запись предпочтения.

Дополнительные сведения о команде см. в разделе "Мост отладки adb Android".

Кроме того, вы можете управлять ссылками приложений Android и проверять их с помощью консоли воспроизведения. Дополнительные сведения см. в разделе "Управление и проверка ссылок приложений Android" на developer.android.com.

Советы по устранению неполадок см. в разделе "Устранение распространенных ошибок реализации в developer.android.com".