From be31d1b47f80bb399cb57225857e312a05a3f9b3 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 26 Aug 2023 16:28:37 +0200 Subject: [PATCH] Migrate image picker to new Photo Picker With Android 13 the previous photo picker didn't trigger at all anymore. But we can use the new Photo Picker UI as described in [0] to get a new and better photo picker. Some refactoring is necessary to suport that. [0] https://android-developers.googleblog.com/2023/04/photo-picker-everywhere.html --- .../ligi/passandroid/ui/PassEditActivity.kt | 18 +++------- .../passandroid/ui/edit/ImageEditHelper.kt | 35 +++++++++---------- 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/android/src/main/java/org/ligi/passandroid/ui/PassEditActivity.kt b/android/src/main/java/org/ligi/passandroid/ui/PassEditActivity.kt index 8d1ac522e..b3a5aa036 100644 --- a/android/src/main/java/org/ligi/passandroid/ui/PassEditActivity.kt +++ b/android/src/main/java/org/ligi/passandroid/ui/PassEditActivity.kt @@ -33,7 +33,7 @@ class PassEditActivity : AppCompatActivity() { private lateinit var binding: EditBinding private lateinit var currentPass: PassImpl - private val imageEditHelper by lazy { ImageEditHelper(this, passStore) } + private lateinit var imageEditHelper: ImageEditHelper internal val passStore: PassStore by inject() @@ -50,7 +50,7 @@ class PassEditActivity : AppCompatActivity() { when (i) { 0 -> showCategoryPickDialog(this@PassEditActivity, currentPass, refreshCallback) 1 -> showColorPickDialog(this@PassEditActivity, currentPass, refreshCallback) - 2 -> pickWithPermissionCheck(ImageEditHelper.REQ_CODE_PICK_ICON) + 2 -> imageEditHelper.startPick(ImageEditHelper.REQ_CODE_PICK_ICON) } }.show() } @@ -78,22 +78,12 @@ class PassEditActivity : AppCompatActivity() { this@PassEditActivity.currentPass, BarCode(PassBarCodeFormat.QR_CODE, UUID.randomUUID().toString().uppercase(Locale.ROOT))) } - } - private fun pickWithPermissionCheck(requestCode: Int) { - constructPermissionsRequest(Manifest.permission.READ_EXTERNAL_STORAGE) { - imageEditHelper.startPick(requestCode) - }.launch() + imageEditHelper = ImageEditHelper(this, passStore) } val refreshCallback = { refresh(currentPass) } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - imageEditHelper.onActivityResult(requestCode, resultCode, data) - } - private fun refresh(pass: Pass) { val passViewHolder = EditViewHolder(binding.passCard) @@ -118,7 +108,7 @@ class PassEditActivity : AppCompatActivity() { addButton.visibility = if (bitmap == null) View.VISIBLE else View.GONE val listener = View.OnClickListener { - pickWithPermissionCheck(requestCode) + imageEditHelper.startPick(requestCode) } val logoImage = findViewById(logo_img) diff --git a/android/src/main/java/org/ligi/passandroid/ui/edit/ImageEditHelper.kt b/android/src/main/java/org/ligi/passandroid/ui/edit/ImageEditHelper.kt index 46e34ea34..c591713e4 100644 --- a/android/src/main/java/org/ligi/passandroid/ui/edit/ImageEditHelper.kt +++ b/android/src/main/java/org/ligi/passandroid/ui/edit/ImageEditHelper.kt @@ -1,8 +1,10 @@ package org.ligi.passandroid.ui.edit -import android.app.Activity -import android.app.Activity.RESULT_OK -import android.content.Intent +import android.net.Uri +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.PickVisualMediaRequest +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity import org.ligi.kaxt.loadImage import org.ligi.passandroid.model.PassBitmapDefinitions import org.ligi.passandroid.model.PassStore @@ -11,27 +13,24 @@ import org.ligi.passandroid.model.pass.PassImpl import java.io.File import java.io.IOException -class ImageEditHelper(private val context: Activity, private val passStore: PassStore) { +class ImageEditHelper(private val context: AppCompatActivity, private val passStore: PassStore) { - fun startPick(reqCodePickLogo: Int) { - val intent = Intent() - intent.type = "image/*" - intent.action = Intent.ACTION_GET_CONTENT - context.startActivityForResult(Intent.createChooser(intent, "Select Picture"), reqCodePickLogo) + private val pickVisualMedia: ActivityResultLauncher = context.registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri -> + val imageStringByRequestCode = reqCodePickLogo?.let { getImageStringByRequestCode(it) } + if (imageStringByRequestCode != null) { + extractImage(uri, imageStringByRequestCode) + } } - fun onActivityResult(requestCode: Int, resultCode: Int, imageReturnedIntent: Intent?) { + private var reqCodePickLogo: Int? = null - if (resultCode == RESULT_OK && imageReturnedIntent != null) { - val imageStringByRequestCode = getImageStringByRequestCode(requestCode) - if (imageStringByRequestCode != null) { - extractImage(imageReturnedIntent, imageStringByRequestCode) - } - } + fun startPick(reqCodePickLogo: Int) { + this.reqCodePickLogo = reqCodePickLogo + pickVisualMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) } - private fun extractImage(imageReturnedIntent: Intent, name: String) { - val extractedFile = imageReturnedIntent.data?.loadImage(context) + private fun extractImage(imageReturned: Uri?, name: String) { + val extractedFile = imageReturned?.loadImage(context) val pass = passStore.currentPass if (extractedFile != null && pass != null && extractedFile.exists()) { try {