From 29dbc202d88cec9f8440e707dca568b95c73108b Mon Sep 17 00:00:00 2001 From: johan12345 Date: Thu, 15 May 2025 22:53:19 +0200 Subject: [PATCH] Rework openUrl function - use preferBrowser only when needed (when opening charger URLs, which might otherwise open in EVMap itself) - make preferBrowser work even if the default browser does not support Custom Tabs #313 Cherry-picked from 17efe71 --- app/src/main/AndroidManifest.xml | 4 ++ .../java/net/vonforst/evmap/MapsActivity.kt | 47 ++++++++++++++++--- .../vonforst/evmap/fragment/MapFragment.kt | 13 +++-- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1159eafd..8c08b5b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -24,6 +24,10 @@ + + + + diff --git a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt index 7ed3dc59..dfd6ad4f 100644 --- a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt +++ b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt @@ -3,6 +3,8 @@ package net.vonforst.evmap import android.app.PendingIntent import android.content.ActivityNotFoundException import android.content.Intent +import android.content.pm.PackageManager +import android.content.pm.ResolveInfo import android.net.Uri import android.os.Build import android.os.Bundle @@ -11,7 +13,6 @@ import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.browser.customtabs.CustomTabColorSchemeParams -import androidx.browser.customtabs.CustomTabsClient import androidx.browser.customtabs.CustomTabsIntent import androidx.core.content.ContextCompat import androidx.core.splashscreen.SplashScreen @@ -268,7 +269,6 @@ class MapsActivity : AppCompatActivity(), } fun openUrl(url: String, rootView: View, preferBrowser: Boolean = true) { - val pkg = CustomTabsClient.getPackageName(this, null) val intent = CustomTabsIntent.Builder() .setDefaultColorSchemeParams( CustomTabColorSchemeParams.Builder() @@ -276,13 +276,46 @@ class MapsActivity : AppCompatActivity(), .build() ) .build() - pkg?.let { - // prefer to open URL in custom tab, even if native app - // available (such as EVMap itself) - if (preferBrowser) intent.intent.setPackage(pkg) + + val uri = Uri.parse(url) + val viewIntent = Intent(Intent.ACTION_VIEW, uri) + if (preferBrowser) { + // EVMap may be set as default app for this link, but we want to open it in a browser + // try to find default web browser + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://")) + val resolveInfo = + packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY) + val pkg = resolveInfo?.activityInfo?.packageName.takeIf { it != "android" } + if (pkg == null) { + // There is no default browser, fall back to app chooser + val chooserIntent = Intent.createChooser(viewIntent, null).apply { + putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, arrayOf(componentName)) + } + val targets: List = packageManager.queryIntentActivities( + viewIntent, + PackageManager.MATCH_DEFAULT_ONLY + ) + + // add missing browsers (if EVMap is already set as default, Android might not find other browsers with the specific intent) + val browsers = packageManager.queryIntentActivities( + browserIntent, + PackageManager.MATCH_DEFAULT_ONLY + ) + val extraIntents = browsers.filter { browser -> + targets.find { it.activityInfo.packageName == browser.activityInfo.packageName } == null + }.map { browser -> + Intent(Intent.ACTION_VIEW, uri).apply { + setPackage(browser.activityInfo.packageName) + } + } + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toTypedArray()) + startActivity(chooserIntent) + return + } + intent.intent.setPackage(pkg) } try { - intent.launchUrl(this, Uri.parse(url)) + intent.launchUrl(this, uri) } catch (e: ActivityNotFoundException) { Snackbar.make( rootView, diff --git a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt index f52371cd..86704300 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -438,7 +438,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MenuProvider { binding.detailView.sourceButton.setOnClickListener { val charger = vm.charger.value?.data if (charger != null) { - (activity as? MapsActivity)?.openUrl(charger.url, binding.root) + (activity as? MapsActivity)?.openUrl(charger.url, binding.root, true) } } binding.detailView.btnChargeprice.setOnClickListener { @@ -453,8 +453,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MenuProvider { } else { (activity as? MapsActivity)?.openUrl( ChargepriceApi.getPoiUrl(charger), - binding.root, - false + binding.root ) } } @@ -508,7 +507,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MenuProvider { R.id.menu_edit -> { val charger = vm.charger.value?.data if (charger?.editUrl != null) { - (activity as? MapsActivity)?.openUrl(charger.editUrl, binding.root) + (activity as? MapsActivity)?.openUrl(charger.editUrl, binding.root, true) if (vm.apiId.value == "goingelectric") { // instructions specific to GoingElectric Toast.makeText( @@ -927,7 +926,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MenuProvider { (activity as? MapsActivity)?.showLocation(charger, binding.root) } R.drawable.ic_fault_report -> { - (activity as? MapsActivity)?.openUrl(charger.url, binding.root) + (activity as? MapsActivity)?.openUrl( + charger.url, + binding.root, + true + ) } R.drawable.ic_payment -> {