Commit 09e2948d authored by Mygod's avatar Mygod

Sync QR code generation from AOSP

See also #2348.
parent c0047e95
...@@ -65,9 +65,9 @@ dependencies { ...@@ -65,9 +65,9 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
implementation 'com.google.android.gms:play-services-vision:19.0.0' implementation 'com.google.android.gms:play-services-vision:19.0.0'
implementation 'com.google.firebase:firebase-ads:18.3.0' implementation 'com.google.firebase:firebase-ads:18.3.0'
implementation 'com.google.zxing:core:3.4.0'
implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.1.0' implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.1.0'
implementation 'com.twofortyfouram:android-plugin-api-for-locale:1.0.4' implementation 'com.twofortyfouram:android-plugin-api-for-locale:1.0.4'
implementation 'net.glxn.qrgen:android:2.0'
implementation 'xyz.belvi.mobilevision:barcodescanner:2.0.3' implementation 'xyz.belvi.mobilevision:barcodescanner:2.0.3'
testImplementation "junit:junit:$junitVersion" testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test:runner:$androidTestVersion" androidTestImplementation "androidx.test:runner:$androidTestVersion"
......
...@@ -26,6 +26,8 @@ import android.content.ActivityNotFoundException ...@@ -26,6 +26,8 @@ import android.content.ActivityNotFoundException
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.format.Formatter import android.text.format.Formatter
import android.util.LongSparseArray import android.util.LongSparseArray
...@@ -62,10 +64,13 @@ import com.google.android.gms.ads.VideoOptions ...@@ -62,10 +64,13 @@ import com.google.android.gms.ads.VideoOptions
import com.google.android.gms.ads.formats.NativeAdOptions import com.google.android.gms.ads.formats.NativeAdOptions
import com.google.android.gms.ads.formats.UnifiedNativeAd import com.google.android.gms.ads.formats.UnifiedNativeAd
import com.google.android.gms.ads.formats.UnifiedNativeAdView import com.google.android.gms.ads.formats.UnifiedNativeAdView
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.MultiFormatWriter
import com.google.zxing.WriterException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import net.glxn.qrgen.android.QRCode import java.nio.charset.StandardCharsets
import net.glxn.qrgen.core.exception.QRGenerationException
class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
companion object { companion object {
...@@ -78,6 +83,8 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -78,6 +83,8 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
private const val REQUEST_IMPORT_PROFILES = 1 private const val REQUEST_IMPORT_PROFILES = 1
private const val REQUEST_REPLACE_PROFILES = 3 private const val REQUEST_REPLACE_PROFILES = 3
private const val REQUEST_EXPORT_PROFILES = 2 private const val REQUEST_EXPORT_PROFILES = 2
private val iso88591 = StandardCharsets.ISO_8859_1.newEncoder()
} }
/** /**
...@@ -119,19 +126,30 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -119,19 +126,30 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
arguments = bundleOf(Pair(KEY_URL, url)) arguments = bundleOf(Pair(KEY_URL, url))
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { /**
val image = ImageView(context) * Based on:
image.layoutParams = LinearLayout.LayoutParams(-1, -1) * https://android.googlesource.com/platform/packages/apps/Settings/+/0d706f0/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java
val size = resources.getDimensionPixelSize(R.dimen.qr_code_size) * https://android.googlesource.com/platform/packages/apps/Settings/+/8a9ccfd/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java#153
val qrcode = QRCode.from(arguments?.getString(KEY_URL)!!).withSize(size, size) as QRCode */
try { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = try {
image.setImageBitmap(qrcode.bitmap()) val url = arguments?.getString(KEY_URL)!!
} catch (e: QRGenerationException) { val size = resources.getDimensionPixelSize(R.dimen.qrcode_size)
val hints = mutableMapOf<EncodeHintType, Any>()
if (!iso88591.canEncode(url)) hints[EncodeHintType.CHARACTER_SET] = StandardCharsets.UTF_8.name()
val qrBits = MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, size, size, hints)
ImageView(context).apply {
layoutParams = ViewGroup.LayoutParams(size, size)
setImageBitmap(Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565).apply {
for (x in 0 until size) for (y in 0 until size) {
setPixel(x, y, if (qrBits.get(x, y)) Color.BLACK else Color.WHITE)
}
})
}
} catch (e: WriterException) {
Crashlytics.logException(e) Crashlytics.logException(e)
(activity as MainActivity).snackbar().setText(e.cause!!.readableMessage).show() (activity as MainActivity).snackbar().setText(e.readableMessage).show()
dismiss() dismiss()
} null
return image
} }
} }
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<dimen name="qr_code_size">250dp</dimen> <dimen name="qrcode_size">264dp</dimen>
<dimen name="profile_padding">8dp</dimen> <dimen name="profile_padding">8dp</dimen>
<dimen name="main_list_padding_bottom">88dp</dimen> <dimen name="main_list_padding_bottom">88dp</dimen>
<dimen name="bottom_sheet_padding">8dp</dimen> <dimen name="bottom_sheet_padding">8dp</dimen>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment