.NET MAUI Android: Как обработать ситуацию, когда вы пытаетесь запустить внешнее приложение, которое не установлено?

Вопрос или проблема

Я использую Launcher для открытия страницы Facebook из моего приложения следующим образом:

async Task OpenFacebook()
{
    try
    {
        // пытаемся открыть приложение Facebook, если не удалось, пытаемся открыть в браузере
        bool opened = await Launcher.Default.TryOpenAsync($"fb://profile?id={FacebookID}");
        if (opened)
            return;

        await Browser.OpenAsync(new Uri($"https://m.facebook.com/{FacebookID}"), BrowserLaunchMode.External);
    }
    catch (Exception ex)
    {
        
    }
}
<activity android:name="com.myapp.MainActivity" 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="fb"/>
    </intent-filter>
</activity>

Это работает, когда приложение Facebook установлено, но когда я удаляю приложение, я ожидал, что оно перейдет в браузер и просто откроет URL. На самом деле, оно просто выдает ошибку:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.myapp/com.myapp.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.myapp.MainActivity" on path: DexPathList[[zip file..., Замечание: opened возвращает true, и функция завершается нормально, затем я получаю вышеупомянутое исключение java, которое остается необработанным и вызывает сбой моего приложения. Мне удалось предотвратить сбой, переместив фильтр намерений в MainActivity.cs следующим образом:

[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "fb")]
public class MainActivity : MauiAppCompatActivity

Но теперь, когда я нажимаю кнопку для открытия FB, opened по-прежнему истинно, и не происходит перехода. Это работает как задумано на iOS, но не на Android. Есть идеи, что я делаю не так?

Ответ или решение

Как обрабатывать попытку запуска внешнего приложения в .NET MAUI для Android, когда приложение не установлено

При разработке приложения на .NET MAUI для Android важно учитывать сценарии, когда внешнее приложение, с которым вы хотите взаимодействовать, может не быть установлено на устройстве пользователя. Одним из таких случаев является попытка открыть приложение Facebook, как это показано в вашем коде. Вы правильно используете Launcher, чтобы сначала попытаться открыть приложение Facebook, а затем (если оно не установлено) — открыть веб-страницу в браузере. Однако вы столкнулись с проблемой, когда приложение аварийно завершает работу с ошибкой java.lang.RuntimeException.

Проблема

Когда Facebook не установлен, ваше приложение возвращает true в результате Launcher.Default.TryOpenAsync, что не отражает реального состояния (приложение не открывается). Это может происходить из-за того, что Launcher в фоновом режиме пытается обработать ваше намерение для запуска Facebook, но не находит приложения, что и приводит к сбою.

Решение проблемы

Вам нужно изменить подход к обработке ошибки, чтобы убедиться, что ваш контроллер правильно реагирует на ситуацию, когда Facebook не установлен. Проанализируем возможное решение вашей проблемы.

  1. Правильная обработка TryOpenAsync:

    • Давайте посмотрим на то, как вы обрабатываете результат от TryOpenAsync. Вместо того чтобы полагаться на возвращаемое значение как на индикатор успешности, проверьте детали выполнения.
  2. Использование LaunchError:

    • Когда TryOpenAsync возвращает true, это может означать, что намерение было обработано, но не всегда с ожидаемым результатом. Нужно ловить ошибки, возникающие при вызове TryOpenAsync, чтобы надёжно обработать сценарии, когда приложение недоступно.
  3. Использование обработки исключений:

    • Если TryOpenAsync вызывает исключения, их следует обрабатывать таким образом, чтобы ваш код мог принять решение об открытии браузера. Вот пример:
async Task OpenFacebook()
{
    try
    {
        // Попробуем открыть приложение Facebook
        bool opened = await Launcher.Default.TryOpenAsync($"fb://profile?id={FacebookID}");
        if (!opened)
        {
            // Если не удалось открыть приложение, открываем в браузере
            await Browser.OpenAsync(new Uri($"https://m.facebook.com/{FacebookID}"), BrowserLaunchMode.External);
        }
    }
    catch (Exception ex)
    {
        // Логируем исключение
        Console.WriteLine($"Ошибка при открытии Facebook: {ex.Message}");
        // Пытаемся открыть Facebook в браузере
        await Browser.OpenAsync(new Uri($"https://m.facebook.com/{FacebookID}"), BrowserLaunchMode.External);
    }
}
  1. Обновление вашего IntentFilter:
    • Вместо того чтобы размешать IntentFilter в MainActivity, рассмотрите возможность использования его непосредственно в классе, который фактически пытается взаимодействовать с Facebook. Пример:
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "fb")]
public class FacebookActivity : MauiAppCompatActivity
{
    // Ваш код для обработки действия
}

Заключение

Ваша проблема может быть решена путем более тщательной обработки получения результата от Launcher.Default.TryOpenAsync и правильным использованием try-catch для исключительных ситуаций. Такой подход обеспечит ваше приложение устойчивостью к ошибкам и улучшит пользовательский опыт. Следуя приведённым рекомендациям, вы сможете плавно обрабатывать ситуации, когда Facebook не установлен, и обеспечивать безошибочное открытие его веб-версии.

Оцените материал
Добавить комментарий

Капча загружается...