Easy barcodes scanning on Android

Yevhenii Smirnov
Yevhenii Smirnov
Dec 8 2023
Posted in Engineering & Technology

Scan barcodes in Android applications without the need for additional development or permission requests

Easy barcodes scanning on Android

Developing features from scratch can be time-consuming and resource-intensive. On the other hand, incorporating features from various sources may not be reliable, especially if they are from unknown or unmaintained origins.

So, what's the best approach?

Ultimately, it boils down to finding a balance based on factors such as:

  • Control: How much control do you need over the feature?
  • Trust: Consider the reliability and maintenance of the source.
  • Resources: Evaluate the time and effort required for implementation or development.

Let's explore Google code scanner, a solution that allows seamless code scanning without extra development and eliminating the need for camera permission requests.

PS: Be sure not to skip important notes provided at the end!

Implementing basic configuration

In your top-level settings.gradle, include following maven repositories under the dependencyResolutionManagement block:

dependencyResolutionManagement {
  repositories {
    google()
    mavenCentral()
  }
}

In your app/build.gradle add the Google Play services dependency for the play-services-code-scanner:

dependencies {
  implementation 'com.google.android.gms:play-services-code-scanner:16.1.0'
}

Scanning a code

Get an instance of GmsBarcodeScanner:

// Options are optional
val options = GmsBarcodeScannerOptions.Builder()

    // Set barcode formats for faster detection, otherwise it will attempt to scan all supported formats
    .setBarcodeFormats(
        Barcode.FORMAT_QR_CODE,
        Barcode.FORMAT_AZTEC)

    // Enables auto zoom
    .enableAutoZoom()

    .build()

val scanner = GmsBarcodeScanning.getClient(context, options)

Scanning the barcode:

scanner.startScan()
   .addOnSuccessListener { barcode ->
       // Task completed successfully
   }
   .addOnCanceledListener {
       // Task canceled
   }
   .addOnFailureListener { e ->
       // Task failed with an exception
   }

And the result:

val rawValue: String? = barcode.rawValue

Important notes

This API is an unbundled library. In short, this means the scanner module is not statically linked in your app at build time, and it needs to be downloaded before use.

Now, there are three options:

  • Configure your app to download the module automatically while the app is installed from the Play Store by including the following code in your AndroidManifest.xml:
<application ...>
  ...
  <meta-data
      android:name="com.google.mlkit.vision.DEPENDENCIES"
      android:value="barcode_ui"/>
  ...
</application>
  • Manually request module installation:
private fun onGmsBarcodeScannerInstall() {
    val moduleInstall = ModuleInstall.getClient(this)
    val moduleInstallRequest = ModuleInstallRequest.newBuilder()
        .addApi(GmsBarcodeScanning.getClient(this))
        .build()

    moduleInstall
        .installModules(moduleInstallRequest)
        .addOnSuccessListener {
            if (it.areModulesAlreadyInstalled()) {
                // Gms Barcode Scanner is already installed
            }

            // Successfully installed Gms Barcode Scanner
        }
        .addOnFailureListener {
            // Failed to install Gms Barcode Scanner
        }
}
  • Let the Google Play services download the module when used for the first time

While the process may seem straightforward, it requires careful consideration due to the following factors:

  • The first option will not work during the app testing before the production release, as the app won't be installed from the Play Store.
  • Opting only for the third choice may lead to a poor user experience, as it's essential to have the scanner available when the user hits that scanner button.

I would recommend including the option for automatic installation in the AndroidManifest.xml. Additionally, consider implementing a manual installation request, for instance, during your intro flow to ensure module availability.

Furthermore, there have been reports, and I have personally encountered an issue where the module becomes unavailable even after successful installation and use. It's important to highlight this, everything seems to work as expected initially, and the problem may surface after hours or even days of use.

With that said, you may consider implementing a manual request for module installation every time the app is launched, at least until the issue is solved. This proactive measure ensures the module availability.

Conclusion

I find great joy in sharing my personal experiences rather than simply crafting a standard implementation guide that you might come across elsewhere.

Speaking of guides, I highly recommend consistently checking the official documentation, even after reading any guide!

As always, you can find us available for any question you might have via our Support Channel.

Keep up-to-date with the latest news