From 2fb956ce67e4bc27f2133b2f52c2d24c95ca9581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Thu, 31 Aug 2023 15:15:23 +0200 Subject: [PATCH] Add permission check to QRCodeImageDialogFragment - Fix possible NPE on SDK 23-28 --- .../QRCodeImageDialogFragment.kt | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/secuso/privacyfriendlycodescanner/qrscanner/ui/dialogfragments/QRCodeImageDialogFragment.kt b/app/src/main/java/com/secuso/privacyfriendlycodescanner/qrscanner/ui/dialogfragments/QRCodeImageDialogFragment.kt index 42d7a79..c9e6d08 100644 --- a/app/src/main/java/com/secuso/privacyfriendlycodescanner/qrscanner/ui/dialogfragments/QRCodeImageDialogFragment.kt +++ b/app/src/main/java/com/secuso/privacyfriendlycodescanner/qrscanner/ui/dialogfragments/QRCodeImageDialogFragment.kt @@ -1,12 +1,17 @@ package com.secuso.privacyfriendlycodescanner.qrscanner.ui.dialogfragments +import android.Manifest import android.app.Dialog +import android.content.pm.PackageManager import android.graphics.drawable.BitmapDrawable +import android.os.Build import android.os.Bundle import android.widget.Button import android.widget.ImageView import android.widget.ProgressBar import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.content.ContextCompat import androidx.fragment.app.DialogFragment import androidx.lifecycle.ViewModelProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -23,7 +28,7 @@ class QRCodeImageDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { - val builder = MaterialAlertDialogBuilder(context!!) + val builder = MaterialAlertDialogBuilder(requireContext()) val dialogView = it.layoutInflater.inflate(R.layout.dialog_image_view, null) val imageView = dialogView.findViewById(R.id.imageView) val progressBar = dialogView.findViewById(R.id.progressBar) @@ -57,18 +62,38 @@ class QRCodeImageDialogFragment : DialogFragment() { context, (imageView.drawable as BitmapDrawable).bitmap ) - QRGeneratorUtils.saveCachedImageToExternalStorage(context) - Toast.makeText( - context, - R.string.image_stored_in_gallery, - Toast.LENGTH_LONG - ).show() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { + if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + activityResultLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) + } else { + saveImageToStorage() + } + } else { + saveImageToStorage() + } } } return dialog } ?: throw IllegalStateException("Activity cannot be null") } + private val activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> + if (isGranted) { + saveImageToStorage() + } else { + Toast.makeText(context, "storage permission denied", Toast.LENGTH_LONG).show() + } + } + + private fun saveImageToStorage() { + QRGeneratorUtils.saveCachedImageToExternalStorage(context) + Toast.makeText( + context, + R.string.image_stored_in_gallery, + Toast.LENGTH_LONG + ).show() + } + companion object { const val TAG = "QRCodeImageDialog" }