1+ /* *
2+ * SPDX-FileCopyrightText: 2025 microG Project Team
3+ * SPDX-License-Identifier: Apache-2.0
4+ */
5+
6+ package org.microg.gms.mlkit
7+
8+ import android.Manifest.permission
9+ import android.content.Intent
10+ import android.content.pm.PackageManager
11+ import android.os.Build
12+ import android.os.Bundle
13+ import android.widget.ImageView
14+ import android.widget.TextView
15+ import androidx.activity.result.contract.ActivityResultContracts
16+ import androidx.appcompat.app.AlertDialog
17+ import androidx.appcompat.app.AppCompatActivity
18+ import androidx.core.content.ContextCompat
19+ import androidx.lifecycle.lifecycleScope
20+ import com.google.android.gms.R
21+ import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
22+ import org.microg.gms.vision.barcode.QRCodeScannerView
23+
24+ private const val KEY_CALLING_APP_NAME = " extra_calling_app_name"
25+ private const val KEY_BARCODE_RESULT = " extra_barcode_result"
26+
27+ class BarcodeScanningActivity : AppCompatActivity () {
28+
29+ private val clientPackageName: String?
30+ get() = runCatching {
31+ intent?.extras?.takeIf { it.containsKey(KEY_CALLING_APP_NAME ) }?.getString(KEY_CALLING_APP_NAME )
32+ }.getOrNull()
33+
34+ private val requestPermissionLauncher =
35+ registerForActivityResult(ActivityResultContracts .RequestPermission ()) { isGranted: Boolean ->
36+ if (isGranted) {
37+ startScanning()
38+ } else {
39+ showPermissionDialog(clientPackageName)
40+ }
41+ }
42+
43+ override fun onCreate (savedInstanceState : Bundle ? ) {
44+ super .onCreate(savedInstanceState)
45+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .LOLLIPOP ) {
46+ finish()
47+ return
48+ }
49+ setContentView(R .layout.activity_barcode_scanning)
50+ findViewById<ImageView >(R .id.barcode_scanning_cancel).setOnClickListener {
51+ finish()
52+ }
53+ if (clientPackageName != null ) {
54+ findViewById<TextView >(R .id.barcode_scanning_tips).text = String .format(getString(R .string.barcode_scanner_brand), clientPackageName)
55+ }
56+ if (ContextCompat .checkSelfPermission(this , permission.CAMERA ) != PackageManager .PERMISSION_GRANTED ) {
57+ requestPermissionLauncher.launch(permission.CAMERA )
58+ } else {
59+ startScanning()
60+ }
61+ }
62+
63+ private fun startScanning (){
64+ lifecycleScope.launchWhenCreated {
65+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
66+ val scannerView = findViewById<QRCodeScannerView >(R .id.scannerView)
67+ scannerView.startScanner { result ->
68+ if (result != null ) {
69+ val resultIntent = Intent ().apply {
70+ putExtra(KEY_BARCODE_RESULT , SafeParcelableSerializer .serializeToBytes(result))
71+ }
72+ setResult(RESULT_OK , resultIntent)
73+ finish()
74+ }
75+ }
76+ }
77+ }
78+ }
79+
80+ private fun showPermissionDialog (callingApp : String? ) {
81+ AlertDialog .Builder (this ).apply {
82+ setTitle(getString(R .string.camera_permission_dialog_title))
83+ setMessage(String .format(getString(R .string.camera_permission_dialog_message), callingApp))
84+ setPositiveButton(getString(R .string.camera_permission_dialog_button)){ dialog, _ ->
85+ dialog.dismiss()
86+ finish()
87+ }
88+ }.show()
89+ }
90+
91+ }
0 commit comments