【问题标题】:Android - QR generator APIAndroid - 二维码生成器 API
【发布时间】:2021-02-03 04:49:02
【问题描述】:

我正在尝试从我的应用中生成一些 QR,但我看到有很多类型的 QR,例如联系人、Wi-Fi 等。我想知道是否有免费的 API 或库来实现这个,我已经看到有网站已经在生成它,所以我想知道 Android 是否有任何 API 或库可供使用。

我检查过的内容:

http://goqr.me/api

Zxing

但我不确定是否有一个功能可以说我想要一个联系人的二维码,这样我就可以添加它的所有信息。

【问题讨论】:

  • 对于各种格式,看看这个优秀的答案——stackoverflow.com/a/26738158/3437352
  • 我想这就是我要找的东西!有没有我更新的页面?
  • 有人在我上面链接的同一线程中发布了这个有用的链接——github.com/zxing/zxing/wiki/Barcode-Contents
  • @SiddharthKamaria 所以,我不需要任何 API 或外部东西来生成 QR 我可以使用同一个库来生成和读取吗?如果是这样,我可以使用该库自定义颜色添加图像等吗?
  • 对于阅读,我使用 Google 的 Mobile Vision API 主要是因为它可以检测到很多开箱即用的 QR 格式,而无需我们将字符串切碎 -- developers.google.com/vision/android/barcodes-overview。关于您的其他查询,老实说,我不知道如何添加叠加层和更改 QR 颜色 :(

标签: android kotlin qr-code zxing


【解决方案1】:

U 可以使用QRCodeWriter 类和Zxing 生成QR 并使用encode() 函数,其中第一个参数是QR 保存的实际数据。自定义示例:

val qrCodeData: String = "data"
val bitMatrix = QRCodeWriter().encode(
    String(
        qrCodeData.toByteArray(charset(CHARSET)),
        Charset.forName(CHARSET)
    ),
    BarcodeFormat.QR_CODE,
    size,
    size,
    hints
)

其中hints 也是此库的一部分,可以在EncodeHintType 中找到。

然后你必须生成一个Bitmap,它可以显示在例如ImageView.

val bitmap = Bitmap.createBitmap(
    size,
    size,
    Bitmap.Config.ARGB_8888
)

for (x in 0 until size) {
    for (y in 0 until size) {
        val fillColor = if (bitMatrix[x, y]) Color.BLACK else Color.WHITE
        bitmap.setPixel(x, y, fillColor) // <-- color ur QR to default black and white
    }
}

【讨论】:

  • 但是我如何生成 QR 作为这个生成器,我可以说它是用于 Twitter、它是用于 SMS、它是一个 Wifi QR...这是参数?
  • 我没有收到任何问题。 Twitter的QR,SMS等的QR有什么区别?
  • 您应该在答案implementation 'com.google.zxing:core:3.4.0'中添加Zxing的依赖项
  • 他说他检查过了,但我确定可以
  • @StuartDTO 您可以自己创建各种类型的字符串并将其传递给 ZXing。例如,WiFi 的格式为"WIFI:S:$ssid;T:WPA;P:$passkey;;"。同样,您可以找到联系人等字符串。顺便说一句,Google Mobile Vision Barcode API 也可以理解此 WiFi 代码,而无需手动拆分字符串。
【解决方案2】:

使用 ZXing 生成二维码

在您的应用级别build.gradle 文件中添加以下ZXing 核心依赖项。

implementation 'com.google.zxing:core:3.4.0'

生成 512x512 像素 WiFi QR 码的示例代码。您可以在 ImageView 中设置生成的位图。

fun getQrCodeBitmap(ssid: String, password: String): Bitmap {
    val size = 512 //pixels
    val qrCodeContent = "WIFI:S:$ssid;T:WPA;P:$password;;"
    val hints = hashMapOf<EncodeHintType, Int>().also { it[EncodeHintType.MARGIN] = 1 } // Make the QR code buffer border narrower
    val bits = QRCodeWriter().encode(qrCodeContent, BarcodeFormat.QR_CODE, size, size) 
    return Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565).also {
        for (x in 0 until size) {
            for (y in 0 until size) {
                it.setPixel(x, y, if (bits[x, y]) Color.BLACK else Color.WHITE)
            }
        }
    }
}

要生成其他类型的二维码,例如 SMS、VCard 等,您可以查看这个有用的ZXing Wiki

使用 Google Mobile Vision API 扫描二维码

将以下 GMS 依赖项添加到您的应用级别 build.gradle

implementation 'com.google.android.gms:play-services-vision:20.1.2'

