在Jetpack Compose中为QR码扫描器添加小方块焦点。

huangapple go评论108阅读模式
英文:

Adding Small Square Focus to QR Code Scanner in Jetpack Compose

问题

我已成功在Jetpack Compose中实现了QR码扫描器,但我想通过在QR码图标上添加一个小正方形焦点来提升用户体验。这个正方形焦点会直观地指示用户应该将QR码放置在哪里进行扫描。我应该如何实现这个效果并将其集成到我的QR码扫描器实现中?

通过在提供的代码中实现这些更改,我期望在相机预览的顶部看到一个小红色正方形叠加层,表示QR码的焦点区域。由于先前代码实现中存在错误,小正方形叠加层未正确绘制在相机预览的顶部,并且编译错误阻止了代码按预期工作。

英文:

I have successfully implemented a QR Code Scanner in Jetpack Compose, but I would like to enhance the user experience by adding a small square focus that hovers over the icon of the QR code. This square focus will visually indicate to the user where to position the QR code for scanning. How can I achieve this effect and integrate it into my existing QR Code Scanner implementation?

By implementing the changes in the provided code, I would expect to see a small red square overlay on top of the camera preview, indicating the focus area for the QR code.Due to errors in the previous code implementation, the small square overlay was not drawn correctly on top of the camera preview, and the compilation errors prevented the code from functioning as intended.

答案1

得分: 0

你可以尝试使用Google Code Scanner库,以下实现可能会对你有帮助:

  1. QRCodeScanner.kt
  2. -----------------
  3. import kotlinx.coroutines.flow.Flow
  4. interface QRCodeScanner {
  5. fun startScanning(): Flow<String?>
  6. }
  1. QRCodeScannerImpl.kt
  2. --------------------
  3. import com.google.android.gms.common.moduleinstall.ModuleInstallClient
  4. import com.google.android.gms.common.moduleinstall.ModuleInstallRequest
  5. import com.google.mlkit.vision.barcode.common.Barcode
  6. import com.google.mlkit.vision.codescanner.GmsBarcodeScanner
  7. import com.niyaj.popos.features.qrcode_scanner.domain.repository.QRCodeScanner
  8. import kotlinx.coroutines.channels.awaitClose
  9. import kotlinx.coroutines.flow.Flow
  10. import kotlinx.coroutines.flow.callbackFlow
  11. import kotlinx.coroutines.launch
  12. import timber.log.Timber
  13. class QRCodeScannerImpl(
  14. private val scanner: GmsBarcodeScanner,
  15. private val playModule: ModuleInstallClient,
  16. ) : QRCodeScanner {
  17. init {
  18. /** 检查设备上是否安装了ScannerModule,否则使用ModuleClientAPI进行安装,更多信息请访问
  19. https://developers.google.com/android/guides/module-install-apis **/
  20. playModule
  21. .areModulesAvailable(scanner)
  22. .addOnSuccessListener {
  23. if (!it.areModulesAvailable()) {
  24. Timber.d("Downloading QR Code Module")
  25. // 模块在设备上不存在,进行安装...
  26. // playModule.deferredInstall(scanner)
  27. val newRequest = ModuleInstallRequest.newBuilder().addApi(scanner).build()
  28. playModule.installModules(newRequest)
  29. }
  30. }.addOnFailureListener {
  31. Timber.d("Failed to install QRCodeScanner Module")
  32. }
  33. }
  34. override fun startScanning(): Flow<String?> {
  35. return callbackFlow {
  36. scanner.startScan()
  37. .addOnSuccessListener {
  38. launch {
  39. send(getDetails(it))
  40. }
  41. }.addOnFailureListener {
  42. launch {
  43. send(null)
  44. }
  45. }
  46. awaitClose { }
  47. }
  48. }
  49. private fun getDetails(barcode: Barcode): String? {
  50. return when (barcode.valueType) {
  51. Barcode.TYPE_WIFI -> {
  52. val ssid = barcode.wifi!!.ssid
  53. val password = barcode.wifi!!.password
  54. val type = barcode.wifi!!.encryptionType
  55. "ssid : $ssid, password : $password, type : $type"
  56. }
  57. Barcode.TYPE_URL -> {
  58. "${barcode.url?.url}"
  59. }
  60. Barcode.TYPE_PRODUCT -> {
  61. barcode.displayValue
  62. }
  63. Barcode.TYPE_EMAIL -> {
  64. "${barcode.email?.address}"
  65. }
  66. Barcode.TYPE_CONTACT_INFO -> {
  67. "${barcode.contactInfo?.name?.formattedName}"
  68. }
  69. Barcode.TYPE_PHONE -> {
  70. "${barcode.phone?.number}"
  71. }
  72. Barcode.TYPE_CALENDAR_EVENT -> {
  73. "${barcode.calendarEvent?.description}"
  74. }
  75. Barcode.TYPE_GEO -> {
  76. "${barcode.geoPoint?.lat} ${barcode.geoPoint?.lng}"
  77. }
  78. Barcode.TYPE_ISBN -> {
  79. barcode.displayValue
  80. }
  81. Barcode.TYPE_DRIVER_LICENSE -> {
  82. "${barcode.driverLicense?.firstName} ${barcode.driverLicense?.lastName }${barcode.driverLicense?.lastName}"
  83. }
  84. Barcode.TYPE_SMS -> {
  85. "${barcode.sms}"
  86. }
  87. Barcode.TYPE_TEXT -> {
  88. barcode.rawValue
  89. }
  90. Barcode.TYPE_UNKNOWN -> {
  91. "${barcode.rawValue}"
  92. }
  93. else -> {
  94. null
  95. }
  96. }
  97. }
  98. }
  1. ScannerModule.kt
  2. import android.app.Application
  3. import android.content.Context
  4. import com.google.android.gms.common.moduleinstall.ModuleInstall
  5. import com.google.android.gms.common.moduleinstall.ModuleInstallClient
  6. import com.google.mlkit.vision.barcode.common.Barcode
  7. import com.google.mlkit.vision.codescanner.GmsBarcodeScanner
  8. import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
  9. import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
  10. import com.niyaj.popos.features.qrcode_scanner.data.QRCodeScannerImpl
  11. import com.niyaj.popos.features.qrcode_scanner.domain.repository.QRCodeScanner
  12. import dagger.Module
  13. import dagger.Provides
  14. import dagger.hilt.InstallIn
  15. import dagger.hilt.components.SingletonComponent
  16. @Module
  17. @InstallIn(SingletonComponent::class)
  18. object ScannerModule {
  19. @Provides
  20. fun provideContext(app: Application): Context {
  21. return app.applicationContext
  22. }
  23. @Provides
  24. fun provideBarCodeOptions(): GmsBarcodeScannerOptions {
  25. return GmsBarcodeScannerOptions.Builder()
  26. .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
  27. .build()
  28. }
  29. @Provides
  30. fun provideGooglePlayModule(context: Context): ModuleInstallClient {
  31. return ModuleInstall.getClient(context)
  32. }
  33. @Provides
  34. fun provideBarCodeScanner(context: Context, options: GmsBarcodeScannerOptions): GmsBarcodeScanner {
  35. return GmsBarcodeScanning.getClient(context, options)
  36. }
  37. @Provides
  38. fun provideBarCodeScannerRepository(scanner: GmsBarcodeScanner, playModule: ModuleInstallClient): QRCodeScanner {
  39. return QRCodeScannerImpl(scanner, playModule)
  40. }
  41. }

