About this codelab
HUAWEI ML Kit BCR Sdkprovides bank card recognition service can quickly recognize information such as the bank card number, covering mainstream bank cards such as China UnionPay, American Express, Mastercard, Visa, and JCB around the world. It is widely used in finance and payment scenarios requiring bank card binding to quickly extract bank card information, realizing quick input of bank card information.
What You Will Create
In this codelab, you will use the demo project that has been created for you to experience ML Kit BCR APIs. Through the demo project, you will experience developing a bank card recognition feature with;
- Developing app with Kotlin Language
- Managing permissong requests and permission process
- Using ML Kit SDK BCR feature and OCR
- Using Clipboard on android
What You Will Learn
In this codelab, you will learn how to:
- Initialize BCR OCR in order to recognition bank cards
- Integrate and use abilities of ML Kit BCR SDK
Hardware Requirements
- One PC with Android Studio installed
- One mobile phone with a USB data cable for running developed apps
Software Requirements
- Android Studio 3.x or later version(Download)
- Java JDK 1.8 or later version(Download)
- EMUI 5.0 or later
- HMS Core (APK) 5.0.1.300 or later version
- Android 4.4 or later
Required Knowledge
- Android development basics
- Basic Kotlin language knowledge
- Basic butterKnife usage knowledge
Before you get started, complete the following preparations:
- Create an app in AppGallery Connect.
- Create an Android Studio project.
- Generate a signing certificate.
- Generate a signing certificate fingerprint.
- Configure the signing certificate fingerprint.
- Add the app package name and save the configuration file.
- Configure the Maven repository address and AppGallery Connect gradle plug-in.
- Configure the signature file in Android Studio.
For details, please refer to Preparations for Integrating HUAWEI HMS.
You can download the codelab project from: https://github.com/lookub/BankCardRecognitionCodelab.git
Creating a Project
Step 1: Start Android Studio.
Step 2: Choose File > Open, go to the directory where the sample project is decompressed, and click OK.
Step 3: Configure the AppGallery Connect plug-in, Maven repository address, build dependencies, obfuscation scripts, and permissions. (These items have been configured in the sample code. If any of them does not meet your requirements, change it in your own project.)
1. Configure the Maven repository address and AppGallery Connect plug-in in the project's build.gradle file.
- Go to allprojects > repositories and configure the Maven repository address for the HMS Core SDK.
allprojects { repositories { maven { url 'https://developer.huawei.com/repo/' } ... } }
- Go to buildscript > repositories and configure the Maven repository address for the HMS Core SDK.
buildscript { repositories { maven {url 'https://developer.huawei.com/repo/'} ... } ... }
- Go to buildscript > dependencies and add build dependencies.
buildscript { dependencies { //Replace {agconnect_version} with the actual AGC plugin version number. //Example: classpath 'com.huawei.agconnect:agcp: 1.4.1.300' classpath 'com.huawei.agconnect:agcp:{agconnect_version}' } }
2. Configure the dependency package in the app's build.gradle file.
- Add a dependency package to the dependencies section in the build.gradle file.
dependencies { ... // ML Kit BCR SDK implementation 'com.huawei.hms:ml-computer-card-bcr:2.0.3.301' ... }
For ML Kit BCR SDK, please refer to latest version.
- Add the following information under apply plugin: 'com.android.application' in the file header:
apply plugin: 'com.huawei.agconnect'
3. Configure obfuscation scripts.
- Configure the following information in the app/proguard-rules.pro file:
-ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.hianalytics.android.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;}
- If you are using AndResGuard, add it to the allowlist in the obfuscation script file.
"R.string.hms*", "R.string.connect_server_fail_prompt_toast", "R.string.getting_message_fail_prompt_toast", "R.string.no_available_network_prompt_toast", "R.string.third_app_*", "R.string.upsdk_*", "R.layout.hms*", "R.layout.upsdk_*", "R.drawable.upsdk*", "R.color.upsdk*", "R.dimen.upsdk*", "R.style.upsdk*", "R.string.agc*"
4. Configure permissions in the AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
// Add this meta-data for automatically update the machine learning model to the user's device.
<meta-data android:name="com.huawei.hms.ml.DEPENDENCY" android:value="bcr"/>
Step 4: In the Android Studio window, choose File > Sync Project with Gradle Files to synchronize the project.
1. Locate following line to create and initialize the MLBcrCapture.Callback Object.
// TODO : create and initialize of MLBcrCapture.Callback
2. Create and initialize of MLBcrCapture.Callback
bcrCaptureCallback = object : MLBcrCapture.Callback {
override fun onSuccess(result: MLBcrCaptureResult) {
if (result == null) {
Log.e(TAG, "callback MLBcrCaptureResult is null")
return
}
Log.i(TAG, "Success AnalyseResults : $result")
}
override fun onCanceled() {
Log.d(TAG, "MLBcrCaptureResult callback onCanceled !")
}
override fun onFailure(retCode: Int, bitmap: Bitmap) {
Log.d(TAG, "MLBcrCaptureResult callback onFailure ! $retCode")
}
override fun onDenied() {
Log.d(TAG, "MLBcrCaptureResult callback onCameraDenied !")
}
}
}
3. Locate following line to create the MLBcrCaptureConfig.Factory Object.
// TODO : create and initialize of MLBcrCaptureConfig.Factory
4. Create and initialize of MLBcrCaptureConfig.Factory
val config = MLBcrCaptureConfig.Factory()
// Set the expected result type of bank card recognition.
.setIsShowPortraitStatusBar(true)
.setResultType(MLBcrCaptureConfig.RESULT_ALL)
.setOrientation(MLBcrCaptureConfig.ORIENTATION_AUTO)
.create()
5. Locate following line and create MLBcrCaptureFactory.getInstance().getBcrCapture with setted Config
// TODO : create and initialize of MBcrCapture
6.Create and initialize of MLBcrCaptureFactory.getInstance().getBcrCapture(config)
try {
val bcrCapture = MLBcrCaptureFactory.getInstance().getBcrCapture(config)
bcrCapture.captureFrame(this, bcrCaptureCallback)
} catch (e: Exception) {
Log.e(TAG, "MLBcrCapture captureFrame Exception : " + e.message, e)
displayFailureAnalyseResults(e.message.toString())
}
7.Invoke checkAndRequestPermissions function when click the R.id.ivCardImage, R.id.btnTakePhoto buttons
// TODO : call ActivityCompat.requestPermissions with checkAndRequestPermissions method
private fun checkAndRequestPermissions() {
ActivityCompat.requestPermissions(
this,
permissionRequestCameraAndStorage,
permissionCodeCameraAndStorage
)
}
8.Invoke startMLBcrCaptureCameraStream function if permissions were has got granted in onRequestPermissionsResult method
// TODO : call startMLBcrCaptureCameraStream function if permissions were has got granted
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
Log.d(TAG, "PermissionsResult : requestCode : $requestCode")
if (requestCode == permissionCodeCameraAndStorage) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED
) {
startMLBcrCaptureCameraStream()
} else {
Log.e(TAG, "onRequestPermissionsResult : CameraPermission was NOT GRANTED")
}
}
}
9.Invoke displaySuccessAnalyseResults function to show recognised card details
// TODO : call displaySuccessAnalyseResults method with MLBcrCaptureResult param in Callback onSuccess
// to show recognised card details
displaySuccessAnalyseResults(result)
10.In the camera stream screen that pops up, place the card in the frame.
![](assets/ss.jpg)
11.Invoke copyTextToClipboard function with view param when click the R.id.tvCardNumberAll or click other textViews thats are showing recognised card numbers partially
// eg : copyTextToClipboard(tvCardNumberAll)
//
// TODO : use Context.CLIPBOARD_SERVICE and set clipboard.setPrimaryClip with created ClipData.newPlainText object
private fun copyTextToClipboard(clickedView: TextView) {
val clickedText: String = clickedView.text.toString()
val clipboard = applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("copiedCardNumber", clickedText)
clipboard.setPrimaryClip(clip)
}
MLBcrCaptureConfig.Factory :
MLBcrCaptureResult content details:
With the object of MLBcrCaptureConfig, you can Specify the expected result type of bank card recognition.
1.1. Locate following line for MLBcrCaptureConfig.Factory custom configurations.
// TODO : custom initialize of MLBcrCaptureConfig.Factory
1.2. Implement the Wise Player’s seek method.
val config = MLBcrCaptureConfig.Factory()
// Set the expected result type of bank card recognition.
// MLBcrCaptureConfig.RESULT_NUM_ONLY: Recognize only the bank card number.
// MLBcrCaptureConfig.RESULT_SIMPLE: Recognize only the bank card number and validity period.
// MLBcrCaptureConfig.ALL_RESULT: Recognize information such as the bank card number, validity period, issuing bank, card organization, and card type.
.setIsShowPortraitStatusBar(true)
.setResultType(MLBcrCaptureConfig.RESULT_ALL)
// Set the recognition screen display orientation.
// MLBcrCaptureConfig.ORIENTATION_AUTO: adaptive mode. The display orientation is determined by the physical sensor.
// MLBcrCaptureConfig.ORIENTATION_LANDSCAPE: landscape mode.
// MLBcrCaptureConfig.ORIENTATION_PORTRAIT: portrait mode.
.setOrientation(MLBcrCaptureConfig.ORIENTATION_AUTO)
.create()
With the object of MLBcrCaptureResult, you can get recognised card details.
2.1.Set views with MLBcrCaptureResult object detail information in displaySuccessAnalyseResults function to show recognised card details
private fun displaySuccessAnalyseResults(result: MLBcrCaptureResult) {
val analyseResults: String = editFormatCardAnalyseResult(result).toString()
Log.i(TAG, "Success AnalyseResults : $analyseResults")
Utils.createVibration(applicationContext, 200)
clResults.visibility = View.VISIBLE
ivDelete.visibility = View.VISIBLE
ivCardImage.setImageBitmap(result.originalBitmap)
ivCardNumberImage.setImageBitmap(result.numberBitmap)
tvCardType.text = result.organization
tvExpireDate.text = result.expire
tvCardNumberAll.text = result.number
tvCardNumber1.text = result.number.substring(0, 4)
tvCardNumber2.text = result.number.substring(4, 8)
tvCardNumber3.text = result.number.substring(8, 12)
tvCardNumber4.text = result.number.substring(12, 16)
}
Test and Verification
Upon completing the essential parts of the code, connect your mobile device to the PC and enable the USB debugging mode. In the Android Studio window, click Run icon to run the project you have created in Android Studio to generate an APK. Then install the APK on the mobile device.
- Open the app upon installing it to your device
- Click the "Take Card Photo" Button.
- place the card in the rectangle and wait for it to recognize.
![](assets/ss.jpg)
Well done. You have successfully completed this Codelab and learned:
- How to developt app with Kotlin lanugage
- How to manage permission reauest and permission process
- How to use ML Kit SDK BCR feature
- How to use BCR OCR
- How to use Clipboard