ZXing Android Embeddedを使って、QRコードを読み取るアプリを作る方法について。
読み取ったQRコードを方法
設定
build.gradleにライブラリを追加します。
repositories {
jcenter()
}
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
implementation 'com.android.support:appcompat-v7:25.3.1' // Minimum 23+ is required
}
android {
buildToolsVersion '27.0.3' // Older versions may give compile errors
}
AndroidManifest.xmlを編集し、ハードウェアアクセラレーションを有効にします。
<application android:hardwareAccelerated="true" ... >
QRコードを読み取る画面を開く
activity_main.xmlにButtonを追加します。
ボタンを押したらscanBarcode()を実行します。
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/scan_barcode"
android:onClick="scanBarcode"/>
ボタンが押されたとき、QRコードを読み取るActivityを呼び出します。
public void scanBarcode(View view) {
new IntentIntegrator(this).initiateScan();
}
オプションを指定することで、QRコード読み込み画面の細かい設定ができます。
public void scanBarcode(View view) {
new IntentIntegrator(this)
// 読み取ったときにビープ音を鳴らさない
.setBeepEnabled(false)
// 画面の向きを固定しない
.setOrientationLocked(true)
// 読み取るバーコードのフォーマットを指定する
.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
// アクティビティを設定する
.setCaptureActivity(CustomScannerActivity.class)
.initiateScan();
}
読み取ったQRコードを受け取る
読み取ったコードを受け取ります。
// Get the results:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
if(result.getContents() == null) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
QRコード読み込み画面を自作する
QRコード読み込み画面を自作する方法を解説します。
画面デザイン
プレビューを表示するコンポーネントcom.journeyapps.barcodescanner.DecoratedBarcodeViewを配置します。
例)activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="@+id/barcodeView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_scanner_layout="@layout/custom_barcode_scanner"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
DecoratedBarcodeView内部のデザインをカスタマイズする場合はapp:zxing_scanner_layoutにレイアウトを設定します。
例)custom_barcode_scanner.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.journeyapps.barcodescanner.BarcodeView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/zxing_barcode_surface"/>
<com.journeyapps.barcodescanner.ViewfinderView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/zxing_viewfinder_view"/>
<TextView android:id="@+id/zxing_status_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="@color/zxing_transparent"
android:text="このテキストはbarcodeView.setStatusText()で設定できます"
android:textColor="@color/zxing_status_text"/>
</merge>
ソースコード
DecoratedBarcodeViewを設定します。
読み込むコードの形式を設定します。
val formats = listOf(BarcodeFormat.QR_CODE)
barcodeView.barcodeView.decoderFactory = DefaultDecoderFactory(formats)
その他の設定はbarcodeView.cameraSettingsで設定できます。
barcodeView.barcodeView.cameraSettings = CameraSettings()
コードを読み込んだときに実行するコールバックを設定します。
barcodeView.decodeContinuous(callback)
コードを読み込んだときの処理を作成します。
val callback = object : BarcodeCallback {
override fun barcodeResult(result: BarcodeResult?) {
if (result?.text == null || result.text == lastText) {
return
}
lastText = result.text
barcodeView.setStatusText(result.text)
}
override fun possibleResultPoints(resultPoints: MutableList<ResultPoint>?) {
}
}
例)MainActivity.kt
class MainActivity : AppCompatActivity() {
private var lastText: String = ""
private val callback = object : BarcodeCallback {
override fun barcodeResult(result: BarcodeResult?) {
if (result?.text == null || result.text == lastText) {
return
}
lastText = result.text
barcodeView.setStatusText(result.text)
}
override fun possibleResultPoints(resultPoints: MutableList<ResultPoint>?) {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val formats = listOf(BarcodeFormat.QR_CODE)
barcodeView.barcodeView.decoderFactory = DefaultDecoderFactory(formats)
barcodeView.decodeContinuous(callback)
}
override fun onResume() {
super.onResume()
barcodeView.resume()
}
override fun onPause() {
super.onPause()
barcodeView.pause()
}
}