Scan Process

The scanning process happens entirely through the TireTreadScanView.

The TireTreadScanView

To start using the Anyline Tire Tread SDK for your measurements, you will need the TireTreadScanView. This view can be added, for example, directly to your Layout.xml file.

To include the TireTreadScanViewin your Layout.xml file, add the io.anyline.tiretread.sdk.scanner.TireTreadScanView view in the appropriated hierarchy, e.g.:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:backgroundTint="@color/black"
    tools:context=".activities.ScanActivity">

    <io.anyline.tiretread.sdk.scanner.TireTreadScanView
        android:id="@+id/myTireTreadScanView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:measurementSystem="metric"
        app:useDefaultHaptic="true" />

        <!-- app:measurementSystem can be set to "metric" or "imperial" -->

    <Button
        android:id="@+id/btnStartScan"
        android:layout_width="125dp"
        android:layout_height="60dp"
        android:layout_marginTop="60dp"
        android:text="Start Capture"
        android:onClick="onClickedBtnStartScan"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
    />

    <TextView
        android:id="@+id/tvDistance"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="40dp"
        android:background="@color/transparent"
        android:text="Distance"
        android:textSize="20dp"
        android:textColor="@color/white"
        android:textAlignment="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent">
    </TextView>

</androidx.constraintlayout.widget.ConstraintLayout>

If you have issues with the disposal of the TireTreadScanView, add the following lines to your Acitvity’s code, to define the View Composition Strategy:

override fun onCreate(savedInstanceState: Bundle?) {

    ...

    val myTireTreadScanView = findViewById<TireTreadScanView>(R.id.myTireTreadScanView)
    myTireTreadScanView.setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnLifecycleDestroyed(this))

    ...
}

Start Scanning

In the previous example, we’ve added a button alongside with the TireTreadScanView. This button will be responsible for starting and stopping the scan process. Here is a Kotlin example with its functionality:

fun onClickedBtnStartScan(view: View) {
    val scannerInstance = TireTreadScanner.instance

    val btnStartScan = (view as Button)
    if (!scannerInstance.isScanning) {
        // Here we start scanning
        scannerInstance.startScanning()
        btnStartScan.text = "Stop"
    } else {
        btnStartScan.visibility = View.GONE
        btnStartScan.isEnabled = false
        btnStartScan.isClickable = false
        // Here we stop scanning
        scannerInstance.stopScanning()
    }
}

The scanning process is automatically stopped after 10 seconds.

Handling the SDK’s events

The TireTreadScanViewCallback is the interface through which the TireTreadScanView communicates back to your application. With these callbacks, you can react on changes and implement your own workflow around the scan process. The callbacks available are:

  • onScanStart

    • Invoked when the scanning process begins

  • onScanStop

    • Invoked when the scanning process ends

  • onScanAbort

    • Invoked when the scanning process is aborted

  • onImageUploaded

    • Invoked after each frame is uploaded

  • onUploadCompleted

    • Invoked once all the frames were successfully uploaded for processing

  • onUploadFailed

    • Invoked if any issue occured during upload

  • 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

Once your "myTireTreadScanView" object is available, add your callback implementation to it. In this example, we will use our own Activity as the callback implementation.

Implement the TireTreadScanViewCallback interface, and override the desired methods, e.g.:

// Implement the TireTreadScanViewCallback interface
class MyScanActivity : AppCompatActivity(), TireTreadScanViewCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scan)

        val myTireTreadScanView = findViewById<TireTreadScanView>(R.id.tireTreadScanView)
        myTireTreadScanView.scanViewCallback = this

    }

    override fun onDistanceChanged(uuid: String?, previousStatus: DistanceStatus, newStatus: DistanceStatus, previousDistance: Float, newDistance: Float,
    ) {
        super.onDistanceChanged(uuid, previousStatus, newStatus, previousDistance, newDistance)

        // newDistance will be in millimiters if you choose Metric, or in inches, if you choose Imperial
        val scanView = findViewById<TireTreadScanView>(R.id.tireTreadScanView)
        val measurementSystem = scanView.measurementSystem
        val distanceString: String = if(measurementSystem == MeasurementSystem.Imperial){
            "${inchStringToTriple(inchToFractionString(newDistance.toDouble())).first} in"
        } else {
            "${(newDistance/10).toInt()} cm"
        }

        var message = ""
        message = when (newStatus) {
            DistanceStatus.CLOSE, DistanceStatus.TOO_CLOSE -> {
                "Increase Distance: "
            }
            DistanceStatus.FAR, DistanceStatus.TOO_FAR -> {
                "Decrease Distance: "
            }
            else -> {
                "Distance OK"
            }
        }
        message += distanceString
        findViewById<TextView>(R.id.tvDistance).text = message
    }

    // override the desired methods to implement your own workflow
    override fun onUploadCompleted(uuid: String?) {
        super.onUploadCompleted(uuid)
        Log.d("MY_APP", "onUploadCompleted!")

        // Tell the user to wait and/or start listening for the results
    }

    // override the desired methods to implement your own workflow
    override fun onUploadFailed(uuid: String?, exception: Exception) {
        super.onUploadFailed(uuid, exception)

        Toast.makeText(applicationContext, "Upload Failed. Check your internet and try again.", Toast.LENGTH_SHORT).show()
        Log.e("MY_APP", "onUploadFailed: ", exception)

        finish()
    }
}
You can check out our GitHub example repository for a full implementation of the Scan Activity.

Now, with the scan process finished, check out the next session to learn how to handle the measurement results.