Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit ded7688

Browse files
author
Mateusz Maziec
committed
Merge branch 'release/1.0.2'
2 parents 15d7044 + 3ddcff2 commit ded7688

File tree

12 files changed

+283
-86
lines changed

12 files changed

+283
-86
lines changed

app/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ dependencies {
3030
testImplementation 'junit:junit:4.12'
3131
androidTestImplementation 'com.android.support.test:runner:1.0.1'
3232
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
33+
34+
implementation project(path: ':scanner')
3335
}

app/src/main/AndroidManifest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.bobekos.bobek.simplebarcodescanner">
44

5+
<uses-permission android:name="android.permission.CAMERA"/>
6+
57
<application
68
android:allowBackup="true"
79
android:icon="@mipmap/ic_launcher"
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,42 @@
11
package com.bobekos.bobek.simplebarcodescanner
22

3-
import android.support.v7.app.AppCompatActivity
43
import android.os.Bundle
4+
import android.support.v7.app.AppCompatActivity
5+
import android.widget.Toast
6+
import com.google.android.gms.vision.barcode.Barcode
7+
import io.reactivex.android.schedulers.AndroidSchedulers
8+
import io.reactivex.disposables.Disposable
9+
import kotlinx.android.synthetic.main.activity_main.*
510

611
class MainActivity : AppCompatActivity() {
712

13+
private var disposable: Disposable? = null
14+
815
override fun onCreate(savedInstanceState: Bundle?) {
916
super.onCreate(savedInstanceState)
1017
setContentView(R.layout.activity_main)
1118
}
12-
}
19+
20+
override fun onStart() {
21+
super.onStart()
22+
23+
disposable = barcodeView
24+
.setBarcodeFormats(Barcode.QR_CODE)
25+
.drawOverlay()
26+
.getObservable()
27+
.observeOn(AndroidSchedulers.mainThread())
28+
.subscribe(
29+
{
30+
Toast.makeText(this@MainActivity, it.displayValue, Toast.LENGTH_SHORT).show()
31+
},
32+
{
33+
Toast.makeText(this@MainActivity, it.message, Toast.LENGTH_LONG).show()
34+
})
35+
}
36+
37+
override fun onStop() {
38+
super.onStop()
39+
40+
disposable?.dispose()
41+
}
42+
}

app/src/main/res/layout/activity_main.xml

+11-9
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@
55
xmlns:tools="http://schemas.android.com/tools"
66
android:layout_width="match_parent"
77
android:layout_height="match_parent"
8-
tools:context=".MainActivity">
8+
tools:context=".MainActivity"
9+
android:id="@+id/root">
910

10-
<TextView
11-
android:layout_width="wrap_content"
12-
android:layout_height="wrap_content"
13-
android:text="Hello World!"
14-
app:layout_constraintBottom_toBottomOf="parent"
15-
app:layout_constraintLeft_toLeftOf="parent"
16-
app:layout_constraintRight_toRightOf="parent"
17-
app:layout_constraintTop_toTopOf="parent"/>
11+
<com.bobekos.bobek.scanner.BarcodeView
12+
android:id="@+id/barcodeView"
13+
android:layout_width="match_parent"
14+
android:layout_height="match_parent"/>
15+
16+
<FrameLayout
17+
android:id="@+id/framelayout"
18+
android:layout_width="match_parent"
19+
android:layout_height="match_parent" />
1820

1921
</android.support.constraint.ConstraintLayout>

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22

