Android QR Code 掃描 各種條碼都能掃
透過Google Vision套件快速製作屬於自己的QR Code 掃描,進行QR Code 掃描各種條碼都能掃,Android QR Code利用相機功能・透過Mobile Vision API 解析QR Code,各種條碼都能掃。
文章目錄
- 導入Google Vision
- 聲明相機權限
- 布局&方法介紹
- 程式碼範例
- 效果展示
- Github
1.導入Google Vision
dependencies {
implementation 'com.google.android.gms:play-services-vision:20.1.3'
}
2.聲明相機權限
<uses-permission android:name="android.permission.CAMERA"/>
3.布局&方法介紹
布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<SurfaceView
android:id="@+id/scanner"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/result"
android:textSize="30sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/scanner" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
方法介紹
偵測Barcode樣式
BarcodeDetector.Builder(this@MainActivity)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build()
創建Camera
//傳入Barcode樣式
CameraSource.Builder(this@MainActivity, barcodeDetector)
//自動對焦
.setAutoFocusEnabled(true)
//預覽寬高
.setRequestedPreviewSize(measuredWidth, measuredHeight)
.build()
綁定Camer
holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
cameraSource.start(holder)
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
cameraSource.stop()
}
})
掃描完成資料回傳
barcodeDetector.setProcessor(object : Detector.Processor<Barcode> {
override fun release() {
}
override fun receiveDetections(detections: Detector.Detections<Barcode>) {
result = findViewById(R.id.result)
//獲取資料
val barcode = detections.detectedItems
if (barcode.size() > 0) {
runOnUiThread {
result.text = barcode.valueAt(0).displayValue
}
}
}
})
4.程式碼範例
import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.google.android.gms.vision.CameraSource
import com.google.android.gms.vision.Detector
import com.google.android.gms.vision.barcode.Barcode
import com.google.android.gms.vision.barcode.BarcodeDetector
private const val REQUEST_CAMERA: Int = 40
@SuppressLint("MissingPermission")
class MainActivity : AppCompatActivity() {
private lateinit var scanner: SurfaceView
private lateinit var result: TextView
private lateinit var cameraSource: CameraSource
private lateinit var barcodeDetector: BarcodeDetector
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//移除ActionBar
supportActionBar?.hide()
//先獲取相機權限
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
REQUEST_CAMERA
)
} else {
//初始化掃描器
initScanner()
//偵測後回傳
resultCallback()
}
}
private fun resultCallback() {
barcodeDetector.setProcessor(object : Detector.Processor<Barcode> {
override fun release() {
}
override fun receiveDetections(detections: Detector.Detections<Barcode>) {
result = findViewById(R.id.result)
//或取資料
val barcode = detections.detectedItems
if (barcode.size() > 0) {
runOnUiThread {
result.text = barcode.valueAt(0).displayValue
}
}
}
})
}
private fun initScanner() {
scanner = findViewById(R.id.scanner)
scanner.apply {
//創建Barcode偵測
barcodeDetector = BarcodeDetector.Builder(this@MainActivity)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build()
//獲取寬高後創建Camera
viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
viewTreeObserver.removeOnGlobalLayoutListener(this)
cameraSource = CameraSource.Builder(this@MainActivity, barcodeDetector)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(measuredWidth, measuredHeight)
.build()
}
})
//camera綁定surfaceView
holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
cameraSource.start(holder)
}
override fun surfaceChanged(
holder: SurfaceHolder,
format: Int,
width: Int,
height: Int
) {
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
cameraSource.stop()
}
})
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (REQUEST_CAMERA == requestCode && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setContentView(R.layout.activity_main)
//初始化掃描器
initScanner()
//偵測後回傳
resultCallback()
}
}
}
5.效果展示
6.Github
Github