Compare commits
2 commits
c706b8ab36
...
d490d6f239
Author | SHA1 | Date | |
---|---|---|---|
d490d6f239 | |||
b3546e6c3a |
2 changed files with 37 additions and 30 deletions
|
@ -2,7 +2,9 @@ package im.angry.openeuicc.ui.wizard
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -20,7 +22,9 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
import com.journeyapps.barcodescanner.ScanContract
|
import com.journeyapps.barcodescanner.ScanContract
|
||||||
import com.journeyapps.barcodescanner.ScanOptions
|
import com.journeyapps.barcodescanner.ScanOptions
|
||||||
import im.angry.openeuicc.common.R
|
import im.angry.openeuicc.common.R
|
||||||
import im.angry.openeuicc.util.*
|
import im.angry.openeuicc.util.ActivationCode
|
||||||
|
import im.angry.openeuicc.util.decodeQrFromBitmap
|
||||||
|
import im.angry.openeuicc.util.preferenceRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -28,6 +32,10 @@ import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizardStepFragment() {
|
class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizardStepFragment() {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "DownloadWizardMethodSelectFragment"
|
||||||
|
}
|
||||||
|
|
||||||
data class DownloadMethod(
|
data class DownloadMethod(
|
||||||
val iconRes: Int,
|
val iconRes: Int,
|
||||||
val titleRes: Int,
|
val titleRes: Int,
|
||||||
|
@ -35,34 +43,28 @@ class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizard
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Maybe we should find a better barcode scanner (or an external one?)
|
// TODO: Maybe we should find a better barcode scanner (or an external one?)
|
||||||
private val barcodeScannerLauncher = registerForActivityResult(ScanContract()) { result ->
|
private val barcodeScannerLauncher =
|
||||||
result.contents?.let { content ->
|
registerForActivityResult(ScanContract()) {
|
||||||
processLpaString(content)
|
processLpaString(it.contents ?: return@registerForActivityResult)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private val gallerySelectorLauncher =
|
private val gallerySelectorLauncher =
|
||||||
registerForActivityResult(ActivityResultContracts.GetContent()) { result ->
|
registerForActivityResult(ActivityResultContracts.GetContent()) {
|
||||||
if (result == null) return@registerForActivityResult
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
runCatching {
|
val decoded = onGalleryResult(it ?: return@launch) ?: return@launch
|
||||||
requireContext().contentResolver.openInputStream(result)?.let { input ->
|
withContext(Dispatchers.Main) { processLpaString(decoded) }
|
||||||
val bmp = BitmapFactory.decodeStream(input)
|
|
||||||
input.close()
|
|
||||||
|
|
||||||
decodeQrFromBitmap(bmp)?.let {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
processLpaString(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bmp.recycle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onGalleryResult(result: Uri) = try {
|
||||||
|
requireContext().contentResolver.openInputStream(result)
|
||||||
|
.use(BitmapFactory::decodeStream)
|
||||||
|
.use(::decodeQrFromBitmap)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Failed to decode QR code from gallery", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val downloadMethods = arrayOf(
|
val downloadMethods = arrayOf(
|
||||||
DownloadMethod(R.drawable.ic_scan_black, R.string.download_wizard_method_qr_code) {
|
DownloadMethod(R.drawable.ic_scan_black, R.string.download_wizard_method_qr_code) {
|
||||||
barcodeScannerLauncher.launch(ScanOptions().apply {
|
barcodeScannerLauncher.launch(ScanOptions().apply {
|
||||||
|
@ -189,3 +191,9 @@ class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizard
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T> Bitmap.use(block: Bitmap.() -> T): T = try {
|
||||||
|
block()
|
||||||
|
} finally {
|
||||||
|
recycle()
|
||||||
|
}
|
|
@ -86,13 +86,12 @@ suspend fun connectSEService(context: Context): SEService = suspendCoroutine { c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun decodeQrFromBitmap(bmp: Bitmap): String? =
|
fun decodeQrFromBitmap(bmp: Bitmap): String {
|
||||||
runCatching {
|
val pixels = IntArray(bmp.width * bmp.height)
|
||||||
val pixels = IntArray(bmp.width * bmp.height)
|
bmp.getPixels(pixels, 0, bmp.width, 0, 0, bmp.width, bmp.height)
|
||||||
bmp.getPixels(pixels, 0, bmp.width, 0, 0, bmp.width, bmp.height)
|
|
||||||
|
|
||||||
val luminanceSource = RGBLuminanceSource(bmp.width, bmp.height, pixels)
|
val luminanceSource = RGBLuminanceSource(bmp.width, bmp.height, pixels)
|
||||||
val binaryBmp = BinaryBitmap(HybridBinarizer(luminanceSource))
|
val binaryBmp = BinaryBitmap(HybridBinarizer(luminanceSource))
|
||||||
|
|
||||||
QRCodeReader().decode(binaryBmp).text
|
return QRCodeReader().decode(binaryBmp).text
|
||||||
}.getOrNull()
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue