title: Android mlkit barcode scanner improve speed
body: <p>Hello I'm using android mlkit barcode scanner without firebase with androidx ,I follow  this code <a href="https://medium.com/@surya.n1447/google-vision-ml-kit-with-camerax-64bbbfd4c6fd" rel="nofollow noreferrer">https://medium.com/@surya.n1447/google-vision-ml-kit-with-camerax-64bbbfd4c6fd</a>
  When I scanning qrcode it is too slow and I don't know how to improve scanning speed is there some tricks  or something like that ? Or is better switch to zxing or Google vision ?
  I using  xiaomi mi 10 t pro</p>
  <p>class ScanPersonFragment : Fragment() {</p>
  <pre><code>private var processingBarcode = AtomicBoolean(false)
  private var mediaPlayer: MediaPlayer? = null
  private lateinit var cameraExecutor: ExecutorService
  private lateinit var scanBarcodeViewModel: ScanPersonViewModel
  
  
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      cameraExecutor = Executors.newSingleThreadExecutor()
      scanBarcodeViewModel = ViewModelProvider(this).get(ScanPersonViewModel::class.java)
  }
  
  override fun onCreateView(
      inflater: LayoutInflater,
      container: ViewGroup?,
      savedInstanceState: Bundle?
  ): View? {
      val v = inflater.inflate(R.layout.fragment_scan_person_destination, container, false)
      mediaPlayer = MediaPlayer.create(context, R.raw.beep)
      scanBarcodeViewModel.progressState.observe(viewLifecycleOwner, {
          v.fragment_scan_person_barcode_progress_bar.visibility = if (it) View.VISIBLE else View.GONE
      })
  
      scanBarcodeViewModel.navigation.observe(viewLifecycleOwner, { navDirections -&gt;
          navDirections?.let {
              findNavController().navigate(navDirections)
              scanBarcodeViewModel.doneNavigating()
          }
      })
  
      return v
  }
  
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)
      if (allPermissionsGranted()) {
          startCamera()
      } else {
          requestPermissions(
              REQUIRED_PERMISSIONS,
              REQUEST_CODE_PERMISSIONS
          )
      }
  }
  
  override fun onResume() {
      super.onResume()
      processingBarcode.set(false)
  }
  
  private fun startCamera() {
      // Create an instance of the ProcessCameraProvider,
      // which will be used to bind the use cases to a lifecycle owner.
      val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
  
  
  
  
      val imageCapture = ImageCapture.Builder()
          .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
          //.setTargetResolution(Size(400, 400))
          .build()
  
      // Add a listener to the cameraProviderFuture.
      // The first argument is a Runnable, which will be where the magic actually happens.
      // The second argument (way down below) is an Executor that runs on the main thread.
      cameraProviderFuture.addListener({
          // Add a ProcessCameraProvider, which binds the lifecycle of your camera to
          // the LifecycleOwner within the application's life.
          val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
          // Initialize the Preview object, get a surface provider from your PreviewView,
          // and set it on the preview instance.
          val preview = Preview.Builder().build().also {
              it.setSurfaceProvider(
                  fragment_scan_person_barcode_preview_view.surfaceProvider
              )
          }
          // Setup the ImageAnalyzer for the ImageAnalysis use case
          val imageAnalysis = ImageAnalysis.Builder()
              .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
              .build()
              .also {
                  it.setAnalyzer(cameraExecutor, BarcodeAnalyzer { barcode -&gt;
                      if (processingBarcode.compareAndSet(false, true)) {
                          mediaPlayer?.start()
                          searchBarcode(barcode)
                      }
                  })
              }
  
          // Select back camera
          val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
          try {
              // Unbind any bound use cases before rebinding
              cameraProvider.unbindAll()
              // Bind use cases to lifecycleOwner
              cameraProvider.bindToLifecycle(this, cameraSelector, preview,  imageAnalysis)
          } catch (e: Exception) {
              Log.e(&quot;PreviewUseCase&quot;, &quot;Binding failed! :(&quot;, e)
          }
      }, ContextCompat.getMainExecutor(requireContext()))
  }
  
  private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
      ContextCompat.checkSelfPermission(
          requireContext(), it
      ) == PackageManager.PERMISSION_GRANTED
  }
  
  override fun onRequestPermissionsResult(
      requestCode: Int, permissions: Array&lt;String&gt;, grantResults:
      IntArray
  ) {
      if (requestCode == REQUEST_CODE_PERMISSIONS) {
          if (allPermissionsGranted()) {
              startCamera()
          } else {
              Toast.makeText(
                  requireContext(),
                  &quot;Permissions not granted by the user.&quot;,
                  Toast.LENGTH_SHORT
              ).show()
          }
      }
  }
  
  private fun searchBarcode(barcode: String) {
      scanBarcodeViewModel.searchBarcode(barcode)
  }
  
  override fun onDestroy() {
      cameraExecutor.shutdown()
      super.onDestroy()
  }
  
  companion object {
      private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
      private const val REQUEST_CODE_PERMISSIONS = 10
  }
  </code></pre>
  <p>class BarcodeAnalyzer(private val barcodeListener: BarcodeListener) : ImageAnalysis.Analyzer {</p>
  <pre><code>@SuppressLint(&quot;UnsafeExperimentalUsageError&quot;)
  override fun analyze(imageProxy: ImageProxy) {
      val mediaImage = imageProxy.image
      if (mediaImage != null) {
          val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
          val options = BarcodeScannerOptions.Builder().setBarcodeFormats(Barcode.FORMAT_QR_CODE).build()
          val scanner = BarcodeScanning.getClient(options)
          // Pass image to the scanner and have it do its thing
          scanner.process(image)
              .addOnSuccessListener { barcodes -&gt;
                  // Task completed successfully
                  for (barcode in barcodes) {
  
                      barcodeListener(barcode.rawValue ?: &quot;&quot;)
                  }
              }
              .addOnFailureListener {
                  // You should really do something about Exceptions
              }
              .addOnCompleteListener {
                  // It's important to close the imageProxy
                  imageProxy.close()
              }
      }
  }
  </code></pre>
  <p>}</p>