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.android.billingclient:billing:2.0.3'
implementation 'com.github.topjohnwu.libsu:core:2.5.1' implementation 'com.github.topjohnwu.libsu:core:2.5.1'
implementation 'com.google.android.material:material:1.1.0-beta02' 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.jakewharton.timber:timber:4.7.1'
implementation 'com.linkedin.dexmaker:dexmaker:2.25.1' implementation 'com.linkedin.dexmaker:dexmaker:2.25.1'
implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.1.0' 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.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3' implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2-1.3.60' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2-1.3.60'

View File

@@ -1,26 +1,53 @@
package be.mygod.vpnhotspot.util package be.mygod.vpnhotspot.util
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.Toast
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import be.mygod.vpnhotspot.R 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() { class QRCodeDialog : DialogFragment() {
companion object { companion object {
private const val KEY_ARG = "arg" 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) } fun withArg(arg: String) = apply { arguments = bundleOf(KEY_ARG to arg) }
private val arg get() = arguments?.getString(KEY_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 { ImageView(context).apply {
val size = resources.getDimensionPixelSize(R.dimen.qr_code_size) val hints = HashMap<EncodeHintType, Any>()
layoutParams = ViewGroup.LayoutParams(size, size) if (!iso88591.canEncode(arg)) hints[EncodeHintType.CHARACTER_SET] = StandardCharsets.UTF_8.name()
setImageBitmap((QRCode.from(arg).withSize(size, size) as QRCode).bitmap()) 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
}
} }

View File

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