Skip to content

Commit 4174162

Browse files
committed
update: qr code and scanner qr
1 parent 8cecaac commit 4174162

File tree

14 files changed

+322
-32
lines changed

14 files changed

+322
-32
lines changed

app/build.gradle.kts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ android {
1111

1212
defaultConfig {
1313
applicationId = ProjectSetting.PACKAGE_NAME
14-
minSdk = 21
14+
minSdk = 23
1515
targetSdk = 35
1616
versionCode = 1
1717
versionName = "1.0"
@@ -71,6 +71,9 @@ dependencies {
7171
implementation(libs.androidx.lifecycle.process)
7272
implementation(libs.androidx.lifecycle.reactivestreams.ktx)
7373

74+
implementation(libs.code.scanner)
75+
implementation(libs.zxing.android.embedded)
76+
7477
testImplementation(libs.androidx.core.testing)
7578
testImplementation (libs.androidx.lifecycle.runtime.testing)
7679

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools">
44

5+
<uses-feature android:name="android.hardware.camera" />
6+
<uses-feature android:name="android.hardware.camera.autofocus" />
7+
<uses-feature android:name="android.hardware.camera.flash" /> <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
8+
<uses-feature android:name="android.hardware.location.gps" />
9+
<uses-feature android:name="android.hardware.camera.any" />
10+
511
<uses-permission android:name="android.permission.INTERNET" />
612
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
713
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
14+
<uses-permission android:name="android.permission.CAMERA" />
15+
<uses-permission android:name="android.permission.FLASHLIGHT" />
816

917
<application
1018
android:name=".QomunalApp"
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.qomunal.opensource.androidresearch.common.base
2+
3+
import com.budiyev.android.codescanner.AutoFocusMode
4+
import com.budiyev.android.codescanner.CodeScanner
5+
import com.budiyev.android.codescanner.DecodeCallback
6+
import com.budiyev.android.codescanner.ErrorCallback
7+
import com.budiyev.android.codescanner.ScanMode
8+
import com.google.zxing.BarcodeFormat
9+
import com.google.zxing.Result
10+
import com.qomunal.opensource.androidresearch.common.ext.showToast
11+
import com.qomunal.opensource.androidresearch.databinding.ActivityQrScannerBinding
12+
13+
14+
/**
15+
* Created by faisalamircs on 24/11/2023
16+
* -----------------------------------------
17+
* Name : Muhammad Faisal Amir
18+
* E-mail : faisalamircs@gmail.com
19+
* Github : github.com/amirisback
20+
* -----------------------------------------
21+
*/
22+
23+
24+
abstract class QrScannerActivity : BaseActivity<ActivityQrScannerBinding>() {
25+
26+
abstract fun doOnSuccessScan(result: Result)
27+
28+
private val codeScanner: CodeScanner by lazy {
29+
CodeScanner(this, binding.scannerView)
30+
}
31+
32+
override fun setupViewBinding(): ActivityQrScannerBinding {
33+
return ActivityQrScannerBinding.inflate(layoutInflater)
34+
}
35+
36+
override fun initUI() {
37+
// Parameters (default values)
38+
codeScanner.camera = CodeScanner.CAMERA_BACK // or CAMERA_FRONT or specific camera id
39+
codeScanner.formats = listOf(BarcodeFormat.QR_CODE)
40+
codeScanner.autoFocusMode = AutoFocusMode.SAFE // or CONTINUOUS
41+
codeScanner.scanMode = ScanMode.SINGLE // or CONTINUOUS or PREVIEW
42+
codeScanner.isAutoFocusEnabled = true // Whether to enable auto focus or not
43+
codeScanner.isFlashEnabled = false // Whether to enable flash or not
44+
45+
// Callbacks
46+
codeScanner.decodeCallback = DecodeCallback {
47+
runOnUiThread {
48+
doOnSuccessScan(it)
49+
}
50+
}
51+
52+
codeScanner.errorCallback = ErrorCallback { // or ErrorCallback.SUPPRESS
53+
runOnUiThread {
54+
showToast("Camera initialization error: ${it.message}")
55+
}
56+
}
57+
58+
binding.scannerView.setOnClickListener {
59+
codeScanner.startPreview()
60+
}
61+
62+
binding.apply {
63+
btnBack.setOnClickListener {
64+
onBackPressedDispatcher.onBackPressed()
65+
}
66+
}
67+
}
68+
69+
override fun onResume() {
70+
super.onResume()
71+
codeScanner.startPreview()
72+
}
73+
74+
override fun onPause() {
75+
codeScanner.releaseResources()
76+
super.onPause()
77+
}
78+
79+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.qomunal.opensource.androidresearch.common.ext
2+
3+
import android.widget.ImageView
4+
import com.google.zxing.BarcodeFormat
5+
import com.journeyapps.barcodescanner.BarcodeEncoder
6+
7+
/**
8+
* Created by faisalamircs on 09/06/2025
9+
* -----------------------------------------
10+
* Name : Muhammad Faisal Amir
11+
* E-mail : faisalamircs@gmail.com
12+
* Github : github.com/amirisback
13+
* -----------------------------------------
14+
*/
15+
16+
17+
fun ImageView.createQRCode(url: String?) {
18+
url?.let {
19+
this.setImageBitmap(
20+
BarcodeEncoder().encodeBitmap(
21+
it,
22+
BarcodeFormat.QR_CODE,
23+
400,
24+
400
25+
)
26+
)
27+
}
28+
}
Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.qomunal.opensource.androidresearch.ui.detail
22

3-
import android.os.Bundle
43
import androidx.activity.viewModels
5-
import com.qomunal.opensource.androidresearch.common.base.BaseActivity
6-
import com.qomunal.opensource.androidresearch.databinding.ActivityDetailBinding
4+
import com.google.zxing.Result
5+
import com.qomunal.opensource.androidresearch.common.base.QrScannerActivity
6+
import com.qomunal.opensource.androidresearch.common.ext.showToast
77

88
/**
99
* Created by faisalamircs on 13/01/2024
@@ -15,32 +15,21 @@ import com.qomunal.opensource.androidresearch.databinding.ActivityDetailBinding
1515
*/
1616

1717

18-
class DetailActivity : BaseActivity<ActivityDetailBinding>() {
18+
class DetailActivity : QrScannerActivity() {
1919

20-
private val viewModel: DetailViewModel by viewModels()
21-
private val reouter: DetailRouter by lazy {
22-
DetailRouter(this)
23-
}
24-
25-
override fun setupViewBinding(): ActivityDetailBinding {
26-
return ActivityDetailBinding.inflate(layoutInflater)
20+
companion object {
21+
const val EXTRA_EVENT = "EXTRA_EVENT"
2722
}
2823

29-
override fun onCreate(savedInstanceState: Bundle?) {
30-
super.onCreate(savedInstanceState)
31-
}
3224

33-
override fun initUI() {
34-
binding.apply {
25+
private val viewModel: DetailViewModel by viewModels()
3526

36-
}
27+
override fun doOnSuccessScan(result: Result) {
28+
showToast(result.text)
3729
}
3830

3931
override fun initObserver() {
40-
viewModel.apply {
4132

42-
}
4333
}
4434

45-
4635
}

app/src/main/java/com/qomunal/opensource/androidresearch/ui/main/MainActivity.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.qomunal.opensource.androidresearch.ui.main
22

3+
import android.content.Intent
34
import android.os.Bundle
45
import androidx.activity.viewModels
56
import com.qomunal.opensource.androidresearch.common.base.BaseActivity
6-
import com.qomunal.opensource.androidresearch.common.ext.showToast
7+
import com.qomunal.opensource.androidresearch.common.ext.createQRCode
78
import com.qomunal.opensource.androidresearch.databinding.ActivityMainBinding
9+
import com.qomunal.opensource.androidresearch.ui.detail.DetailActivity
810

911
class MainActivity : BaseActivity<ActivityMainBinding>() {
1012

@@ -23,9 +25,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
2325

2426
override fun initUI() {
2527
binding.apply {
26-
btnTest.setOnClickListener {
27-
showToast("Yes u click on me")
28+
btnScanner.setOnClickListener {
29+
startActivity(Intent(this@MainActivity, DetailActivity::class.java))
2830
}
31+
32+
ivQrQode.createQRCode("Amir")
2933
}
3034
}
3135

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="20dp"
3+
android:height="17dp"
4+
android:viewportWidth="20"
5+
android:viewportHeight="17">
6+
<path
7+
android:pathData="M20,7.285H4.158L9.907,1.536L8.371,0L0,8.371L8.371,16.742L9.907,15.206L4.158,9.457H20V7.285Z"
8+
android:fillColor="#0D0D0D"/>
9+
<path
10+
android:pathData="M20,7.285H4.158L9.907,1.536L8.371,0L0,8.371L8.371,16.742L9.907,15.206L4.158,9.457H20V7.285Z"
11+
android:fillColor="#000000"
12+
android:fillAlpha="0.2"/>
13+
</vector>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="296dp"
3+
android:height="296dp"
4+
android:viewportWidth="296"
5+
android:viewportHeight="296">
6+
<path
7+
android:fillColor="#FF000000"
8+
android:pathData="M32,236v-28h56v56H32V236L32,236zM80,236v-20H40v40h40V236L80,236zM48,236v-12h24v24H48V236L48,236zM104,260v-4h-8v-16h8v-24h8v-8H96v-8H64v-8h8v-8H56v16h-8v-8H32v-8h16v-16h-8v8h-8v-16h16v8h8v8h8v-8h8v8h16v-8h-8v-8H56v-8h24v-8H56v-8h-8v8H32v-24h8v8h48v-8h-8v-8H64v8h-8v-8H40V96h16v16h8v-8h16v-8h8v8h-8v8h8v8h8v-16h8v-8h-8V72h16v8h8v8h-8v8h8v48h-16v-8h-8v8h-8v8h-8v8h8v8h8v8h16v-8h-8v-8h-8v-8h16v16h8v-16h8v16h8v-24h8v-8h8v8h-8v8h8v8h24v-8h-8v-8h-8v-16h-8v-8h8v-8h8v-8h-8v-8h-8v16h-8v-8h-8v8h-8v-8h8v-8h-8V72h-8v-8h8v8h8V40h8v16h16v-8h-8V32h16v8h-8v8h16v-8h8v-8h16v24h-16v-8h-8v16h8v24h8v-8h8v40h16v-8h-8V96h16v24h16v-8h-8V96h8v16h8v-8h16v16h-8v-8h-8v8h-8v24h8v8h-8v8h-16v8h-8v8h-16v-8h-8v-8h-8v16h8v8h24v8h16v-8h-8v-8h8v-8h8v8h8v8h8v-16h-8v-8h16v24h-8v16h8v16h-8v24h8v8h-24v16h-24v-8h16v-8h-16v-16h-8v16h-8v8h8v8h-16v-24h-8v16h-8v-8h-8v-32h8v24h8v-24h8v-16h-8v-8h-8v-8h8v-8h-8v-8h-8v32h8v8h-16v16h-8v16h8v8h-8v8h16v8h-16v-8h-8v-8h-8v16h-32V260L104,260zM128,248v-8h8v-24h-16v8h8v8h-16v8h-8v8h8v8h16V248L128,248zM240,240v-8h8v-16h8v-8h-8v-24h-8v24h8v8h-8v8h-8v24h8V240L240,240zM200,236v-4h-8v8h8V236L200,236zM152,220v-4h-8v8h8V220L152,220zM224,212v-12h-24v24h24V212L224,212zM208,212v-4h8v8h-8V212L208,212zM144,204v-4h16v-8h-16v-8h-8v8h8v8h-16v-8h-8v8h-8v-8h-8v-8h-8v-8h-8v8h-8v8h8v-8h8v8h8v8h8v8h32V204L144,204zM120,180v-4h-8v8h8V180L120,180zM160,176v-8h-16v8h8v8h8V176L160,176zM208,164v-4h-8v8h8V164L208,164zM224,156v-4h8v-24h-8v8h-8v8h-8v-8h-16v-8h-8v-8h8V96h-8v-8h-8v-8h-8v8h-8V64h8v8h8v-8h-8v-8h-8v8h-8v24h8v8h8v-8h8v24h-8v8h-8v8h8v16h8v-8h16v8h8v8h16v8h8V156L224,156zM216,148v-4h8v8h-8V148L216,148zM88,140v-4h8v-8h-8v8h-8v8h8V140L88,140zM112,124v-4h-8v8h8V124L112,124zM112,84v-4h-8v8h8V84L112,84zM144,80v-8h-8v16h8V80L144,80zM192,44v-4h-8v8h8V44L192,44zM256,260v-4h8v8h-8V260L256,260zM256,144v-8h-8v-8h8v8h8v16h-8V144L256,144zM32,60V32h56v56H32V60L32,60zM80,60V40H40v40h40V60L80,60zM48,60V48h24v24H48V60L48,60zM208,60V32h56v56h-56V60L208,60zM256,60V40h-40v40h40V60L256,60zM224,60V48h24v24h-24V60L224,60zM96,60v-4h8v8h-8V60L96,60zM112,52v-4h-8V32h8v8h8v-8h8v8h-8v16h-8V52L112,52z"/>
9+
</vector>
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
xmlns:tools="http://schemas.android.com/tools"
45
android:layout_width="match_parent"
56
android:layout_height="match_parent">
67

8+
<ImageView
9+
android:id="@+id/iv_qr_qode"
10+
android:layout_width="match_parent"
11+
android:layout_height="350dp"
12+
app:layout_constraintEnd_toEndOf="parent"
13+
app:layout_constraintStart_toStartOf="parent"
14+
app:layout_constraintTop_toTopOf="parent"
15+
tools:src="@drawable/ic_dummy_qr_code" />
16+
717
<Button
8-
android:id="@+id/btn_test"
9-
android:layout_width="wrap_content"
18+
android:id="@+id/btn_scanner"
19+
android:layout_width="match_parent"
1020
android:layout_height="wrap_content"
11-
android:text="Click On Me"
21+
android:layout_margin="16dp"
22+
android:text="Scan QR Code"
1223
app:layout_constraintBottom_toBottomOf="parent"
1324
app:layout_constraintEnd_toEndOf="parent"
14-
app:layout_constraintStart_toStartOf="parent"
15-
app:layout_constraintTop_toTopOf="parent" />
25+
app:layout_constraintStart_toStartOf="parent" />
1626

1727
</androidx.constraintlayout.widget.ConstraintLayout>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent">
6+
7+
<androidx.constraintlayout.widget.ConstraintLayout
8+
android:id="@+id/tab_bar"
9+
android:layout_width="match_parent"
10+
android:layout_height="@dimen/dimen_64dp"
11+
app:layout_constraintEnd_toEndOf="parent"
12+
app:layout_constraintStart_toStartOf="parent"
13+
app:layout_constraintTop_toTopOf="parent">
14+
15+
<ImageButton
16+
android:id="@+id/btn_back"
17+
android:layout_width="@dimen/dimen_24dp"
18+
android:layout_height="@dimen/dimen_24dp"
19+
android:layout_marginStart="@dimen/dimen_16dp"
20+
android:background="@android:color/transparent"
21+
android:src="@drawable/ic_back"
22+
app:layout_constraintBottom_toBottomOf="parent"
23+
app:layout_constraintStart_toStartOf="parent"
24+
app:layout_constraintTop_toTopOf="parent" />
25+
26+
<TextView
27+
android:id="@+id/tv_title"
28+
android:layout_width="wrap_content"
29+
android:layout_height="wrap_content"
30+
android:text=""
31+
android:textSize="@dimen/ts16"
32+
android:textStyle="bold"
33+
app:layout_constraintBottom_toBottomOf="parent"
34+
app:layout_constraintEnd_toEndOf="parent"
35+
app:layout_constraintStart_toStartOf="parent"
36+
app:layout_constraintTop_toTopOf="parent" />
37+
</androidx.constraintlayout.widget.ConstraintLayout>
38+
39+
<androidx.constraintlayout.widget.ConstraintLayout
40+
android:layout_width="@dimen/dimen_0dp"
41+
android:layout_height="@dimen/dimen_0dp"
42+
app:layout_constraintBottom_toBottomOf="parent"
43+
app:layout_constraintEnd_toEndOf="parent"
44+
app:layout_constraintStart_toStartOf="parent"
45+
app:layout_constraintTop_toBottomOf="@id/tab_bar">
46+
47+
<FrameLayout
48+
android:layout_width="match_parent"
49+
android:layout_height="match_parent">
50+
51+
<com.budiyev.android.codescanner.CodeScannerView
52+
android:id="@+id/scanner_view"
53+
android:layout_width="match_parent"
54+
android:layout_height="match_parent"
55+
app:autoFocusButtonColor="@android:color/white"
56+
app:autoFocusButtonVisible="true"
57+
app:flashButtonColor="@android:color/white"
58+
app:flashButtonVisible="true"
59+
app:frameAspectRatioHeight="1"
60+
app:frameAspectRatioWidth="1"
61+
app:frameColor="@android:color/white"
62+
app:frameCornersRadius="@dimen/dimen_0dp"
63+
app:frameCornersSize="50dp"
64+
app:frameSize="0.75"
65+
app:frameThickness="@dimen/dimen_2dp"
66+
app:frameVerticalBias="0.5"
67+
app:maskColor="#77000000" />
68+
</FrameLayout>
69+
70+
</androidx.constraintlayout.widget.ConstraintLayout>
71+
72+
</androidx.constraintlayout.widget.ConstraintLayout>

0 commit comments

Comments
 (0)