A powerful, easy-to-use Android SDK for barcode scanning and generation. Built with Kotlin and Jetpack Compose, BlinkCode provides a single entry point for all your barcode needs.
Via JitPack:
dependencies {
implementation("com.github.Syedovaiss:BlinkCode:1.0")
}- ✅ Real-time Camera Scanning - Scan barcodes using device camera with live preview
- ✅ Image Scanning - Scan barcodes from Bitmap images or URIs
- ✅ QR Code Generation - Generate QR codes with custom content and styling
- ✅ Barcode Generation - Support for multiple barcode formats (CODE_128, EAN_13, EAN_8, UPC_A, CODE_39, etc.)
- ✅ Jetpack Compose Ready - Built-in composable views for seamless integration
- ✅ Clean Architecture - Well-structured, testable, and maintainable codebase
- ✅ Minimal Dependencies - Single entry point API for easy integration
- Min SDK: 24 (Android 7.0)
- Target SDK: 36
- Kotlin: 2.0.21+
- Java: 11+
- Jetpack Compose: Required for UI components
Add JitPack to your root settings.gradle.kts:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}Then add the dependency in your app/build.gradle.kts:
dependencies {
implementation("com.github.Syedovaiss:BlinkCode:1.0")
}Alternatively, if you're using the module locally:
Add the BlinkCode module to your settings.gradle.kts:
include(":blinkcode")In your app/build.gradle.kts, add the dependency:
dependencies {
implementation(project(":blinkcode"))
}Add the required permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />For Android 13+ (API 33+), also add:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />For older versions, add:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />Initialize BlinkCode in your Application class:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
BlinkCode.initialize(this)
}
}Or with custom configuration:
BlinkCode.initialize(
context = this,
config = BlinkCodeConfig(
scanningEnabled = true,
creationEnabled = true,
loggingEnabled = true,
scanIntervalMillis = 500,
qrSize = Size(400, 400)
)
)@Composable
fun ScanScreen() {
BlinkCode.CreateCameraView(
onBarcodeDetected = { barcode ->
// Handle detected barcode
println("Detected: $barcode")
},
onError = { error ->
// Handle error
println("Error: ${error.message}")
}
)
}@Composable
fun GenerateScreen() {
var qrBitmap by remember { mutableStateOf<Bitmap?>(null) }
LaunchedEffect(Unit) {
val result = BlinkCode.generateQRCode(
content = "https://example.com",
size = Size(400, 400),
foregroundColor = Color.Black,
backgroundColor = Color.White
)
result.onSuccess { bitmap ->
qrBitmap = bitmap
}.onFailure { error ->
println("Error: ${error.message}")
}
}
BlinkCode.CreateBarcodeView(bitmap = qrBitmap)
}Initialize the SDK. Must be called before using any SDK features.
Parameters:
context: Context- Application contextconfig: BlinkCodeConfig- Optional configuration (default:BlinkCodeConfig())
Example:
BlinkCode.initialize(context = this)Scan barcode from an ML Kit InputImage.
Parameters:
inputImage: InputImage- The InputImage to scan
Returns: Result<List<String>> - List of detected barcode values
Example:
val inputImage = InputImage.fromBitmap(bitmap, rotationDegrees)
val result = BlinkCode.scanFromImage(inputImage)
result.onSuccess { barcodes ->
println("Found ${barcodes.size} barcode(s)")
}Scan barcode from a Bitmap image.
Parameters:
bitmap: Bitmap- The Bitmap to scan
Returns: Result<List<String>> - List of detected barcode values
Example:
val result = BlinkCode.scanFromBitmap(bitmap)
result.fold(
onSuccess = { barcodes -> println("Found: $barcodes") },
onFailure = { error -> println("Error: ${error.message}") }
)Scan barcode from an image URI.
Parameters:
uri: Uri- The URI of the imagecontext: Context- Context to load the image
Returns: Result<List<String>> - List of detected barcode values
Example:
val uri = // ... get URI from image picker
val result = BlinkCode.scanFromUri(uri, context)
result.onSuccess { barcodes ->
// Handle detected barcodes
}Generate a QR code bitmap.
Parameters:
content: String- Content to encodesize: Size- Size of the QR code (width x height)foregroundColor: Color- Foreground color (default: Black)backgroundColor: Color- Background color (default: White)
Returns: Result<Bitmap> - Generated QR code bitmap
Example:
val result = BlinkCode.generateQRCode(
content = "Hello World",
size = Size(400, 400),
foregroundColor = Color.Black,
backgroundColor = Color.White
)
result.onSuccess { bitmap ->
// Use the bitmap
}Generate a barcode bitmap.
Parameters:
content: String- Content to encodeformat: BarcodeFormat- Barcode format (CODE_128, EAN_13, EAN_8, UPC_A, CODE_39, etc.)size: Size- Size of the barcode (width x height)foregroundColor: Color- Foreground color (default: Black)backgroundColor: Color- Background color (default: White)
Returns: Result<Bitmap> - Generated barcode bitmap
Example:
val result = BlinkCode.generateBarcode(
content = "123456789012",
format = BarcodeFormat.CODE_128,
size = Size(400, 200),
foregroundColor = Color.Black,
backgroundColor = Color.White
)Create a camera view for real-time barcode scanning.
Parameters:
onBarcodeDetected: (String) -> Unit- Callback when barcode is detectedonError: ((Throwable) -> Unit)?- Optional error callback
Example:
BlinkCode.CreateCameraView(
onBarcodeDetected = { barcode ->
// Handle detected barcode
},
onError = { error ->
// Handle error
}
)Create a view to display a generated barcode or QR code.
Parameters:
bitmap: Bitmap?- The bitmap to display (can be null)modifier: Modifier- Optional Compose modifier for styling
Example:
BlinkCode.CreateBarcodeView(
bitmap = qrBitmap,
modifier = Modifier.size(200.dp)
)Customize SDK behavior with BlinkCodeConfig:
data class BlinkCodeConfig(
val scanningEnabled: Boolean = true, // Enable scanning features
val creationEnabled: Boolean = true, // Enable generation features
val loggingEnabled: Boolean = true, // Enable SDK logging
val qrSize: Size = Size(400, 400), // Default QR code size
val defaultColor: Color = Color.Black, // Default foreground color
val autoSaveGeneratedFiles: Boolean = false, // Auto-save generated files
val scanIntervalMillis: Long = 500 // Scan throttling interval
)Example:
BlinkCode.initialize(
context = this,
config = BlinkCodeConfig(
loggingEnabled = false,
scanIntervalMillis = 1000, // Scan every second
qrSize = Size(500, 500)
)
)- QR Code
- EAN-13
- EAN-8
- UPC-A
- UPC-E
- Code 128
- Code 39
- Code 93
- Codabar
- ITF
- Data Matrix
- PDF417
- Aztec
- QR Code
- CODE_128
- EAN_13
- EAN_8
- UPC_A
- CODE_39
- And more (via ZXing)
All scanning and generation methods return Result<T> which can be handled using Kotlin's Result API:
val result = BlinkCode.scanFromBitmap(bitmap)
// Option 1: Using fold
result.fold(
onSuccess = { barcodes ->
// Handle success
},
onFailure = { error ->
// Handle error
}
)
// Option 2: Using onSuccess/onFailure
result.onSuccess { barcodes ->
// Handle success
}.onFailure { error ->
// Handle error
}
// Option 3: Using getOrNull/getOrElse
val barcodes = result.getOrNull()
val barcodesOrEmpty = result.getOrElse { emptyList() }BlinkCode SDK follows clean architecture principles:
- API Layer: Single entry point (
BlinkCodeobject) - Domain Layer: Use cases for business logic
- Data Layer: Repositories and data sources
- Presentation Layer: UI components and ViewModels
The SDK uses Koin for dependency injection. All dependencies are configured internally and managed automatically.
The SDK is designed to be testable. All repositories and use cases use interfaces, making it easy to mock dependencies in tests.
If you're using ProGuard or R8, add these rules to your proguard-rules.pro:
# BlinkCode SDK
-keep class com.ovais.blinkcode.** { *; }
-dontwarn com.ovais.blinkcode.**
# Keep ZXing classes
-keep class com.google.zxing.** { *; }
# Keep ML Kit classes
-keep class com.google.mlkit.** { *; }
-dontwarn com.google.mlkit.**
Make sure you request camera permission before using the camera view:
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
// Camera permission granted
}
}
// Request permission
launcher.launch(Manifest.permission.CAMERA)Make sure you call BlinkCode.initialize() in your Application class before using any SDK features.
The SDK automatically handles camera lifecycle management. If you encounter binding errors, ensure:
- Only one camera view is active at a time
- The camera view is properly disposed when leaving the screen
- Camera permissions are granted
Check out the sample app in the app module for complete examples of all SDK features.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
For issues, questions, or feature requests, please open an issue on the repository.
Made with ❤️ using Kotlin and Jetpack Compose