diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 585d0a843..38fb8c122 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,10 @@ + + + + diff --git a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt index 0b63dd14b..c97c12895 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 @@ -271,8 +272,7 @@ class MapsActivity : AppCompatActivity(), } } - fun openUrl(url: String, preferBrowser: Boolean = true) { - val pkg = CustomTabsClient.getPackageName(this, null) + fun openUrl(url: String, preferBrowser: Boolean = false) { val intent = CustomTabsIntent.Builder() .setDefaultColorSchemeParams( CustomTabColorSchemeParams.Builder() @@ -280,13 +280,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) { val cb = fragmentCallback ?: return Snackbar.make( 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 4bf408a5f..83a4c61c4 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -407,7 +407,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac binding.detailView.sourceButton.setOnClickListener { val charger = vm.charger.value?.data if (charger != null) { - (activity as? MapsActivity)?.openUrl(charger.url) + (activity as? MapsActivity)?.openUrl(charger.url, true) } } binding.detailView.btnChargeprice.setOnClickListener { @@ -420,7 +420,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac extras ) } else { - (activity as? MapsActivity)?.openUrl(ChargepriceApi.getPoiUrl(charger), false) + (activity as? MapsActivity)?.openUrl(ChargepriceApi.getPoiUrl(charger)) } } binding.detailView.btnChargerWebsite.setOnClickListener { @@ -473,7 +473,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac R.id.menu_edit -> { val charger = vm.charger.value?.data if (charger?.editUrl != null) { - (activity as? MapsActivity)?.openUrl(charger.editUrl) + (activity as? MapsActivity)?.openUrl(charger.editUrl, true) if (vm.apiId.value == "goingelectric") { // instructions specific to GoingElectric Toast.makeText( @@ -827,7 +827,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac (activity as? MapsActivity)?.showLocation(charger) } R.drawable.ic_fault_report -> { - (activity as? MapsActivity)?.openUrl(charger.url) + (activity as? MapsActivity)?.openUrl(charger.url, true) } R.drawable.ic_payment -> {