-
Notifications
You must be signed in to change notification settings - Fork 16
Reference
Rather than complicating and diluting the library, we leave the task of requesting permissions to the implementation. You may wish to handle these uniquely, with your own rationale dialogs etc, but all our sample implementations handle runtime permissions for you to reference.
Resource: https://developer.android.com/training/permissions/requesting
The library declares
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
If your app requires the barcode features, you should declare these features as required in your apps manifest, in order for the PlayStore to filter your listing to devices with a camera.
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Resource: https://developer.android.com/guide/topics/manifest/uses-feature-element
This library is written almost exclusively in Kotlin, but should be usable from both Kotlin and Java applications. Wherever possible we have tried to adhere to Kotlin-Java interop guide.
Example Java usage
getLifecycle().addObserver(mBarcodeView);
mBarcodeView.getBarcodes().observe(this, new Observer<List<Barcode>>() {
@Override
public void onChanged(@NonNull List<Barcode> barcodes) {
StringBuilder builder = new StringBuilder();
for (Barcode barcode : barcodes) {
builder.append(barcode.getDisplayValue()).append("\n");
}
mTextBarcodes.setText(builder.toString());
}
});
This library is built to use and work with Android Architecture Components.
If you add BarcodeView
as an observer to your LifecycleOwner
(as in step 2), then we can call the relevant start()
, release()
, etc methods at the right lifecycle points for you.
If you wish not to use lifecycle awareness then we recommend you call the following in your lifecycle methods
override fun onStart() {
super.onStart()
barcodeView.start()
}
override fun onResume() {
super.onResume()
barcodeView.resume()
}
override fun onPause() {
super.onPause()
barcodeView.pause()
}
override fun onStop() {
super.onStop()
barcodeView.release()
}
These ensure that we are releasing resources when we can, and being good citizens of the user's device.
Resource: https://developer.android.com/topic/libraries/architecture/lifecycle
To receive barcodes you can simply observe the LiveData
objects provided
barcodeView.barcodes.observe(viewLifecycleOwner, Observer { barcodes ->
// ...
})
or
barcodeView.barcode.observe(viewLifecycleOwner, Observer { barcode ->
// ...
})
If don't wish to use LiveData
, then you can use one of the provided listener callbacks
barcodeView.onBarcodesListener = OnBarcodesListener { barcodes ->
// ...
}
or
barcodeView.onBarcodeListener = OnBarcodeListener { barcode ->
// ...
}
Resource: https://developer.android.com/topic/libraries/architecture/livedata
You choose to either receive one or multiple barcodes.
For implementation details on adding listeners, see the section above.
If you choose to receive a single barcode we simply take the first barcode from the list of barcodes.
To customise this behaviour, you can provide a sort comparator, which we will use to sort the list of barcodes before returning the first. We have provided a base class BarcodeComparator
in order to help guide this and provide you with FrameMetadata
, which might be useful when writing a sort.
app:sort="none"
Available values: none
or central
or
barcodeView.setOptions(
Options.Builder()
.barcodesSort(CentralBarcodeComparator())
.build()
)
or
barcodeView.setBarcodesSort(CentralBarcodeComparator())
We have provided this central sort to cover the common use case. It will sort the barcodes such that the one situated closest to the centre of the users frame (screen) will be first. This can be used in combination with listening for a single barcode, to only receive the barcode closest to the centre of the frame.
KBarcode will output various logs in order to provide errors and information. You can config these to not show for release builds by
KBarcode.setDebugging(BuildConfig.DEBUG)
We recommend you call this in your Application.onCreate()
. By default no logs will output.
Sometimes things go wrong when starting the camera. To receive callbacks about these
barcodeView.onCameraErrorListener = OnCameraErrorListener { error ->
// ...
}
See CameraException.kt for more details
You can request different camera facing directions
app:cameraFacing="back"
Available values: front
, back
or external
external
- Only available in Android.M
or
barcodeView.setOptions(
Options.Builder()
.cameraFacing(CameraCharacteristics.LENS_FACING_BACK)
.build()
)
or
barcodeView.setCameraFacing(CameraCharacteristics.LENS_FACING_BACK)
You can request different camera flash modes
app:cameraFacing="torch"
Available values: off
, single
or torch
or
barcodeView.setOptions(
Options.Builder()
.cameraFlashMode(CameraMetadata.FLASH_MODE_TORCH)
.build()
)
or
barcodeView.setCameraFlashMode(CameraMetadata.FLASH_MODE_TORCH)
This library can detect CODE_128, CODE_39, CODE_93, CODABAR, DATA_MATRIX, EAN_13, EAN_8, ITF, QR_CODE, UPC_A, UPC_E, PDF417 and AZTEC. However you can improve processing performance by reducing the number of formats you are looking for.
You can set your required formats in XML
app:formats="numeric"
Available values:
- all - Uses all the formats listed above
- numeric - CODABAR, EAN_13, EAN_8, ITF, UPC_A, UPC_E
- alphanumeric - CODE_128, CODE_39, CODE_93
- data - DATA_MATRIX, QR_CODE, PDF417, AZTEC
- ean - EAN_13, EAN_8
Or you can choose your own selection programmatically
barcodeView.setOptions(
Options.Builder()
.barcodeFormats(
intArrayOf(
Barcode.FORMAT_UPC_A, Barcode.FORMAT_UPC_E
)
)
.build()
)
or
barcodeView.setBarcodeFormats(
intArrayOf(
Barcode.FORMAT_UPC_A, Barcode.FORMAT_UPC_E
)
)
In order to make the processing as efficient as possible we want to provide it with the smallest image (frame) possible. However barcodes require a minimum number of pixels in order to represent themselves.
To this end we have provided some default minimum barcode widths, however some barcodes vary based on the number of characters you are encoding. Therefore our defaults may not provide the best results for your use case. So you can set the number yourself. Use the minimum number of pixels needed to encode your data, we use a multiple of this in order to cater for how much of the screen the barcode will occupy.
app:minBarcodeWidth="300"
or
barcodeView.setOptions(
Options.Builder()
.minBarcodeWidth(300)
.build()
)
or
barcodeView.setMinBarcodeWidth(100)
You can set different scale types on the preview shown within the BarcodeView
app:previewScaleType="centerInside"
Available values: centerInside
or centerCrop
or
barcodeView.setOptions(
Options.Builder()
.previewScaleType(BarcodeView.CENTER_INSIDE)
.build()
)
or
barcodeView.setPreviewScaleType(BarcodeView.CENTER_INSIDE)
Scale the surface uniformly (maintain its aspect ratio) so that both dimensions (width and height) of the surface will be equal to or less than the corresponding dimension of the parent BarcodeView.
Scale the surface uniformly (maintain its aspect ratio) so that both dimensions (width and height) of the surface will be equal to or larger than the corresponding dimension of the parent BarcodeView.
The BarcodeView
has a tap to focus feature, which clears the selected focus after a period of time. This provides the optimal user experience.
That period of time is customisable should your use case require something different.
app:clearFocusDelay="2000"
Available values: never
or a numeric value representing milliseconds
Setting the delay to never
, will mean the camera remains focused wherever the user taps indefinitely.
or
barcodeView.setOptions(
Options.Builder()
.clearFocusDelay(BarcodeView.CLEAR_FOCUS_DELAY_DEFAULT)
.build()
)
or
barcodeView.setClearFocusDelay(BarcodeView.CLEAR_FOCUS_DELAY_DEFAULT)
Please do raise issues for suggesting improvements to this wiki.