33
buildscript {
4-
ext.kotlin_version = '1.2.30'
4+
ext.kotlin_version = '1.2.31'
55
repositories {
66
google()
77
jcenter()
88
mavenCentral()
99
}
1010
dependencies {
11-
classpath 'com.android.tools.build:gradle:3.2.0-alpha06'
11+
classpath 'com.android.tools.build:gradle:3.2.0-alpha07'
1212
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1313
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
1414

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.bobekos.bobek.scanner
2+
3+
import android.graphics.Rect
4+
5+
6+
interface BarcodeOverlay {
7+
8+
fun onUpdate(posRect: Rect)
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.bobekos.bobek.scanner
2+
3+
import android.content.Context
4+
import android.graphics.Canvas
5+
import android.graphics.Color
6+
import android.graphics.Paint
7+
import android.graphics.Rect
8+
import android.util.AttributeSet
9+
import android.util.TypedValue
10+
import android.view.View
11+
12+
13+
class BarcodeRectOverlay : View, BarcodeOverlay {
14+
15+
constructor(context: Context?) : super(context)
16+
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
17+
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
18+
19+
private var rect: Rect? = null
20+
21+
init {
22+
setWillNotDraw(false)
23+
}
24+
25+
private val paint by lazy {
26+
Paint().apply {
27+
color = Color.WHITE
28+
style = Paint.Style.STROKE
29+
strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3f, context?.resources?.displayMetrics)
30+
}
31+
}
32+
33+
override fun onUpdate(posRect: Rect) {
34+
rect = posRect
35+
invalidate()
36+
}
37+
38+
override fun onDraw(canvas: Canvas?) {
39+
super.onDraw(canvas)
40+
41+
if (rect != null) {
42+
canvas?.drawRect(rect, paint)
43+
}
44+
}
45+
}

scanner/src/main/java/com/bobekos/bobek/scanner/BarcodeScanner.kt

+61-19
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,96 @@ import android.Manifest
44
import android.annotation.SuppressLint
55
import android.content.Context
66
import android.content.pm.PackageManager
7+
import android.graphics.Rect
78
import android.support.v4.app.ActivityCompat
89
import android.view.SurfaceHolder
9-
import com.bobekos.bobek.scanner.BarcodeTrackerFactory
1010
import com.google.android.gms.vision.CameraSource
11+
import com.google.android.gms.vision.Detector
1112
import com.google.android.gms.vision.MultiProcessor
13+
import com.google.android.gms.vision.Tracker
1214
import com.google.android.gms.vision.barcode.Barcode
1315
import com.google.android.gms.vision.barcode.BarcodeDetector
1416
import io.reactivex.Observable
17+
import io.reactivex.ObservableEmitter
1518

1619

17-
class BarcodeScanner(private val context: Context?, private val holder: SurfaceHolder) {
20+
internal class BarcodeScanner(
21+
private val context: Context?,
22+
private val holder: SurfaceHolder,
23+
private val config: BarcodeScannerConfig) {
1824

1925
private val barcodeDetector by lazy {
20-
BarcodeDetector.Builder(context).build()
26+
BarcodeDetector.Builder(context)
27+
.setBarcodeFormats(config.barcodeFormat)
28+
.build()
29+
}
30+
31+
private val cameraSource by lazy {
32+
getCameraSource(config.previewSize, config.isAutoFocus)
2133
}
2234

2335
@SuppressLint("MissingPermission")
2436
fun getObservable(): Observable<Barcode> {
25-
return Observable.create<Barcode> { emitter ->
26-
27-
if (context == null) {
37+
return Observable.create { emitter ->
38+
if (context == null && !emitter.isDisposed) {
2839
emitter.onError(NullPointerException("Context is null"))
2940
} else {
3041
if (checkPermission()) {
31-
getCameraSource().start(holder)
42+
cameraSource.start(holder)
43+
44+
val tracker = BarcodeTracker(emitter)
45+
val processor = MultiProcessor.Builder(BarcodeTrackerFactory(tracker)).build()
46+
barcodeDetector.setProcessor(processor)
3247
} else {
33-
emitter.onError(SecurityException("Permission Denial: Camera"))
48+
if (!emitter.isDisposed) {
49+
emitter.onError(SecurityException("Permission Denial: Camera"))
50+
}
3451
}
3552

36-
val processor = MultiProcessor.Builder(BarcodeTrackerFactory({
37-
if (holder.surface == null || !holder.surface.isValid) {
38-
emitter.onComplete()
39-
} else if (it != null) {
40-
emitter.onNext(it)
41-
}
42-
})).build()
53+
emitter.setCancellable {
54+
cameraSource.release()
55+
}
56+
}
57+
}
58+
}
59+
60+
inner class BarcodeTracker(private val subscriber: ObservableEmitter<Barcode>) : Tracker<Barcode>() {
61+
62+
override fun onNewItem(id: Int, barcode: Barcode?) {
63+
if (barcode != null) {
64+
if (config.drawOverLay) {
65+
BarcodeView.overlaySubject.onNext(barcode.boundingBox)
66+
}
67+
68+
if (!subscriber.isDisposed) {
69+
subscriber.onNext(barcode)
70+
}
71+
}
72+
}
73+
74+
override fun onUpdate(detection: Detector.Detections<Barcode>?, barcode: Barcode?) {
75+
if (barcode != null && config.drawOverLay) {
76+
BarcodeView.overlaySubject.onNext(barcode.boundingBox)
77+
}
78+
}
79+
80+
override fun onMissing(p0: Detector.Detections<Barcode>?) {
81+
82+
}
4383

44-
barcodeDetector.setProcessor(processor)
84+
override fun onDone() {
85+
if (config.drawOverLay) {
86+
BarcodeView.overlaySubject.onNext(Rect())
4587
}
4688
}
4789
}
4890

49-
private fun getCameraSource(): CameraSource {
91+
private fun getCameraSource(size: Size, isAutoFocus: Boolean): CameraSource {
5092
return CameraSource.Builder(context, barcodeDetector)
5193
.setFacing(CameraSource.CAMERA_FACING_BACK)
52-
.setRequestedPreviewSize(640, 480)
94+
.setRequestedPreviewSize(size.width, size.height)
5395
.setRequestedFps(15.0f)
54-
.setAutoFocusEnabled(true)
96+
.setAutoFocusEnabled(isAutoFocus)
5597
.build()
5698
}
5799

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.bobekos.bobek.scanner
2+
3+
import com.google.android.gms.vision.barcode.Barcode
4+
5+
6+
internal data class BarcodeScannerConfig(
7+
var isAutoFocus: Boolean = true,
8+
var drawOverLay: Boolean = false,
9+
var previewSize: Size = Size(640, 480),
10+
var barcodeFormat: Int = Barcode.ALL_FORMATS
11+
)
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
package com.bobekos.bobek.scanner
22

3-
import com.google.android.gms.vision.Detector
43
import com.google.android.gms.vision.MultiProcessor
54
import com.google.android.gms.vision.Tracker
65
import com.google.android.gms.vision.barcode.Barcode
76

87

9-
class BarcodeTrackerFactory(private val callback: (barcode: Barcode?) -> Unit) : MultiProcessor.Factory<Barcode> {
8+
internal class BarcodeTrackerFactory(private val tracker: Tracker<Barcode>) : MultiProcessor.Factory<Barcode> {
109

1110
override fun create(p0: Barcode?): Tracker<Barcode> {
12-
return BarcodeTracker(callback)
13-
}
14-
15-
class BarcodeTracker(private val callback: (barcode: Barcode?) -> Unit) : Tracker<Barcode>() {
16-
17-
override fun onNewItem(id: Int, barcode: Barcode?) {
18-
callback(barcode)
19-
}
20-
21-
override fun onUpdate(p0: Detector.Detections<Barcode>?, p1: Barcode?) {
22-
}
23-
24-
override fun onMissing(p0: Detector.Detections<Barcode>?) {
25-
}
26-
27-
override fun onDone() {
28-
}
29-
11+
return tracker
3012
}
3113
}

0 commit comments

Comments
 (0)