Fix Wi-Fi QR code with non-ISO chars
This commit is contained in:
@@ -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'
|
||||||
|
|||||||
@@ -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>()
|
||||||
|
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)
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user