Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions play-services-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,19 @@
</intent-filter>
</service>

<activity
android:name="org.microg.gms.mlkit.BarcodeScanningActivity"
android:exported="true"
android:process=":ui"
android:excludeFromRecents="true"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">
<intent-filter>
<action android:name="com.google.android.gms.mlkit.ACTION_SCAN_BARCODE" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<service android:name="org.microg.gms.DummyService">
<intent-filter>
<action android:name="com.google.android.contextmanager.service.ContextManagerService.START" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* SPDX-FileCopyrightText: 2025 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package org.microg.gms.mlkit

import android.Manifest.permission
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.R
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
import org.microg.gms.vision.barcode.QRCodeScannerView

private const val KEY_CALLING_APP_NAME = "extra_calling_app_name"
private const val KEY_BARCODE_RESULT = "extra_barcode_result"

class BarcodeScanningActivity : AppCompatActivity() {

private val clientPackageName: String?
get() = runCatching {
intent?.extras?.takeIf { it.containsKey(KEY_CALLING_APP_NAME) }?.getString(KEY_CALLING_APP_NAME)
}.getOrNull()

private val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
if (isGranted) {
startScanning()
} else {
showPermissionDialog(clientPackageName)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
finish()
return
}
setContentView(R.layout.activity_barcode_scanning)
findViewById<ImageView>(R.id.barcode_scanning_cancel).setOnClickListener {
finish()
}
if (clientPackageName != null) {
findViewById<TextView>(R.id.barcode_scanning_tips).text = String.format(getString(R.string.barcode_scanner_brand), clientPackageName)
}
if (ContextCompat.checkSelfPermission(this, permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissionLauncher.launch(permission.CAMERA)
} else {
startScanning()
}
}

private fun startScanning(){
lifecycleScope.launchWhenCreated {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val scannerView = findViewById<QRCodeScannerView>(R.id.scannerView)
scannerView.startScanner { result ->
if (result != null) {
val resultIntent = Intent().apply {
putExtra(KEY_BARCODE_RESULT, SafeParcelableSerializer.serializeToBytes(result))
}
setResult(RESULT_OK, resultIntent)
finish()
}
}
}
}
}

private fun showPermissionDialog(callingApp: String?) {
AlertDialog.Builder(this).apply {
setTitle(getString(R.string.camera_permission_dialog_title))
setMessage(String.format(getString(R.string.camera_permission_dialog_message), callingApp))
setPositiveButton(getString(R.string.camera_permission_dialog_button)){ dialog, _ ->
dialog.dismiss()
finish()
}
}.show()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<org.microg.gms.vision.barcode.QRCodeScannerView
android:id="@+id/scannerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<ImageView
android:id="@+id/barcode_scanning_cancel"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="start"
android:contentDescription="@android:string/cancel"
android:scaleType="centerCrop"
android:layout_margin="20dp"
android:src="@drawable/ic_close_btn" />

<TextView
android:id="@+id/barcode_scanning_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:textSize="16dp"
android:textColor="@android:color/darker_gray"
android:layout_gravity="bottom|center"/>

</FrameLayout>
4 changes: 4 additions & 0 deletions play-services-core/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ microG GmsCore 内置一套自由的 SafetyNet 实现,但是官方服务器要
<string name="auth_action_notification_content">你的 Google 账户需要额外设置。</string>
<string name="auth_action_activity_explanation">要能在这台设备上使用你的 Google 账户 %s 请完成下列步骤。</string>
<string name="auth_action_step_enable_lockscreen_description">你的 Google 账户受工作场所或教育机构管理。你的管理员决定设备在可以访问账户数据前需要设置安全屏幕锁。\n\n请设置一个密码、PIN或手势屏幕锁。</string>
<string name="barcode_scanner_brand">由 microG 代表“%1$s”扫描</string>
<string name="camera_permission_dialog_button">确定</string>
<string name="camera_permission_dialog_message">microG 服务需要访问设备的摄像头,才能为%1$s扫描二维码。\n\n若要启用该权限,请在“设置”中向 microG 服务授予相机权限。</string>
<string name="camera_permission_dialog_title">需要相机使用权限</string>
<string name="pref_vending_asset_delivery_summary">当使用 Play 资产传递的应用请求时下载额外的资产</string>
<string name="pref_vending_asset_delivery_category">Google Play 资产传递</string>
<string name="pref_vending_asset_delivery_switch">启用按需资产传递</string>
Expand Down
5 changes: 5 additions & 0 deletions play-services-core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,9 @@ Please set up a password, PIN, or pattern lock screen."</string>
<string name="games_delete_snapshot_dialog_ok">OK</string>
<string name="games_delete_snapshot_error">Deletion failed, please try again later</string>

<string name="barcode_scanner_brand">Scanned by microG on behalf of %1$s</string>
<string name="camera_permission_dialog_button">OK</string>
<string name="camera_permission_dialog_message">microG services needs to access your device\'s camera to scan a code for %1$s.\n\nTo enable, please grant camera permission to microG services in Settings.</string>
<string name="camera_permission_dialog_title">Camera permission required</string>

</resources>
4 changes: 4 additions & 0 deletions play-services-vision/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ dependencies {
implementation project(':play-services-base-core')
implementation "androidx.annotation:annotation:$annotationVersion"
implementation "com.google.zxing:core:3.5.2"
implementation "androidx.camera:camera-core:1.3.0"
implementation "androidx.camera:camera-camera2:1.3.0"
implementation "androidx.camera:camera-lifecycle:1.3.0"
implementation "androidx.camera:camera-view:1.3.0"
}

android {
Expand Down
4 changes: 4 additions & 0 deletions play-services-vision/core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature
android:name="android.hardware.camera"
android:required="false" />

<application>
</application>
Expand Down
Loading