Fix Wi-Fi QR code with non-ISO chars

This commit is contained in:
Mygod
2019-12-09 21:57:11 +08:00
parent f63708ec3c
commit 1709ffd8ff
3 changed files with 35 additions and 8 deletions

View File

@@ -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'

View File

@@ -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?) =
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = try {
ImageView(context).apply {
val size = resources.getDimensionPixelSize(R.dimen.qr_code_size)
val hints = HashMap<EncodeHintType, Any>()
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((QRCode.from(arg).withSize(size, size) as QRCode).bitmap())
setImageBitmap(bitmap)
}
} catch (e: WriterException) {
Timber.w(e)
Toast.makeText(context, e.readableMessage, Toast.LENGTH_LONG).show()
dismiss()
null
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="listitem_manage_tether_padding_start">56dp</dimen>
<dimen name="qr_code_size">250dp</dimen>
<dimen name="qrcode_size">264dp</dimen>
</resources>