From c18dbb1b32020ca3947406ac505aa8a6080777cc Mon Sep 17 00:00:00 2001 From: Netrifier Date: Wed, 11 Mar 2026 20:08:28 +0530 Subject: [PATCH 1/2] fix: open link in browser if handler app fails Add openLink helper that retries opening the URL in a browser if the initial intent fails with ActivityNotFoundException. --- .../compose/settings/SettingsScreen.kt | 10 ++++------ .../droidify/ui/appDetail/AppDetailFragment.kt | 11 ++++------- .../utility/common/extension/Context.kt | 18 ++++++++++++++++-- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/src/main/kotlin/com/looker/droidify/compose/settings/SettingsScreen.kt b/app/src/main/kotlin/com/looker/droidify/compose/settings/SettingsScreen.kt index dca22d834..cfc01e8b1 100644 --- a/app/src/main/kotlin/com/looker/droidify/compose/settings/SettingsScreen.kt +++ b/app/src/main/kotlin/com/looker/droidify/compose/settings/SettingsScreen.kt @@ -19,7 +19,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.core.net.toUri @@ -42,6 +41,7 @@ import com.looker.droidify.datastore.model.LegacyInstallerComponent import com.looker.droidify.datastore.model.ProxyType import com.looker.droidify.datastore.model.Theme import com.looker.droidify.utility.common.SdkCheck +import com.looker.droidify.utility.common.extension.openLink import com.looker.droidify.utility.common.isIgnoreBatteryEnabled import com.looker.droidify.utility.common.requestBatteryFreedom import java.util.* @@ -114,8 +114,6 @@ fun SettingsScreen( } } - val uriHandler = LocalUriHandler.current - Scaffold( topBar = { TopAppBar( @@ -377,7 +375,7 @@ fun SettingsScreen( ActionSettingItem( title = stringResource(R.string.special_credits), description = FOXY_DROID_TITLE, - onClick = { uriHandler.openUri(FOXY_DROID_URL) }, + onClick = { context.openLink(FOXY_DROID_URL) }, ) } @@ -385,7 +383,7 @@ fun SettingsScreen( ActionSettingItem( title = DROID_IFY_TITLE, description = BuildConfig.VERSION_NAME, - onClick = { uriHandler.openUri(DROID_IFY_URL) }, + onClick = { context.openLink(DROID_IFY_URL) }, ) } } @@ -588,7 +586,7 @@ private fun Context.translateLocale(locale: Locale?): String { val capitalizedLanguage = language?.replaceFirstChar { it.uppercase(Locale.getDefault()) } val countrySuffix = if (country?.isNotEmpty() == true && country.compareTo( language.toString(), - ignoreCase = true + ignoreCase = true, ) != 0 ) { "($country)" diff --git a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt index e6b153c5e..448822d67 100644 --- a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt +++ b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt @@ -45,6 +45,7 @@ import com.looker.droidify.utility.common.extension.getLauncherActivities import com.looker.droidify.utility.common.extension.getMutatedIcon import com.looker.droidify.utility.common.extension.isFirstItemVisible import com.looker.droidify.utility.common.extension.isSystemApplication +import com.looker.droidify.utility.common.extension.openLink import com.looker.droidify.utility.common.extension.systemBarsPadding import com.looker.droidify.utility.common.extension.updateAsMutable import com.looker.droidify.utility.common.shareUrl @@ -246,7 +247,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { val canInstall = product != null && installed == null && compatible val canUpdate = product != null && compatible && product.canUpdate(installed?.installedItem) && - !preference.shouldIgnoreUpdate(product.versionCode) + !preference.shouldIgnoreUpdate(product.versionCode) val canUninstall = product != null && installed != null && !installed.isSystem val canLaunch = product != null && installed != null && installed.launcherActivities.isNotEmpty() @@ -476,7 +477,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { AppDetailAdapter.Action.SOURCE -> { val link = products[0].first.source - startActivity(Intent(Intent.ACTION_VIEW, link.toUri())) + requireContext().openLink(link) } } } @@ -486,11 +487,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { } override fun onCustomButtonClick(url: String) { - try { - startActivity(Intent(Intent.ACTION_VIEW, url.toUri())) - } catch (e: ActivityNotFoundException) { - e.printStackTrace() - } + requireContext().openLink(url) } private fun startLauncherActivity(name: String) { diff --git a/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt b/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt index a457d8506..5d9590e37 100644 --- a/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt +++ b/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt @@ -2,6 +2,7 @@ package com.looker.droidify.utility.common.extension import android.app.NotificationManager import android.app.job.JobScheduler +import android.content.ActivityNotFoundException import android.content.ClipData import android.content.ClipboardManager import android.content.Context @@ -39,9 +40,22 @@ fun Context.copyToClipboard(clip: String) { fun Context.openLink(url: String) { val intent = intent(Intent.ACTION_VIEW) { - setData(url.toUri()) + data = url.toUri() + } + try { + startActivity(intent) + } catch (_: ActivityNotFoundException) { + // If no app found try to force open in browser + intent.selector = intent(Intent.ACTION_VIEW) { + data = "https://".toUri() + addCategory(Intent.CATEGORY_BROWSABLE) + } + try { + startActivity(intent) + } catch (e: ActivityNotFoundException) { + e.printStackTrace() + } } - startActivity(intent) } val Context.corneredBackground: Drawable From f255ae468c597765e547a4513a30e989a009dd9a Mon Sep 17 00:00:00 2001 From: Netrifier Date: Thu, 12 Mar 2026 15:08:08 +0530 Subject: [PATCH 2/2] fix: add log message and use safer context --- .../com/looker/droidify/ui/appDetail/AppDetailFragment.kt | 4 ++-- .../com/looker/droidify/utility/common/extension/Context.kt | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt index 448822d67..d3466df2c 100644 --- a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt +++ b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt @@ -477,7 +477,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { AppDetailAdapter.Action.SOURCE -> { val link = products[0].first.source - requireContext().openLink(link) + context?.openLink(link) } } } @@ -487,7 +487,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { } override fun onCustomButtonClick(url: String) { - requireContext().openLink(url) + context?.openLink(url) } private fun startLauncherActivity(name: String) { diff --git a/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt b/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt index 5d9590e37..6e31493ff 100644 --- a/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt +++ b/app/src/main/kotlin/com/looker/droidify/utility/common/extension/Context.kt @@ -10,6 +10,7 @@ import android.content.Intent import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.os.PowerManager +import android.util.Log import android.view.inputmethod.InputMethodManager import androidx.annotation.AttrRes import androidx.annotation.DrawableRes @@ -18,6 +19,7 @@ import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import androidx.core.net.toUri import com.looker.droidify.R +import com.looker.droidify.utility.common.log inline val Context.clipboardManager: ClipboardManager? get() = getSystemService() @@ -45,6 +47,7 @@ fun Context.openLink(url: String) { try { startActivity(intent) } catch (_: ActivityNotFoundException) { + log("Failed to find dedicated app for $url, trying browser", "OpenLink", Log.WARN) // If no app found try to force open in browser intent.selector = intent(Intent.ACTION_VIEW) { data = "https://".toUri()