Android - 二维码生成器API

15

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

我已经检查过:

http://goqr.me/api

Zxing

但我不确定是否有一个函数可以告诉我,好的,我想要一个联系人的QR码,这样我就可以添加所有相关信息。


查看这个优秀答案,了解各种格式--https://dev59.com/F2Ij5IYBdhLWcg3wxn2d#26738158 - Siddharth Kamaria
我想这就是我在寻找的!有没有任何页面可以让我更新这个信息? - StuartDTO
我主要使用Google的Mobile Vision API来进行读取,因为它可以直接检测到许多QR格式,而无需我们去处理字符串 -- https://developers.google.com/vision/android/barcodes-overview。关于您提出的另一个问题,我真的不知道如何添加覆盖层和更改QR颜色 :( - Siddharth Kamaria
我会在回答中添加一个例子。 - Siddharth Kamaria
只是为了更清楚地表达这个话题,QR码并不是不同的“类型”。QR码只包含数据。就这样。当它被扫描时,数据被读取。这取决于扫描它的系统或应用程序对数据的处理方式。 - TJ Olsen
显示剩余3条评论
4个回答

27

使用ZXing生成二维码

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

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

生成一个512x512像素的WiFi二维码的示例代码。您可以将结果位图设置到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)
            }
        }
    }
}

要生成其他类型的QR码,如短信、VCard等,请查看这个有用的ZXing Wiki
使用Google Mobile Vision API扫描QR码
将以下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,我测试完后会告诉你。这意味着我有一个when语句,包含所有可能的检测,并在其中执行自己的操作?我的意思是现在你已经放了qr.wifi,但为了确保我能接受所有类型,我必须把所有类型都放进去,对吧? - StuartDTO
@StuartDTO 是的,你可以在检测中使用when语句并进行正确的处理,但一定要处理null/空值。如果代码有任何问题,请告诉我,因为我是从我的一个项目中取出并进行了一些编辑! - Siddharth Kamaria
我已经在else块中请求了权限,但是什么也没有发生。如果我返回并再次打开活动,则会显示黑屏,但不会显示相机内容。 - StuartDTO
1
我终于让它工作了,但有没有办法创建像自定义扫描视图这样的东西? - StuartDTO
请将此行代码更正为:val bits = QRCodeWriter().encode(qrCodeContent, BarcodeFormat.QR_CODE, size, size) - hamid Mahmoodi
显示剩余3条评论

5

对于vCard,我可以推荐这个如何使用Java创建vcf文件?

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/


5
您可以使用 Zxing 中的 QRCodeWriter 类生成 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
    }
}

但我如何生成二维码,就像这些生成器一样,我可以说它是为Twitter,是为短信,还是为Wifi QR... 参数是什么? - StuartDTO
我不明白这个问题。Twitter的QR码和短信的QR码有什么区别? - P.Juni
1
你应该在你的答案中添加 Zxing 的依赖,即 implementation 'com.google.zxing:core:3.4.0' - Siddharth Kamaria
1
他说他检查过了,但我可以再确认一下。 - P.Juni
@StuartDTO 你可以自己创建不同类型的字符串并将其传递给ZXing。例如,WiFi的格式为“WIFI:S:$ssid;T:WPA;P:$passkey;;”。类似地,您也可以找到联系人等字符串。顺便说一句,这个WiFi代码也可以被Google Mobile Vision Barcode API理解,而无需手动拆分字符串。 - Siddharth Kamaria
显示剩余2条评论

2

如果您正在使用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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接