From 1709ffd8ffdfc5b31da6921550d6df0a0030571e Mon Sep 17 00:00:00 2001 From: Mygod Date: Mon, 9 Dec 2019 21:57:11 +0800 Subject: [PATCH] Fix Wi-Fi QR code with non-ISO chars --- mobile/build.gradle | 2 +- .../be/mygod/vpnhotspot/util/QRCodeDialog.kt | 39 ++++++++++++++++--- mobile/src/main/res/values/dimen.xml | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/mobile/build.gradle b/mobile/build.gradle index 747311fc..e6b8ee7f 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -88,10 +88,10 @@ dependencies { implementation 'com.android.billingclient:billing:2.0.3' implementation 'com.github.topjohnwu.libsu:core:2.5.1' implementation 'com.google.android.material:material:1.1.0-beta02' + implementation 'com.google.zxing:core:3.4.0' implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.linkedin.dexmaker:dexmaker:2.25.1' implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.1.0' - implementation 'net.glxn.qrgen:android:2.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2-1.3.60' diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/QRCodeDialog.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/QRCodeDialog.kt index 34344c83..71bb2bb9 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/QRCodeDialog.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/QRCodeDialog.kt @@ -1,26 +1,53 @@ package be.mygod.vpnhotspot.util +import android.graphics.Bitmap +import android.graphics.Color import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import android.widget.ImageView +import android.widget.Toast import androidx.core.os.bundleOf import androidx.fragment.app.DialogFragment import be.mygod.vpnhotspot.R -import net.glxn.qrgen.android.QRCode +import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType +import com.google.zxing.MultiFormatWriter +import com.google.zxing.WriterException +import timber.log.Timber +import java.nio.charset.StandardCharsets +/** + * Based on: + * https://android.googlesource.com/platform/packages/apps/Settings/+/0d706f0/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java + * https://android.googlesource.com/platform/packages/apps/Settings/+/8a9ccfd/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java#153 + */ class QRCodeDialog : DialogFragment() { companion object { private const val KEY_ARG = "arg" + private val iso88591 = StandardCharsets.ISO_8859_1.newEncoder() } fun withArg(arg: String) = apply { arguments = bundleOf(KEY_ARG to arg) } private val arg get() = arguments?.getString(KEY_ARG) - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = - ImageView(context).apply { - val size = resources.getDimensionPixelSize(R.dimen.qr_code_size) - layoutParams = ViewGroup.LayoutParams(size, size) - setImageBitmap((QRCode.from(arg).withSize(size, size) as QRCode).bitmap()) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = try { + ImageView(context).apply { + val hints = HashMap() + if (!iso88591.canEncode(arg)) hints[EncodeHintType.CHARACTER_SET] = StandardCharsets.UTF_8.name() + val size = resources.getDimensionPixelSize(R.dimen.qrcode_size) + val qrBits = MultiFormatWriter().encode(arg, BarcodeFormat.QR_CODE, size, size, hints) + val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565) + for (x in 0 until size) for (y in 0 until size) { + bitmap.setPixel(x, y, if (qrBits.get(x, y)) Color.BLACK else Color.WHITE) } + layoutParams = ViewGroup.LayoutParams(size, size) + setImageBitmap(bitmap) + } + } catch (e: WriterException) { + Timber.w(e) + Toast.makeText(context, e.readableMessage, Toast.LENGTH_LONG).show() + dismiss() + null + } } diff --git a/mobile/src/main/res/values/dimen.xml b/mobile/src/main/res/values/dimen.xml index 3a4f06a6..85625e72 100644 --- a/mobile/src/main/res/values/dimen.xml +++ b/mobile/src/main/res/values/dimen.xml @@ -1,5 +1,5 @@ 56dp - 250dp + 264dp