注意:代码中包含注释和链接,这些部分没有翻译。

英文:

You could try out Google Code Scanner Library
https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner

below implementation might help you.

  1. QRCodeScanner.kt
  2. -----------------
  3. import kotlinx.coroutines.flow.Flow
  4. interface QRCodeScanner {
  5. fun startScanning(): Flow&lt;String?&gt;
  6. }
  1. QRCodeScannerImpl.kt
  2. --------------------
  3. import com.google.android.gms.common.moduleinstall.ModuleInstallClient
  4. import com.google.android.gms.common.moduleinstall.ModuleInstallRequest
  5. import com.google.mlkit.vision.barcode.common.Barcode
  6. import com.google.mlkit.vision.codescanner.GmsBarcodeScanner
  7. import com.niyaj.popos.features.qrcode_scanner.domain.repository.QRCodeScanner
  8. import kotlinx.coroutines.channels.awaitClose
  9. import kotlinx.coroutines.flow.Flow
  10. import kotlinx.coroutines.flow.callbackFlow
  11. import kotlinx.coroutines.launch
  12. import timber.log.Timber
  13. class QRCodeScannerImpl(
  14. private val scanner: GmsBarcodeScanner,
  15. private val playModule: ModuleInstallClient,
  16. ) : QRCodeScanner {
  17. init {
  18. /** Checking does ScannerModule is installed on the device otherwise,
  19. install using ModuleClientAPI, for more visit
  20. https://developers.google.com/android/guides/module-install-apis **/
  21. playModule
  22. .areModulesAvailable(scanner)
  23. .addOnSuccessListener {
  24. if (!it.areModulesAvailable()) {
  25. Timber.d(&quot;Downloading QR Code Module&quot;)
  26. // Modules are not present on the device install...
  27. // playModule.deferredInstall(scanner)
  28. val newRequest = ModuleInstallRequest.newBuilder().addApi(scanner).build()
  29. playModule.installModules(newRequest)
  30. }
  31. }.addOnFailureListener {
  32. Timber.d(&quot;Failed to install QRCodeScanner Module&quot;)
  33. }
  34. }
  35. override fun startScanning() : Flow&lt;String?&gt; {
  36. return callbackFlow {
  37. scanner.startScan()
  38. .addOnSuccessListener {
  39. launch {
  40. send(getDetails(it))
  41. }
  42. }.addOnFailureListener {
  43. launch {
  44. send(null)
  45. }
  46. }
  47. awaitClose { }
  48. }
  49. }
  50. private fun getDetails(barcode : Barcode) : String? {
  51. return when (barcode.valueType) {
  52. Barcode.TYPE_WIFI -&gt; {
  53. val ssid = barcode.wifi!!.ssid
  54. val password = barcode.wifi!!.password
  55. val type = barcode.wifi!!.encryptionType
  56. &quot;ssid : $ssid, password : $password, type : $type&quot;
  57. }
  58. Barcode.TYPE_URL -&gt; {
  59. &quot;${barcode.url?.url}&quot;
  60. }
  61. Barcode.TYPE_PRODUCT -&gt; {
  62. barcode.displayValue
  63. }
  64. Barcode.TYPE_EMAIL -&gt; {
  65. &quot;${barcode.email?.address}&quot;
  66. }
  67. Barcode.TYPE_CONTACT_INFO -&gt; {
  68. &quot;${barcode.contactInfo?.name?.formattedName}&quot;
  69. }
  70. Barcode.TYPE_PHONE -&gt; {
  71. &quot;${barcode.phone?.number}&quot;
  72. }
  73. Barcode.TYPE_CALENDAR_EVENT -&gt; {
  74. &quot;${barcode.calendarEvent?.description}&quot;
  75. }
  76. Barcode.TYPE_GEO -&gt; {
  77. &quot;${barcode.geoPoint?.lat} ${barcode.geoPoint?.lng}&quot;
  78. }
  79. Barcode.TYPE_ISBN -&gt; {
  80. barcode.displayValue
  81. }
  82. Barcode.TYPE_DRIVER_LICENSE -&gt; {
  83. &quot;${barcode.driverLicense?.firstName} ${barcode.driverLicense?.lastName }${barcode.driverLicense?.lastName}&quot;
  84. }
  85. Barcode.TYPE_SMS -&gt; {
  86. &quot;${barcode.sms}&quot;
  87. }
  88. Barcode.TYPE_TEXT -&gt; {
  89. barcode.rawValue
  90. }
  91. Barcode.TYPE_UNKNOWN -&gt; {
  92. &quot;${barcode.rawValue}&quot;
  93. }
  94. else -&gt; {
  95. null
  96. }
  97. }
  98. }
  99. }
  1. ScannerModule.kt
  2. import android.app.Application
  3. import android.content.Context
  4. import com.google.android.gms.common.moduleinstall.ModuleInstall
  5. import com.google.android.gms.common.moduleinstall.ModuleInstallClient
  6. import com.google.mlkit.vision.barcode.common.Barcode
  7. import com.google.mlkit.vision.codescanner.GmsBarcodeScanner
  8. import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
  9. import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
  10. import com.niyaj.popos.features.qrcode_scanner.data.QRCodeScannerImpl
  11. import com.niyaj.popos.features.qrcode_scanner.domain.repository.QRCodeScanner
  12. import dagger.Module
  13. import dagger.Provides
  14. import dagger.hilt.InstallIn
  15. import dagger.hilt.components.SingletonComponent
  16. @Module
  17. @InstallIn(SingletonComponent::class)
  18. object ScannerModule {
  19. @Provides
  20. fun provideContext(app: Application):Context{
  21. return app.applicationContext
  22. }
  23. @Provides
  24. fun provideBarCodeOptions() : GmsBarcodeScannerOptions {
  25. return GmsBarcodeScannerOptions.Builder()
  26. .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
  27. .build()
  28. }
  29. @Provides
  30. fun provideGooglePlayModule(context: Context) : ModuleInstallClient {
  31. return ModuleInstall.getClient(context)
  32. }
  33. @Provides
  34. fun provideBarCodeScanner(context: Context, options: GmsBarcodeScannerOptions): GmsBarcodeScanner {
  35. return GmsBarcodeScanning.getClient(context, options)
  36. }
  37. @Provides
  38. fun provideBarCodeScannerRepository(scanner : GmsBarcodeScanner, playModule : ModuleInstallClient): QRCodeScanner {
  39. return QRCodeScannerImpl(scanner, playModule)
  40. }
  41. }

huangapple
  • 本文由 发表于 2023年7月20日 14:32:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727242.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定