From 7eb721b2316d1390e15a95937d7f0ece15b779c7 Mon Sep 17 00:00:00 2001 From: Abhay Sood Date: Mon, 3 Feb 2025 14:56:18 +0530 Subject: [PATCH] chore(android): handle permissions correctly --- .../measure/android/bugreport/ImageLoader.kt | 2 +- .../android/bugreport/MsrBugReportActivity.kt | 24 +++++++++++++++---- .../sh/measure/android/utils/Permissions.kt | 16 +++++++++++++ android/sample/src/main/AndroidManifest.xml | 2 ++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/android/measure/src/main/java/sh/measure/android/bugreport/ImageLoader.kt b/android/measure/src/main/java/sh/measure/android/bugreport/ImageLoader.kt index 2aac87506..057acf7c3 100644 --- a/android/measure/src/main/java/sh/measure/android/bugreport/ImageLoader.kt +++ b/android/measure/src/main/java/sh/measure/android/bugreport/ImageLoader.kt @@ -106,7 +106,7 @@ internal object ImageLoader { imageView.setImageBitmap(it) onLoadedListener() } - } + }, ) } diff --git a/android/measure/src/main/java/sh/measure/android/bugreport/MsrBugReportActivity.kt b/android/measure/src/main/java/sh/measure/android/bugreport/MsrBugReportActivity.kt index 916348374..68f7a62b2 100644 --- a/android/measure/src/main/java/sh/measure/android/bugreport/MsrBugReportActivity.kt +++ b/android/measure/src/main/java/sh/measure/android/bugreport/MsrBugReportActivity.kt @@ -1,5 +1,8 @@ package sh.measure.android.bugreport +import android.Manifest.permission.READ_EXTERNAL_STORAGE +import android.Manifest.permission.READ_MEDIA_IMAGES +import android.Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED import android.app.Activity import android.content.Context import android.content.Intent @@ -8,6 +11,7 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.text.InputFilter +import android.view.View import android.widget.EditText import android.widget.HorizontalScrollView import android.widget.ImageButton @@ -27,6 +31,7 @@ import sh.measure.android.bugreport.BugReportCollector.Companion.MAX_ATTACHMENTS import sh.measure.android.bugreport.BugReportCollector.Companion.MAX_DESCRIPTION_LENGTH import sh.measure.android.bugreport.BugReportCollector.Companion.PICK_IMAGES_REQUEST import sh.measure.android.bugreport.BugReportCollector.Companion.READ_IMAGES_PERMISSION_REQUEST +import sh.measure.android.utils.isPermissionDeclared internal class MsrBugReportActivity : Activity() { private lateinit var etDescription: EditText @@ -79,8 +84,7 @@ internal class MsrBugReportActivity : Activity() { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { PICK_IMAGES_REQUEST -> { - val selectedUris = - bugReportCollector.onImagePickedResult(this, resultCode, data) + val selectedUris = bugReportCollector.onImagePickedResult(this, resultCode, data) handleSelectedUris(selectedUris) } } @@ -99,7 +103,7 @@ internal class MsrBugReportActivity : Activity() { } else { Toast.makeText( this, - "Unable to open image picker, permission denied", + "Photos access needed to attach screenshots", Toast.LENGTH_LONG, ).show() } @@ -110,6 +114,7 @@ internal class MsrBugReportActivity : Activity() { private fun setupInitialState(savedInstanceState: Bundle?) { bugReportCollector = Measure.getBugReportCollector() maxAttachments = intent.getIntExtra(MAX_ATTACHMENTS_EXTRA, 1) + tvChooseImage.visibility = if (canAccessGalleryImages()) View.VISIBLE else View.GONE if (savedInstanceState == null) { showInitialScreenshot() } else { @@ -188,7 +193,7 @@ internal class MsrBugReportActivity : Activity() { return IntentCompat.getParcelableExtra( intent, INITIAL_SCREENSHOT_EXTRA, - ParcelableAttachment::class.java + ParcelableAttachment::class.java, ) } @@ -292,4 +297,15 @@ internal class MsrBugReportActivity : Activity() { uris.toList(), ) } + + private fun canAccessGalleryImages(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + isPermissionDeclared(this, READ_MEDIA_VISUAL_USER_SELECTED) || + isPermissionDeclared(this, READ_MEDIA_IMAGES) + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + isPermissionDeclared(this, READ_MEDIA_IMAGES) + } else { + isPermissionDeclared(this, READ_EXTERNAL_STORAGE) + } + } } diff --git a/android/measure/src/main/java/sh/measure/android/utils/Permissions.kt b/android/measure/src/main/java/sh/measure/android/utils/Permissions.kt index 6220dfb76..c43d20376 100644 --- a/android/measure/src/main/java/sh/measure/android/utils/Permissions.kt +++ b/android/measure/src/main/java/sh/measure/android/utils/Permissions.kt @@ -1,6 +1,7 @@ package sh.measure.android.utils import android.content.Context +import android.content.pm.PackageManager import androidx.core.content.PermissionChecker internal fun hasPermission(context: Context, permission: String): Boolean { @@ -9,3 +10,18 @@ internal fun hasPermission(context: Context, permission: String): Boolean { permission, ) == PermissionChecker.PERMISSION_GRANTED } + +/** + * Checks if the [permission] is declared in the manifest. + */ +internal fun isPermissionDeclared(context: Context, permission: String): Boolean { + return try { + val packageInfo = context.packageManager.getPackageInfo( + context.packageName, + PackageManager.GET_PERMISSIONS, + ) + packageInfo.requestedPermissions?.contains(permission) ?: false + } catch (e: PackageManager.NameNotFoundException) { + false + } +} diff --git a/android/sample/src/main/AndroidManifest.xml b/android/sample/src/main/AndroidManifest.xml index 42fe3ca7b..70b7435f8 100644 --- a/android/sample/src/main/AndroidManifest.xml +++ b/android/sample/src/main/AndroidManifest.xml @@ -5,6 +5,8 @@ + +