Callbacks
Implementing behaviour for the callback
parameter of the TireTreadScanView
is optional, and only needed for advanced use-cases.
It allows your application to react to all of the scan events, and implement custom workflows around the scan process.
The available events are:
-
OnScanStarted
: Invoked when the scanning process begins -
OnScanStopped
: Invoked when the scanning process ends -
OnImageUploaded
: Invoked after each frame is uploaded -
OnDistanceChanged
: Invoked whenever the distance between the device and the tire changes-
This information serves as a guide to assist your app’s users in scanning correctly
-
-
OnTireWidthProvided
: Invoked when the user provides a value via theTireWidthInput
screen or skips the step entirely
Listen to the ScanEvent
s and handle them, e.g.:
-
Android
-
Swift
class MyScanActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scan)
val myTireTreadScanView = findViewById<TireTreadScanView>(R.id.tireTreadScanView)
myTireTreadScanView.init(
tireTreadScanViewConfig = TireTreadScanViewConfig(),
onScanAborted = ::onScanAborted,
onScanProcessCompleted = ::onScanProcessCompleted,
tireTreadScanViewCallback = ::handleScanEvent,
) { measurementUUID, exception ->
// handle error during scanning process
}
}
private fun onScanAborted(measurementUUID: String?) {
// handle scan aborted
}
private fun onScanProcessCompleted(measurementUUID: String) {
Log.d("MY_APP", "upload is completed!")
// redirect to the result loading screen
if (!uuid.isNullOrEmpty()) {
openLoadAndResultScreen(uuid)
}
}
private fun handleScanEvent(event: ScanEvent) {
when (event) {
is OnImageUploaded -> {
Log.i(
getString(R.string.app_name),
"onImageUploaded: ${event.uploaded}/${event.total}"
)
}
// When not using the "default UI", use this event to provide guidance to the users
is OnDistanceChanged -> onDistanceChanged(event.uuid, event.previousStatus, event.newStatus, event.previousDistance, event.newDistance)
else -> {
Log.i(getString(R.string.app_name), event.toString())
}
}
}
fun startScanning() {
// this function allows your application to manually start the scan process
TireTreadScanner.instance.startScanning()
}
fun stopScanning() {
// this function allows your application to manually stop the scan process
TireTreadScanner.instance.stopScanning()
}
fun abortScan() {
// this function allows your application to manually abort the scan process
TireTreadScanner.instance.abortScanning()
finish()
}
private fun onDistanceChanged(uuid: String?, previousStatus: DistanceStatus, newStatus: DistanceStatus, previousDistance: Float, newDistance: Float, ) {
super.onDistanceChanged(uuid, previousStatus, newStatus, previousDistance, newDistance)
val measurementSystem = if (PreferencesUtils.shouldUseImperialSystem(this@ScanActivity)) {
MeasurementSystem.Imperial
} else {
MeasurementSystem.Metric
}
// newDistance will be in millimeters if you choose Metric, or in inches, if you choose Imperial
val distanceString: String = if (measurementSystem == MeasurementSystem.Imperial) {
"$newDistance in"
} else {
"${(newDistance / 10).toInt()} cm"
}
var message = ""
message = when (newStatus) {
DistanceStatus.TOO_CLOSE -> {
"Increase Distance: "
}
DistanceStatus.TOO_FAR -> {
"Decrease Distance: "
}
else -> {
"Distance OK"
}
}
message += distanceString
findViewById<TextView>(R.id.tvDistance).text = message
}
}
extension YourViewController {
TireTreadScanViewKt.TireTreadScanView(
context: self,
onScanAborted: onScanAborted,
onScanProcessCompleted: onScanProcessCompleted,
callback: handleScanEvent
) { measurementUUID, error in
// Handle errors during scanning process
}
private func onError(measurementUUID: String?, exception: Exception) {
print("onUploadFailed")
self.displayError()
}
private func onScanAborted(measurementUUID: String?) {
TireTreadScanner.companion.abortScanning()
finish()
}
private func onScanProcessCompleted(measurementUUID: String) {
print("onUploadCompleted")
if let safeUuid = event.measurementUUID {
// redirect to the result loading screen
self.displayLoading(uuid: safeUuid)
} else {
self.displayError()
}
}
private func handleScanEvent(event: ScanEvent) {
switch(event) {
case let event as OnImageUploaded:
print("onImageUploaded: \(event.total) images uploaded in total")
break
// When not using the "default UI", use this event to provide guidance to the users
case event as OnDistanceChanged:
self.onDistanceChanged(event.measurementUUID, event.previousStatus, event.newStatus, event.previousDistance, event.newDistance)
break
default:
print("ScanEvent: \(event.description)")
break
}
}
func startScanning() {
// this function allows your application to manually start the scan process
TireTreadScanner.companion.startScanning()
}
func stopScanning() {
// this function allows your application to manually stop the scan process
TireTreadScanner.companion.stopScanning()
}
func abortScanning() {
// this function allows your application to manually abort the scan process
TireTreadScanner.companion.abortScanning()
}
/// When not using the "default UI", use this callback to provide guidance to the users
/// Called when the distance has changed.
///
/// - Parameters:
/// - uuid: The UUID associated with the distance change.
/// - previousStatus: The previous distance status.
/// - newStatus: The new distance status.
/// - previousDistance: The previous distance value.
/// - newDistance: The new distance value.
///
/// Note: The distance values are provided in millimeters if the metric system is selected (`UserDefaultsManager.shared.imperialSystem = false`), and in inches if the imperial system is selected (`UserDefaultsManager.shared.imperialSystem = true`).
private func onDistanceChanged(uuid: String?, previousStatus: DistanceStatus, newStatus: DistanceStatus, previousDistance: Float, newDistance: Float) {
if Int(newDistance) != Int(previousDistance) {
let distanceInCentimeters = UserDefaultsManager.shared.imperialSystem ? (newDistance * 2.54) : (newDistance / 10.0)
DispatchQueue.main.async { [weak self] in
self?.updateUI(status: newStatus, distance: Int(UserDefaultsManager.shared.imperialSystem ? newDistance : distanceInCentimeters))
}
}
}
}