Skip to content

Commit

Permalink
Fix several ActivityNotFoundExceptions
Browse files Browse the repository at this point in the history
In certain screens of the app(like shared decks and account login) the
user could trigger an ACTION_VIEW from the content, which will
delegate to our custom tabs implementation. This will call the platform
launchUrl() method which would fail if there's no app to handle it.

Also added guards for the several extensions openUrl(), the check
AdaptionUtil.hasWebBrowser() is failing in a few cases.
  • Loading branch information
lukstbit authored and mikehardy committed Feb 3, 2025
1 parent f5b3d33 commit 3f21e3c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
20 changes: 18 additions & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/utils/AndroidUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package com.ichi2.anki.utils

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
Expand All @@ -28,6 +29,7 @@ import com.ichi2.anki.showThemedToast
import com.ichi2.anki.snackbar.showSnackbar
import com.ichi2.utils.AdaptionUtil
import com.ichi2.utils.copyToClipboard
import timber.log.Timber

/**
* Acquire a wake lock and release it after running [block].
Expand Down Expand Up @@ -73,7 +75,16 @@ fun Context.openUrl(uri: Uri) {
}
return
}
startActivity(Intent(Intent.ACTION_VIEW, uri))
try {
startActivity(Intent(Intent.ACTION_VIEW, uri))
} catch (ex: Exception) {
Timber.w("No app found to handle opening an external url from ${this::class.java.name}")
if (this is FragmentActivity) {
showSnackbar(R.string.activity_start_failed)
} else {
showThemedToast(this, R.string.activity_start_failed, false)
}
}
}

// necessary for Fragments that are BaseSnackbarBuilderProvider to work correctly
Expand All @@ -82,7 +93,12 @@ fun Fragment.openUrl(uri: Uri) {
showSnackbar(getString(R.string.no_browser_msg, uri.toString()))
return
}
startActivity(Intent(Intent.ACTION_VIEW, uri))
try {
startActivity(Intent(Intent.ACTION_VIEW, uri))
} catch (ex: ActivityNotFoundException) {
Timber.w("No app found to handle opening an external url from ${Fragment::class.java.name}")
showSnackbar(R.string.activity_start_failed)
}
}

fun Fragment.openUrl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package com.ichi2.compat.customtabs

import android.app.Activity
import android.content.ActivityNotFoundException
import android.net.Uri
import android.os.Bundle
import androidx.annotation.CheckResult
Expand All @@ -23,6 +24,8 @@ import androidx.browser.customtabs.CustomTabsClient
import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsServiceConnection
import androidx.browser.customtabs.CustomTabsSession
import com.ichi2.anki.R
import com.ichi2.anki.snackbar.showSnackbar
import timber.log.Timber

/**
Expand Down Expand Up @@ -171,7 +174,12 @@ class CustomTabActivityHelper : ServiceConnectionCallback {
}
} else {
customTabsIntent.intent.setPackage(packageName)
customTabsIntent.launchUrl(activity, uri)
try {
customTabsIntent.launchUrl(activity, uri)
} catch (ex: ActivityNotFoundException) {
Timber.w("No app found to handle opening an external url from CustomTabsActivityHelper")
activity.showSnackbar(R.string.activity_start_failed)
}
}
}

Expand Down

0 comments on commit 3f21e3c

Please sign in to comment.