KotlinでQRコード読み取り

今回はAndroidのUI開発の最新ツール「Jetpack Compose」を使用して、 AndroidアプリケーションでQRコードの読み取りに挑戦します!QRコードの読み取りにはZxingライブラリを使用させて頂きます。

※この記事は2023/08/6時点の情報です。

開発環境は「Android Studio Flamingo | 2022.2.1 Patch 2」を使用しました。 Kotlin初心者が製作していますので、いろいろおかしい点があるかと思います。 もし流用される場合は、適宜修正してください。ご利用は自己責任でお願いいたします。

完成イメージ

QRコード読み取りアプリの完成イメージ

【build.gradle(:app)】
Zxingを使用するための次のライブラリを追加しています。
implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
implementation 'androidx.appcompat:appcompat:1.0.2'

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.sample.qrreader'
    compileSdk 34

    defaultConfig {
        applicationId "com.sample.qrreader"
        minSdk 29
        targetSdk 34
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary true
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion '1.3.2'
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.8.0'
    implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.5.1'
    implementation platform('androidx.compose:compose-bom:2022.10.00')
    implementation 'androidx.compose.ui:ui'
    implementation 'androidx.compose.ui:ui-graphics'
    implementation 'androidx.compose.ui:ui-tooling-preview'
    implementation 'androidx.compose.material3:material3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00')
    androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
    debugImplementation 'androidx.compose.ui:ui-tooling'
    debugImplementation 'androidx.compose.ui:ui-test-manifest'
    implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
    implementation 'androidx.appcompat:appcompat:1.0.2'
}

ソースは以下のとおりです。新規プロジェクト作成で「Empty Activity」テンプレートを選択した際に自動作成された「MainActivity.kt」を修正しました。 新規プロジェクト作成に関してはコチラの記事を参考にしてください。【はじめてのAndroidアプリケーション(Kotlin)】

package com.sample.qrreader

import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.webkit.URLUtil
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.AnnotatedString
import com.google.zxing.integration.android.IntentIntegrator

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            QRCodeReaderScreen()
        }
    }
}

@Composable
fun QRCodeReaderScreen() {
    var qrCodeContent by remember { mutableStateOf(null) }
    val context = LocalContext.current

    val qrCodeResultLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == AppCompatActivity.RESULT_OK) {
            val intentResult = IntentIntegrator.parseActivityResult(result.resultCode, result.data)
            intentResult?.contents?.let {
                qrCodeContent = it
            }
        }
    }

    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        if (isGranted) {
            val integrator = IntentIntegrator(context as ComponentActivity)
            integrator.setOrientationLocked(false)
            qrCodeResultLauncher.launch(integrator.createScanIntent())
        } else {
            // アクセス許可が拒否されたケースを処理する
        }
    }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(onClick = { launcher.launch(Manifest.permission.CAMERA) }) {
            Text("Open Camera")
        }
        if (qrCodeContent != null) {
            Text("QR Code Content:")
            ClickableText(
                text = AnnotatedString(qrCodeContent!!),
                onClick = { offset ->
                    // URLをタップした際にはブラウザで開く
                    qrCodeContent?.let { url ->
                        if (URLUtil.isValidUrl(url)) {
                            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                            context.startActivity(intent)
                        }
                    }
                },
            )
        }
    }
}

Kotlin初心者なりに何とか動くものを作成することができました! QRコードを読み取るアプリはストアでもたくさん見かけますが、同じようなモノが 自分で作れると非常に嬉しいですね!どうでしたか?QRコードの読み取り処理を理解できましたか?

KotlinでQRコードを読み取る処理を覚えられましたか?

Kotlin初心者の筆者でも上手く作成できたので、きっと何とかなります!あきらめず頑張りましょう!

管理人情報