diff --git a/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt b/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt
index dfb54058b..13a868871 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt
@@ -88,6 +88,7 @@ import app.grapheneos.camera.ui.CustomGrid
import app.grapheneos.camera.ui.QROverlay
import app.grapheneos.camera.ui.QRToggle
import app.grapheneos.camera.ui.SettingsDialog
+import app.grapheneos.camera.ui.dialog.showActionableDialog
import app.grapheneos.camera.ui.seekbar.ExposureBar
import app.grapheneos.camera.ui.seekbar.ZoomBar
import app.grapheneos.camera.util.CameraControl
@@ -1126,6 +1127,10 @@ open class MainActivity : AppCompatActivity(),
isQRDialogShowing = true
+ if (showActionableDialog(this, rawText) { isQRDialogShowing = false }) {
+ return
+ }
+
val hString = bytesToHex(
rawText.toByteArray(StandardCharsets.UTF_8)
)
diff --git a/app/src/main/java/app/grapheneos/camera/ui/dialog/ActionableQrDialog.kt b/app/src/main/java/app/grapheneos/camera/ui/dialog/ActionableQrDialog.kt
new file mode 100644
index 000000000..75c81404e
--- /dev/null
+++ b/app/src/main/java/app/grapheneos/camera/ui/dialog/ActionableQrDialog.kt
@@ -0,0 +1,86 @@
+package app.grapheneos.camera.ui.dialog
+
+import android.app.Activity
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AlertDialog
+import app.grapheneos.camera.R
+import app.grapheneos.camera.qr.data.GEO
+import app.grapheneos.camera.qr.data.Mail
+import app.grapheneos.camera.qr.data.MeCard
+import app.grapheneos.camera.qr.data.Phone
+import app.grapheneos.camera.qr.data.SMS
+import app.grapheneos.camera.qr.data.VCard
+import app.grapheneos.camera.qr.parser.parseGeo
+import app.grapheneos.camera.qr.parser.parseMail
+import app.grapheneos.camera.qr.parser.parseMeCard
+import app.grapheneos.camera.qr.parser.parsePhoneOrFacetime
+import app.grapheneos.camera.qr.parser.parseSMS
+import app.grapheneos.camera.qr.parser.parseVCard
+
+private data class DialogContent(
+ @StringRes val title: Int,
+ val message: String,
+ @StringRes val action: Int
+)
+
+fun showActionableDialog(activity: Activity, rawContent: String, onDismiss: () -> Unit): Boolean {
+
+ val card = parsePhoneOrFacetime(rawContent)
+ ?: parseSMS(rawContent)
+ ?: parseGeo(rawContent)
+ ?: parseMeCard(rawContent)
+ ?: parseMail(rawContent)
+ ?: parseVCard(rawContent)
+ ?: return false
+
+ val (title, message, action) = when (card) {
+ is GEO -> DialogContent(
+ R.string.address,
+ activity.getString(R.string.address_message, card.long, card.lat),
+ R.string.open_in_maps
+ )
+
+ is MeCard -> DialogContent(
+ R.string.contact_card_me_card,
+ activity.getString(R.string.mecard_message),
+ R.string.add_to_contacts
+ )
+
+ is Phone -> DialogContent(
+ R.string.phone,
+ activity.getString(R.string.call_message, "${card.number}"),
+ R.string.call
+ )
+
+ is SMS -> DialogContent(
+ R.string.message,
+ activity.getString(R.string.sms_message, card.number),
+ R.string.message
+ )
+
+ is Mail -> DialogContent(
+ R.string.mail,
+ activity.getString(R.string.mail_message, card.mailTo.to),
+ R.string.mail,
+ )
+
+ is VCard -> DialogContent(
+ R.string.contact_card_vcard,
+ activity.getString(R.string.vcard_message),
+ R.string.add_to_contacts
+ )
+ }
+
+ activity.runOnUiThread {
+ AlertDialog.Builder(activity)
+ .setTitle(title)
+ .setMessage(message)
+ .setOnDismissListener { onDismiss() }
+ .setNegativeButton(android.R.string.cancel, null)
+ .setPositiveButton(action) { _, _ ->
+ activity.startActivity(card.toActionIntent(activity))
+ }.show()
+ }
+
+ return true
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 113a06ba3..7b4ea7b24 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -184,4 +184,23 @@
Use ZSL in Latency mode
Uses Zero Shutter Lag (ZSL) in Latency mode for faster capture. Certain devices may have a buggy implementation for this.
+
+ Address
+ Contact Card (MeCard)
+ Contact Card (vCard)
+ Phone
+ Message
+ Email
+
+ Navigate
+ Call
+ Add to contacts
+
+ Do you want to navigate to longitude %s and latitude %s?
+ Do you want to save this contact info?
+ Do you want to import this contact info?
+ Do you want to call %s?
+ Do you want to chat with %s?
+ Do you want to send email to %s?
+