[Android] Show QrCode instead of links when no browser is installed
Nicolas Pomepuy
git at videolan.org
Mon Mar 28 15:16:56 UTC 2022
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Mon Mar 28 16:01:03 2022 +0200| [95bfc26c2e40ae30c7ac0685109eaca0207a82c5] | committer: Nicolas Pomepuy
Show QrCode instead of links when no browser is installed
> https://code.videolan.org/videolan/vlc-android/commit/95bfc26c2e40ae30c7ac0685109eaca0207a82c5
---
.../resources/src/main/res/values/strings.xml | 2 +
application/vlc-android/build.gradle | 1 +
.../org/videolan/vlc/gui/dialogs/LicenseDialog.kt | 5 +-
.../src/org/videolan/vlc/gui/helpers/UiTools.kt | 7 +-
.../src/org/videolan/vlc/util/UrlUtils.kt | 75 ++++++++++++++++++++++
5 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/application/resources/src/main/res/values/strings.xml b/application/resources/src/main/res/values/strings.xml
index 9afa2ff33..c49c2676d 100644
--- a/application/resources/src/main/res/values/strings.xml
+++ b/application/resources/src/main/res/values/strings.xml
@@ -924,5 +924,7 @@
<string name="always_fast_seek_summary">Seek is faster but may be less precise</string>
<string name="touch_only">Touch only feature</string>
<string name="touch_only_description">Switching to the mobile interface can only be done with a tactile screen or a mouse.\nPlease slide below to verify that this feature is safe to change.</string>
+ <string name="no_web_browser">No web browser installed</string>
+ <string name="no_web_browser_message">You can scan this on your smartphone.\nThe URL is %s</string>
</resources>
diff --git a/application/vlc-android/build.gradle b/application/vlc-android/build.gradle
index bfc80d8d1..4d272090e 100644
--- a/application/vlc-android/build.gradle
+++ b/application/vlc-android/build.gradle
@@ -193,6 +193,7 @@ dependencies {
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.ext.kotlinx_version"
implementation 'nl.dionsegijn:konfetti:1.2.2'
+ implementation 'com.google.zxing:core:3.4.0'
// Tests
androidTestImplementation "androidx.test.espresso:espresso-contrib:$rootProject.espressoVersion"
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/LicenseDialog.kt b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/LicenseDialog.kt
index 3c68c7e50..c1a23b899 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/LicenseDialog.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/LicenseDialog.kt
@@ -21,18 +21,17 @@
*/
package org.videolan.vlc.gui.dialogs
-import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.net.toUri
import androidx.core.os.bundleOf
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.videolan.vlc.databinding.DialogLicenseBinding
import org.videolan.vlc.gui.LibraryWithLicense
+import org.videolan.vlc.util.openLinkIfPossible
const val LICENSE_ITEM = "LICENSE_ITEM"
@@ -74,7 +73,7 @@ class LicenseDialog : VLCBottomSheetDialogFragment() {
binding = DialogLicenseBinding.inflate(layoutInflater, container, false)
binding.library = licenseItem
binding.licenseButton.setOnClickListener {
- if (licenseItem.licenseLink.isNotEmpty()) requireActivity().startActivity(Intent(Intent.ACTION_VIEW, licenseItem.licenseLink.toUri()))
+ if (licenseItem.licenseLink.isNotEmpty()) requireActivity().openLinkIfPossible(licenseItem.licenseLink)
}
return binding.root
}
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
index 616dea25b..648ee3e79 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
@@ -83,6 +83,7 @@ import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.media.getAll
import org.videolan.vlc.providers.medialibrary.MedialibraryProvider
import org.videolan.vlc.util.FileUtils
+import org.videolan.vlc.util.openLinkIfPossible
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
@@ -379,13 +380,13 @@ object UiTools {
AboutVersionDialog.newInstance().show(activity.supportFragmentManager, "AboutVersionDialog")
}
v.findViewById<View>(R.id.about_website_container).setOnClickListener {
- activity.startActivity(Intent(Intent.ACTION_VIEW, "https://www.videolan.org/vlc/".toUri()))
+ activity.openLinkIfPossible("https://www.videolan.org/vlc/")
}
v.findViewById<View>(R.id.about_forum_container).setOnClickListener {
- activity.startActivity(Intent(Intent.ACTION_VIEW, "https://forum.videolan.org/viewforum.php?f=35".toUri()))
+ activity.openLinkIfPossible("https://forum.videolan.org/viewforum.php?f=35")
}
v.findViewById<View>(R.id.about_sources_container).setOnClickListener {
- activity.startActivity(Intent(Intent.ACTION_VIEW, "https://code.videolan.org/videolan/vlc-android".toUri()))
+ activity.openLinkIfPossible("https://code.videolan.org/videolan/vlc-android")
}
v.findViewById<View>(R.id.about_authors_container).setOnClickListener {
diff --git a/application/vlc-android/src/org/videolan/vlc/util/UrlUtils.kt b/application/vlc-android/src/org/videolan/vlc/util/UrlUtils.kt
new file mode 100644
index 000000000..c494a2631
--- /dev/null
+++ b/application/vlc-android/src/org/videolan/vlc/util/UrlUtils.kt
@@ -0,0 +1,75 @@
+/*
+ * ************************************************************************
+ * UrlUtils.kt
+ * *************************************************************************
+ * Copyright © 2022 VLC authors and VideoLAN
+ * Author: Nicolas POMEPUY
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * **************************************************************************
+ *
+ *
+ */
+
+package org.videolan.vlc.util
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ResolveInfo
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.widget.ImageView
+import androidx.appcompat.app.AlertDialog
+import androidx.core.net.toUri
+import com.google.zxing.BarcodeFormat
+import com.google.zxing.qrcode.QRCodeWriter
+import org.videolan.vlc.R
+
+
+fun Context.openLinkIfPossible(url: String, size: Int = 512) {
+
+
+ try {
+
+
+ val intent = Intent(Intent.ACTION_VIEW, url.toUri())
+ val match: List<ResolveInfo> = packageManager.queryIntentActivities(intent, 0)
+
+ if (match.size == 1) {
+ val resolveActivity = intent.resolveActivity(packageManager)
+ if (resolveActivity == null || resolveActivity.packageName.startsWith("com.google.android.tv.frameworkpackagestubs")) throw IllegalStateException("No web browser found")
+ }
+ startActivity(intent)
+ } catch (e: Exception) {
+ val image = ImageView(this)
+
+ val bits = QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, size, size)
+ val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565).also {
+ for (x in 0 until size) {
+ for (y in 0 until size) {
+ it.setPixel(x, y, if (bits[x, y]) Color.BLACK else Color.WHITE)
+ }
+ }
+ }
+ image.setImageBitmap(bitmap)
+ AlertDialog.Builder(this)
+ .setTitle(getString(R.string.no_web_browser))
+ .setMessage(getString(R.string.no_web_browser_message, url))
+ .setView(image)
+ .setPositiveButton(R.string.ok) { _, _ ->
+
+ }
+ .show()
+ }
+}
\ No newline at end of file
More information about the Android
mailing list