第 1 步:设置条码处理器回调。

private val processor = object : Detector.Processor<Barcode> {
    
    override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
        detections?.apply {
            if (detectedItems.isNotEmpty()) {
                val qr = detectedItems.valueAt(0)
                // Parses the WiFi format for you and gives the field values directly
                // Similarly you can do qr.sms for SMS QR code etc.
                qr.wifi?.let { 
                    Log.d(TAG, "SSID: ${it.ssid}, Password: ${it.password}")
                }
            }
        }
    }

    override fun release() {}
} 

第 2 步: 使用条形码处理器回调设置 BardcodeDetector,并将其添加到 CameraSource,如下所示。不要忘记在运行时检查 Manifest.permission.CAMERA 并将其添加到您的 AndroidManifest.xml

private fun setupCameraView() {
    if (ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
        BarcodeDetector.Builder(requireContext()).setBarcodeFormats(QR_CODE).build().apply {
            setProcessor(processor)
            if (!isOperational) {
                Log.d(TAG, "Native QR detector dependencies not available!")
                return
            }
            cameraSource = CameraSource.Builder(requireContext(), this).setAutoFocusEnabled(true)
                .setFacing(CameraSource.CAMERA_FACING_BACK).build()
        }
    } else {
        // Request camers permission from user
        // Add <uses-permission android:name="android.permission.CAMERA" /> to AndroidManifest.xml
    }
}

第 3 步:SurfaceView 添加到您的布局中以托管您的CameraSource

<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" /> 

第 4 步:创建回调以在创建/销毁表面时启动和停止 CameraSource

private val callback = object : SurfaceHolder.Callback {

    override fun surfaceCreated(holder: SurfaceHolder) {
        // Ideally, you should check the condition somewhere 
        // before inflating the layout which contains the SurfaceView
        if (isPlayServicesAvailable(requireActivity()))
            cameraSource?.start(holder)
    } 

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        cameraSource?.stop()
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { }
}


// Helper method to check if Google Play Services are up to-date on the phone
fun isPlayServicesAvailable(activity: Activity): Boolean {
    val code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(applicationContext)
    if (code != ConnectionResult.SUCCESS) {
        GoogleApiAvailability.getInstance().getErrorDialog(activity, code, code).show()
        return false
    }
    return true
}

第 5 步:将所有内容与生命周期方法链接在一起。

// Create camera source and attach surface view callback to surface holder
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.fragment_camera_sheet, container, false).also {
        setupCamera()
        it.surfaceView.holder.addCallback(callback)
    }
}

// Free up camera source resources
override fun onDestroy() {
    super.onDestroy()
    cameraSource?.release()
}

【讨论】:

  • 很棒的@Siddhart Kamaria,我会在测试后告诉你。这意味着我有一个何时可以进行所有可能的检测并在那里做自己的事情?我的意思是现在你已经放了 qr.wifi 但为了确保我可以接受所有我必须放在那里的所有类型,对吧?
  • @StuartDTO 是的,您可以在检测中使用 when 语句并进行正确处理,但请确保处理空值/空值。如果代码有任何问题,也请告诉我,因为我从我的一个项目中取出它并进行了一些编辑!
  • 我终于让它工作了,但是有没有办法像自定义扫描视图一样创建?
  • 非常感谢兄弟。
  • @hamidMahmoodi 感谢您指出这一点。
【解决方案3】:

如果您使用的是zxing-android-embedded

dependencies {
    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
}

你可以让它更短

val barcodeEncoder = BarcodeEncoder()
val bitmap = barcodeEncoder.encodeBitmap(content, BarcodeFormat.QR_CODE, 512, 512)

your_image_view.setImageBitmap(bitmap)

【讨论】:

    【解决方案4】:

    对于 vCard,我可以推荐这个How to create vcf file using java?

    ZXing正道【2021更新】

    依赖Gradle Scripts/build.gradle(Module:app)

    implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
    

    代码

    import android.util.Log;
    import android.graphics.Bitmap;
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.WriterException;
    import com.journeyapps.barcodescanner.BarcodeEncoder;
    
    public static Bitmap generateQR(String content, int size) {
        Bitmap bitmap = null;
        try {
            BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
            bitmap = barcodeEncoder.encodeBitmap(content,
                BarcodeFormat.QR_CODE, size, size);
        } catch (WriterException e) {
            Log.e("generateQR()", e.getMessage());
        }
        return bitmap;
    }
    

    更多详情:dx.dragan.ba/qr-creation-android/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      相关资源
      最近更新 更多