KotlinでQRコード読み取り
今回はAndroidのUI開発の最新ツール「Jetpack Compose」を使用して、 AndroidアプリケーションでQRコードの読み取りに挑戦します!QRコードの読み取りにはZxingライブラリを使用させて頂きます。
開発環境は「Android Studio Flamingo | 2022.2.1 Patch 2」を使用しました。 Kotlin初心者が製作していますので、いろいろおかしい点があるかと思います。 もし流用される場合は、適宜修正してください。ご利用は自己責任でお願いいたします。
完成イメージ
【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初心者の筆者でも上手く作成できたので、きっと何とかなります!あきらめず頑張りましょう!