Skip to content
This repository has been archived by the owner on Oct 10, 2020. It is now read-only.

Commit

Permalink
Merge pull request #207 from mintware-de/merge_2.x_in_3.x
Browse files Browse the repository at this point in the history
Merge changes of 2.x into 3.x
  • Loading branch information
devtronic authored Apr 12, 2020
2 parents 102e6e4 + 340b5fb commit 8e01920
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 129 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ Changes:
- minSdk version on Android is now 18
- `BarcodeScanner.scan()` returns a `ScanResult` object. Check [UPGRADE.md](./UPGRADE.md) for migration details.

## v2.0.2 - 2020-04-14

Bugfixes:
- [Fixed the request camera permission flow on Android](https://github.com/mintware-de/flutter_barcode_reader/pull/186) - @devtronic

## v2.0.1 - 2020-02-19

Bugfixes:
Expand Down
54 changes: 48 additions & 6 deletions android/src/main/kotlin/de/mintware/barcode_scan/ActivityHelper.kt
Original file line number Diff line number Diff line change
@@ -1,41 +1,83 @@
package de.mintware.barcode_scan

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener
import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener

class ActivityHelper(private var applicationContext: Context?,
var activity: Activity? = null
) : PluginRegistry.ActivityResultListener {
) : ActivityResultListener, RequestPermissionsResultListener {

companion object {
const val TAG = "BarcodeScanPlugin"
const val REQ_START_SCAN = 100
const val REQ_CAMERA_PERMISSION = 200
}

private val resultMap: HashMap<Int, ActivityResultHandler> = linkedMapOf()
private val activityResultMap: HashMap<Int, ActivityResultListener> = linkedMapOf()
private val permissionResultMap: HashMap<Int, RequestPermissionsResultListener> = linkedMapOf()

fun showScannerActivity(result: MethodChannel.Result, config: Protos.Configuration) {
if (activity == null) {
Log.d(TAG, "Could not launch BarcodeScannerActivity because the plugin is not attached to any activity")
return
}

resultMap[REQ_START_SCAN] = ScanResultHandler(result)
activityResultMap[REQ_START_SCAN] = ScanResultHandler(result)

val intent = Intent(applicationContext, BarcodeScannerActivity::class.java)
intent.putExtra(BarcodeScannerActivity.EXTRA_CONFIG, config.toByteArray())
activity!!.startActivityForResult(intent, REQ_START_SCAN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
if (!resultMap.containsKey(requestCode)) {
if (!activityResultMap.containsKey(requestCode)) {
return false
}

return resultMap.getValue(requestCode).handle(requestCode, resultCode, data)
return activityResultMap
.getValue(requestCode)
.onActivityResult(requestCode, resultCode, data)
}

fun requestCameraAccessIfNecessary(sink: EventChannel.EventSink?
): Boolean {
if (activity == null) {
Log.d(TAG, "Could not launch BarcodeScannerActivity because the plugin is not attached to any activity")
return false
}

permissionResultMap[REQ_CAMERA_PERMISSION] = RequestCameraPermissionHandler(sink)

val array = arrayOf(Manifest.permission.CAMERA)
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
return false
}

ActivityCompat.requestPermissions(activity!!, array, REQ_CAMERA_PERMISSION)
return true
}

override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<out String>?,
grantResults: IntArray?
): Boolean {
if (!permissionResultMap.containsKey(requestCode)) {
return false
}

return permissionResultMap
.getValue(requestCode)
.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import io.flutter.plugin.common.PluginRegistry.Registrar
class BarcodeScanPlugin : FlutterPlugin, ActivityAware {

@Nullable
private var methodCallHandler: MethodCallHandlerImpl? = null
private var channelHandler: ChannelHandler? = null
@Nullable
private var activityHelper: ActivityHelper? = null

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
activityHelper = ActivityHelper(flutterPluginBinding.applicationContext)

methodCallHandler = MethodCallHandlerImpl(activityHelper!!)
methodCallHandler!!.startListening(flutterPluginBinding.binaryMessenger)
channelHandler = ChannelHandler(activityHelper!!)
channelHandler!!.startListening(flutterPluginBinding.binaryMessenger)
}

// This static function is optional and equivalent to onAttachedToEngine. It supports the old
Expand All @@ -35,7 +35,7 @@ class BarcodeScanPlugin : FlutterPlugin, ActivityAware {
@Suppress("unused")
@JvmStatic
fun registerWith(registrar: Registrar) {
val handler = MethodCallHandlerImpl(ActivityHelper(
val handler = ChannelHandler(ActivityHelper(
registrar.context(),
registrar.activity()
))
Expand All @@ -44,17 +44,17 @@ class BarcodeScanPlugin : FlutterPlugin, ActivityAware {
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
if (methodCallHandler == null) {
if (channelHandler == null) {
return
}

methodCallHandler!!.stopListening()
methodCallHandler = null
channelHandler!!.stopListening()
channelHandler = null
activityHelper = null
}

override fun onDetachedFromActivity() {
if (methodCallHandler == null) {
if (channelHandler == null) {
return
}

Expand All @@ -66,10 +66,11 @@ class BarcodeScanPlugin : FlutterPlugin, ActivityAware {
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
if (methodCallHandler == null) {
if (channelHandler == null) {
return
}
binding.addActivityResultListener(activityHelper!!)
binding.addRequestPermissionsResultListener(activityHelper!!)
activityHelper!!.activity = binding.activity
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package de.mintware.barcode_scan

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.zxing.BarcodeFormat
import com.google.zxing.Result
import me.dm7.barcodescanner.zxing.ZXingScannerView
Expand All @@ -20,11 +16,10 @@ class BarcodeScannerActivity : Activity(), ZXingScannerView.ResultHandler {
}

private lateinit var config: Protos.Configuration
private var scannerView: ZXingAutofocusScannerView? = null
lateinit var scannerView: ZXingScannerView
private var scannerViewInitialized: Boolean = false

companion object {
const val REQUEST_TAKE_PHOTO_CAMERA_PERMISSION = 100
const val TOGGLE_FLASH = 200
const val EXTRA_CONFIG = "config"
const val EXTRA_RESULT = "scan_result"
Expand All @@ -43,6 +38,7 @@ class BarcodeScannerActivity : Activity(), ZXingScannerView.ResultHandler {
Protos.BarcodeFormat.qr to BarcodeFormat.QR_CODE,
Protos.BarcodeFormat.upce to BarcodeFormat.UPC_E
)

}

// region Activity lifecycle
Expand Down Expand Up @@ -76,41 +72,37 @@ class BarcodeScannerActivity : Activity(), ZXingScannerView.ResultHandler {
scannerViewInitialized = true
}

override fun onPause() {
scannerView?.stopCamera()
super.onPause()
}

override fun onResume() {
super.onResume()

if (!requestCameraAccessIfNecessary()) {
setupScannerView()
scannerView?.setResultHandler(this)
startCamera()
}
}
// endregion

// region AppBar menu
override fun onCreateOptionsMenu(menu: Menu): Boolean {
scannerView?.also {
val buttonText = (if (it.flash) config.stringsMap["flash_off"] else config.stringsMap["flash_on"])
val item = menu.add(0, TOGGLE_FLASH, 0, buttonText)
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
var buttonText = config.stringsMap["flash_on"]
if (scannerView.flash) {
buttonText = config.stringsMap["flash_off"]
}

val item = menu.add(0, TOGGLE_FLASH, 0, buttonText)
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == TOGGLE_FLASH) {
scannerView?.toggleFlash()
scannerView.toggleFlash()
this.invalidateOptionsMenu()
return true
}
return super.onOptionsItemSelected(item)
}

override fun onPause() {
super.onPause()
scannerView.stopCamera()
}

override fun onResume() {
super.onResume()
setupScannerView()
scannerView.setResultHandler(this)
scannerView.startCamera()
}
// endregion

override fun handleResult(result: Result?) {
Expand Down Expand Up @@ -147,56 +139,6 @@ class BarcodeScannerActivity : Activity(), ZXingScannerView.ResultHandler {
finish()
}

private fun requestCameraAccessIfNecessary(): Boolean {
val array = arrayOf(Manifest.permission.CAMERA)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, array, REQUEST_TAKE_PHOTO_CAMERA_PERMISSION)
return true
}
return false
}

override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode != REQUEST_TAKE_PHOTO_CAMERA_PERMISSION) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
return
}
if (verifyPermissions(grantResults)) {
startCamera()
} else {
val intent = Intent()
intent.putExtra(EXTRA_ERROR_CODE, "PERMISSION_NOT_GRANTED")
setResult(RESULT_CANCELED, intent)
finish()
}
}

private fun startCamera() {
scannerView?.run {
if (config.useCamera > -1) {
startCamera(config.useCamera)
} else {
startCamera()
}
}
}

/**
* Check that all given permissions have been granted by verifying that each entry in the
* given array is of the value [PackageManager.PERMISSION_GRANTED].
* @see Activity.onRequestPermissionsResult
*/
private fun verifyPermissions(grantResults: IntArray): Boolean {
// Verify that each required permission has been granted, otherwise return false.
return grantResults.isNotEmpty() && grantResults.all {
it == PackageManager.PERMISSION_GRANTED
}
}

private fun mapRestrictedBarcodeTypes(): List<BarcodeFormat> {
val types: MutableList<BarcodeFormat> = mutableListOf()

Expand All @@ -211,5 +153,4 @@ class BarcodeScannerActivity : Activity(), ZXingScannerView.ResultHandler {

return types
}
}

}
Loading

0 comments on commit 8e01920

Please sign in to comment.