Helps in detecting QR codes using Jetpack's CameraX and Google Vision.
- Covers
permissions
,viewfinder
- Provides
detected string
from QR code - Option to signal the library to stop detection
- Informs if
flash
hardware present, Option to toggle it on or off - Provides
on error
,exception
,permission denied
callbacks - Releases resources on pause, reclaims on resume, closes proxyImage when done, handles backpressure
- Uses
Jetpack's CameraX library
andGoogle's ML Kit
internally - so you're in safe hands! - Bonus:
- Option to detect QR code from Bitmap
- Option to get bitmap from project assets or device gallery on the fly
- Supports Jetpack Compose
InShot_20220408_161949510.mp4
In project-level build.gradle
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
In app-level build.gradle
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
// if using compose
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
}
dependencies {
// airqr
implementation "com.github.mumayank:airqr:AIR_QR_VERSION"
// jetpack cameraX
implementation "androidx.camera:camera-core:+"
implementation "androidx.camera:camera-view:+"
// jetpack compose
implementation "androidx.compose.ui:ui:+"
implementation "androidx.compose.ui:ui-tooling-preview:+"
implementation "androidx.compose.material:material:+"
implementation 'androidx.activity:activity-compose:+'
}
in onCreate
define previewView
:
val previewView = PreviewView(this)
in onCreate
's setContent
:
AndroidView(
factory = { previewView },
modifier = Modifier.fillMaxSize()
)
AirQr.Builder()
.withContext(LocalContext.current)
.withLifecycleOwner(LocalLifecycleOwner.current)
.withPreviewView(previewView)
.onError {
// can ignore as this means error only in processing the current frame
}
.onPermissionsNotGranted {
// cannot proceed, show some error
}
.onException {
// cannot proceed, show some error
}
.onQrCodeDetected { string, shouldStopScanning ->
if (string.isNotEmpty()) { // your logic to confirm this is the QR code you are interested in
shouldStopScanning?.invoke() // call this method to inform the library to stop
// your regular flow continues from here
}
}
.build()
.startScan() // you could choose to stop at .build() and call airQr?.startScan() later too
Add PreviewView
in your layout xml
:
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
In your activity:
Declare airQr
at activity-level:
private var airQr: AirQr? = null
Define airQr
inside onCreate
:
airQr = AirQr.Builder()
.withContext(this@BindingExampleActivity)
.withLifecycleOwner(this@BindingExampleActivity)
.withPreviewView(binding.previewView)
// (rest of the builder functions same as above jetpack-way)
In activity, override:
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
airQr?.onRequestPermissionsResult(this, requestCode)
}
Analyze any bitmap for QR code:
AirQr.analyzeBitmap(
bitmap,
onDetection = { string ->
// qr code is successfully detected containing string
},
onError = { errorString ->
// show some error to the user
}
)
Get bitmap from image file in project's assets folder:
BitmapHelper.getBitmapFromAsset(
appCompatActivity,
"image.png", // image file name with extension
onSuccess = { bitmap ->
// use the bitmap in the above function to analyze it
},
onFailure = { errorString ->
// show some error to the user
}
)
Choose image from user's device (using explorer app/ other photos app installed on user's device)
BitmapHelper.getBitmapFromGallery(
this,
onSuccess = { bitmap ->
// use the bitmap in the above airqr function to analyze it
},
onFailure = { errorString ->
// show some error to the user
}
)
That's all!
Checkout: Issues and Wiki too!
PRs are welcomed!