Use the ZXing IntentIntegrator to turn your phone’s camera into a powerful QR Code scanner!
QR codes are all around us, and many of us have become accustomed to using these codes to quickly access information. App developers know that QR codes are quick and easy for consumers to scan. Let’s see how we can implement a QR code scanner in Android Studio in a few short steps.
Open Android Studio and create a new project. Select the “Empty Activity” template. Then, name the project “QRScannerTest” and select Kotlin for the programming language. Choose Android 7.0 for the Minimum SDK and create the project.
To access the class we will need from ZXing, we must add the following dependency to our module build.gradle file.
implementation 'com.journeyapps:zxing-android-embedded:4.2.0'
Then, add the following permission in the AndroidMainifest.xml file to gain access to the camera.
<uses-permission android:name="android.permission.CAMERA"
/>
For this project, we will just use a ConstraintLayout with a TextView and ImageButton. The TextView will be constrained in the center of our layout and have the text “Tap below to scan.” Our ImageButton will be constrained between the bottom of our TextView and the bottom of our layout. We have chosen a QR code vector asset from Android Studio’s clip art to use with our ImageButton.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"><TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tap below to scan"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/qr_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:srcCompat="@drawable/qr_scanner" />
</androidx.constraintlayout.widget.ConstraintLayout>
For our app to have the functionality to scan QR codes, we must make use of ZXing’s IntentIntegrator and override the onActivityResult function in our MainActivity class. IntentIntegrator allows us to start a QR code scan with just a few lines of code. The result will then appear in our Activity’s onActivityResult function. From there, we will use an AlertDialog to send the user to the QR code’s website.
4.1 Starting the QR Code Scanner in onCreate
First, we will get references to the views in our layout. Next, we will add an OnclickListener to our ImageButton that will use an instance of IntentIntegrator to start a scan.
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView:TextView = findViewById(R.id.textView)
val qrButton:ImageButton = findViewById(R.id.qr_button)
qrButton.setOnClickListener({
val intentIntegrator = IntentIntegrator(this)
intentIntegrator.setDesiredBarcodeFormats(listOf(IntentIntegrator.QR_CODE))
intentIntegrator.initiateScan()
})
}
}
Notice that we called the setDesiredBarcodeFormats function on the variable intentIntegrator. This function allows us to narrow down our barcode format to only focus on QR codes. The ZXing IntentIntegrator class has support for several barcode formats, but for this tutorial we are going to only focus on QR codes. Therefore, we pass a list with just the IntentIntegrator.QR_CODE constant as the only entry. Finally, we start a scan with the variable intentIntegrator’s initiateScan function.
4.2 Processing the Scanner’s Result in onActivityResult
The result of our scan will be sent to the onActivityResult function. In order for the fuction to work, we will have to call the super.onActivityResult function. After that, we will create a variable called “result” that will hold the data from IntentIntegrator’s parseActivityResult function. Then, we will use a conditional statement to check if result of our scan is empty.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
var result = IntentIntegrator.parseActivityResult(resultCode, data)
if (result != null) { }
}
Inside our if statement, we will add code that will be executed if our scan is successful. Here we will build and display the AlertDialog that we mentioned earlier. It will have both positive and negative buttons. If the positive button is selected, then an Intent will be used to start an Internet search with QR code’s data. Otherwise, the user will remain at the same screen in our app.
AlertDialog.Builder(this)
.setMessage("Would you like to go to ${result.contents}?")
.setPositiveButton("Yes", DialogInterface.OnClickListener { dialogInterface, i ->
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY,result.contents)
startActivity(intent)
})
.setNegativeButton("No",DialogInterface.OnClickListener { dialogInterface, i -> })
.create()
.show()
To test this app, run the app in Android Studio and install it on a device. Once the app is installed, make sure that you have enabled the Camera permission for the app in Settings if it is not enabled already. Next, find a QR code and tap the ImageButton to scan it. You should then see the AlertDialog display with a message regarding the QR code. Select “Yes” if you wish to visit the code’s URL. Then, you will have successfully arrived at the QR code’s destination.
Awesome job! With this example, you can now build a QR code scanner in your next Android Studio project! I encourage you to view the official documentation for the ZXing scanner because it is very versatile. The link to that documentation is below. Also, if you want to see the full code for this project, feel free to click on the link to its GitHub repository. Happy coding!