You should call the scanner.startScan() function from another suspend function to avoid it from getting executed on the main thread.
Example :
A barcode scanner class that has the function to start scan and store the result inside of a StateFlow.
class BarcodeScanner(
context: Context
) {
/**
* From the docs: If you know which barcode formats you expect to read, you can improve the
* speed of the barcode detector by configuring it to only detect those formats.
*/
private val options = GmsBarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_ALL_FORMATS
)
.build()
private val scanner = GmsBarcodeScanning.getClient(context, options)
val barCodeResults = MutableStateFlow<String?>(null)
suspend fun startScan() {
try {
val result = scanner.startScan().await()
barCodeResults.value = result.rawValue
Timber.d(barCodeResults.value)
} catch (e: Exception) {
Log.d("scan error: $e")
}
}
Provide the scanner class using dagger hilt
@InstallIn(SingletonComponent::class)
@Module
object AppModules {
@Provides
fun provideBarcodeScanner(@ApplicationContext appContext: Context) = BarcodeScanner(appContext)
}
Call the function from your viewModel
class MainViewModel @Inject (barcodeScanner : BarcodeScanner) : ViewModel {
val scanResult = MutableStateFlow<String?>(null)
init{
barcodeScanner.barCodeResults.collect{
scanResult.value = it
}
}
fun startScanning(){
lifecycleScope.launch{
barcodeScanner.startScan()
}
}
}