Commit f75b5469 authored by Mygod's avatar Mygod

Use Google mobile vision API to scan QR codes as well

Interestingly even though multiple QR code isn't enabled, if there are two QR codes in the picture they will all get scanned.
parent 22ffcc53
...@@ -70,9 +70,9 @@ dependencies { ...@@ -70,9 +70,9 @@ dependencies {
implementation 'com.twofortyfouram:android-plugin-api-for-locale:1.0.2' implementation 'com.twofortyfouram:android-plugin-api-for-locale:1.0.2'
implementation 'dnsjava:dnsjava:2.1.8' implementation 'dnsjava:dnsjava:2.1.8'
implementation 'eu.chainfire:libsuperuser:1.0.0.201704021214' implementation 'eu.chainfire:libsuperuser:1.0.0.201704021214'
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'net.glxn.qrgen:android:2.0' implementation 'net.glxn.qrgen:android:2.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
implementation 'xyz.belvi.mobilevision:barcodescanner:2.0.3'
testImplementation "junit:junit:$junitVersion" testImplementation "junit:junit:$junitVersion"
androidTestImplementation "com.android.support.test:runner:$androidTestVersion" androidTestImplementation "com.android.support.test:runner:$androidTestVersion"
androidTestImplementation "com.android.support.test.espresso:espresso-core:$androidEspressoVersion" androidTestImplementation "com.android.support.test.espresso:espresso-core:$androidEspressoVersion"
......
...@@ -23,41 +23,37 @@ package com.github.shadowsocks ...@@ -23,41 +23,37 @@ package com.github.shadowsocks
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.hardware.camera2.CameraAccessException import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.app.TaskStackBuilder import android.support.v4.app.TaskStackBuilder
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar import android.support.v7.widget.Toolbar
import android.util.Log import android.util.Log
import android.util.SparseArray
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import com.github.shadowsocks.App.Companion.app import com.github.shadowsocks.App.Companion.app
import com.github.shadowsocks.database.Profile import com.github.shadowsocks.database.Profile
import com.github.shadowsocks.database.ProfileManager import com.github.shadowsocks.database.ProfileManager
import com.github.shadowsocks.utils.resolveResourceId import com.github.shadowsocks.utils.resolveResourceId
import com.google.zxing.Result import com.google.android.gms.samples.vision.barcodereader.BarcodeCapture
import com.google.android.gms.samples.vision.barcodereader.BarcodeGraphic
import com.google.android.gms.vision.Frame import com.google.android.gms.vision.Frame
import com.google.android.gms.vision.barcode.Barcode import com.google.android.gms.vision.barcode.Barcode
import com.google.android.gms.vision.barcode.BarcodeDetector import com.google.android.gms.vision.barcode.BarcodeDetector
import xyz.belvi.mobilevisionbarcodescanner.BarcodeRetriever
import me.dm7.barcodescanner.zxing.ZXingScannerView class ScannerActivity : AppCompatActivity(), Toolbar.OnMenuItemClickListener, BarcodeRetriever {
class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Toolbar.OnMenuItemClickListener {
companion object { companion object {
private const val MY_PERMISSIONS_REQUEST_CAMERA = 1 private const val TAG = "ScannerActivity"
private const val REQUEST_IMPORT = 2 private const val REQUEST_IMPORT = 2
private const val REQUEST_IMPORT_OR_FINISH = 3 private const val REQUEST_IMPORT_OR_FINISH = 3
} }
private lateinit var scannerView: ZXingScannerView
private fun navigateUp() { private fun navigateUp() {
val intent = parentActivityIntent val intent = parentActivityIntent
if (shouldUpRecreateTask(intent) || isTaskRoot) if (shouldUpRecreateTask(intent) || isTaskRoot)
...@@ -67,19 +63,7 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too ...@@ -67,19 +63,7 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.layout_scanner)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
toolbar.title = title
toolbar.setNavigationIcon(theme.resolveResourceId(R.attr.homeAsUpIndicator))
toolbar.setNavigationOnClickListener { navigateUp() }
toolbar.inflateMenu(R.menu.scanner_menu)
toolbar.setOnMenuItemClickListener(this)
scannerView = findViewById(R.id.scanner)
if (Build.VERSION.SDK_INT >= 25) getSystemService(ShortcutManager::class.java).reportShortcutUsed("scan") if (Build.VERSION.SDK_INT >= 25) getSystemService(ShortcutManager::class.java).reportShortcutUsed("scan")
}
override fun onStart() {
super.onStart()
if (try { if (try {
(getSystemService(Context.CAMERA_SERVICE) as CameraManager).cameraIdList.isEmpty() (getSystemService(Context.CAMERA_SERVICE) as CameraManager).cameraIdList.isEmpty()
} catch (_: CameraAccessException) { } catch (_: CameraAccessException) {
...@@ -88,43 +72,29 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too ...@@ -88,43 +72,29 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too
startImport() startImport()
return return
} }
val permissionCheck = ContextCompat.checkSelfPermission(this, setContentView(R.layout.layout_scanner)
android.Manifest.permission.CAMERA) val toolbar = findViewById<Toolbar>(R.id.toolbar)
if (permissionCheck != PackageManager.PERMISSION_GRANTED) toolbar.title = title
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CAMERA), toolbar.setNavigationIcon(theme.resolveResourceId(R.attr.homeAsUpIndicator))
MY_PERMISSIONS_REQUEST_CAMERA) toolbar.setNavigationOnClickListener { navigateUp() }
toolbar.inflateMenu(R.menu.scanner_menu)
toolbar.setOnMenuItemClickListener(this)
(supportFragmentManager.findFragmentById(R.id.barcode) as BarcodeCapture).setRetrieval(this)
} }
override fun onResume() { override fun onRetrieved(barcode: Barcode) = runOnUiThread {
super.onResume() Profile.findAll(barcode.rawValue).forEach { ProfileManager.createProfile(it) }
val permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) navigateUp()
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
scannerView.setResultHandler(this) // Register ourselves as a handler for scan results.
scannerView.startCamera() // Start camera on resume
} }
override fun onRetrievedMultiple(closetToClick: Barcode?, barcode: MutableList<BarcodeGraphic>?) = check(false)
override fun onBitmapScanned(sparseArray: SparseArray<Barcode>?) { }
override fun onRetrievedFailed(reason: String?) {
Log.w(TAG, reason)
} }
override fun onPermissionRequestDenied() {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA)
if (grantResults.getOrNull(0) == PackageManager.PERMISSION_GRANTED) {
scannerView.setResultHandler(this)
scannerView.startCamera()
} else {
Toast.makeText(this, R.string.add_profile_scanner_permission_required, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.add_profile_scanner_permission_required, Toast.LENGTH_SHORT).show()
startImport() startImport()
} }
else super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun onPause() {
super.onPause()
scannerView.stopCamera() // Stop camera on pause
}
override fun handleResult(rawResult: Result?) {
Profile.findAll(rawResult?.text).forEach { ProfileManager.createProfile(it) }
navigateUp()
}
override fun onMenuItemClick(item: MenuItem) = when (item.itemId) { override fun onMenuItemClick(item: MenuItem) = when (item.itemId) {
R.id.action_import -> { R.id.action_import -> {
...@@ -160,11 +130,11 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too ...@@ -160,11 +130,11 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too
} catch (e: Exception) { } catch (e: Exception) {
app.track(e) app.track(e)
} }
} else Log.w("ScannerActivity", "Google vision isn't operational.") } else Log.w(TAG, "Google vision isn't operational.")
Toast.makeText(this, if (success) R.string.action_import_msg else R.string.action_import_err, Toast.makeText(this, if (success) R.string.action_import_msg else R.string.action_import_err,
Toast.LENGTH_SHORT).show() Toast.LENGTH_SHORT).show()
finish() navigateUp()
} else if (requestCode == REQUEST_IMPORT_OR_FINISH) finish() } else if (requestCode == REQUEST_IMPORT_OR_FINISH) navigateUp()
else -> super.onActivityResult(requestCode, resultCode, data) else -> super.onActivityResult(requestCode, resultCode, data)
} }
} }
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/toolbar_light_dark" /> <include layout="@layout/toolbar_light_dark" />
<me.dm7.barcodescanner.zxing.ZXingScannerView android:id="@+id/scanner" <fragment
android:layout_width="match_parent" android:id="@+id/barcode"
android:layout_height="0dp" android:name="com.google.android.gms.samples.vision.barcodereader.BarcodeCapture"
android:layout_weight="1"/> android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:gvb_auto_focus="true"
app:gvb_code_format="qr_code"/>
</LinearLayout> </LinearLayout>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment