Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve permission handle flow. #332

Merged
merged 6 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 21 additions & 22 deletions app/src/main/java/me/rosuh/easywatermark/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -65,6 +67,8 @@ class MainActivity : AppCompatActivity() {
private val currentBgColor: Int
get() = ((launchView.parent as? View?)?.background as? ColorDrawable)?.color ?: colorSurface

private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>

private val contentFunList: List<FuncTitleModel> by lazy {
listOf(
FuncTitleModel(
Expand Down Expand Up @@ -227,6 +231,16 @@ class MainActivity : AppCompatActivity() {
registerForActivityResult(PickImageContract()) { uri: Uri? ->
handleActivityResult(REQ_PICK_ICON, listOf(uri))
}
requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
return@registerForActivityResult
}
Toast.makeText(
this,
getString(R.string.request_permission_failed),
Toast.LENGTH_SHORT
).show()
}
}

override fun onNewIntent(intent: Intent?) {
Expand Down Expand Up @@ -427,7 +441,7 @@ class MainActivity : AppCompatActivity() {
}
// pick image button
launchView.ivSelectedPhotoTips.setOnClickListener {
preCheckStoragePermission {
checkReadingPermission(requestPermissionLauncher) {
performFileSearch(REQ_CODE_PICK_IMAGE)
}
}
Expand Down Expand Up @@ -581,7 +595,7 @@ class MainActivity : AppCompatActivity() {
TextContentDisplayFragment.replaceShow(this, launchView.fcFunctionDetail.id)
}
FuncTitleModel.FuncType.Icon -> {
preCheckStoragePermission {
checkReadingPermission(requestPermissionLauncher) {
performFileSearch(REQ_PICK_ICON)
}
}
Expand Down Expand Up @@ -650,7 +664,7 @@ class MainActivity : AppCompatActivity() {
}

R.id.action_pick -> {
preCheckStoragePermission {
checkReadingPermission(requestPermissionLauncher) {
performFileSearch(REQ_CODE_PICK_IMAGE)
}
true
Expand Down Expand Up @@ -698,25 +712,6 @@ class MainActivity : AppCompatActivity() {
}
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQ_CODE_REQ_WRITE_PERMISSION -> {
if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(
this,
getString(R.string.request_permission_failed),
Toast.LENGTH_SHORT
).show()
}
}
}
}

private fun dealWithImage(uri: List<Uri>) {
if (FileUtils.isImage(this.contentResolver, uri.first())) {
viewModel.updateImageList(uri)
Expand Down Expand Up @@ -827,6 +822,10 @@ class MainActivity : AppCompatActivity() {
return ViewInfo.from(launchView.ivPhoto)
}

fun requestPermission(block: () -> Unit) {
checkWritingPermission(requestPermissionLauncher, grant = block)
}

companion object {
private const val REQ_CODE_PICK_IMAGE: Int = 42
const val REQ_CODE_REQ_WRITE_PERMISSION: Int = 43
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
Expand Down Expand Up @@ -48,7 +49,7 @@ class SaveImageBSDialogFragment : BaseBindBSDFragment<DialogSaveFileBinding>() {
openShare()
} else {
// saving jobs
requireActivity().preCheckStoragePermission {
(activity as? MainActivity)?.requestPermission {
shareViewModel.saveImage(
requireActivity().contentResolver,
(requireContext() as MainActivity).getImageViewInfo(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import android.content.pm.PackageManager
import android.content.res.Configuration
import android.os.Build
import android.util.TypedValue
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
Expand All @@ -18,54 +19,57 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import me.rosuh.cmonet.CMonet
import me.rosuh.easywatermark.R
import me.rosuh.easywatermark.ui.MainActivity

fun Activity.isStoragePermissionGrated(): Boolean {
val readGranted = ContextCompat.checkSelfPermission(
this,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
Manifest.permission.READ_EXTERNAL_STORAGE
}
) == PackageManager.PERMISSION_GRANTED

val writeGranted =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED

return readGranted && writeGranted
fun Activity.isStoragePermissionGrated(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}

fun Activity.preCheckStoragePermission(block: () -> Unit) {
if (isStoragePermissionGrated()) {
block.invoke()
fun Activity.checkReadingPermission(
activityResultLauncher: ActivityResultLauncher<String>,
failed: (msg: String) -> Unit = {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
},
grant: () -> Unit,
) {
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
requestPermission()
Manifest.permission.READ_EXTERNAL_STORAGE
}
preCheckStoragePermission(activityResultLauncher, permissions, failed, grant)
}

/**
* 申请权限
*/
fun Activity.requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
MainActivity.REQ_CODE_REQ_WRITE_PERMISSION
)
fun Activity.checkWritingPermission(
activityResultLauncher: ActivityResultLauncher<String>,
failed: (msg: String) -> Unit = {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
},
grant: () -> Unit,
) {
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE),
MainActivity.REQ_CODE_REQ_WRITE_PERMISSION
)
Manifest.permission.WRITE_EXTERNAL_STORAGE
}
preCheckStoragePermission(activityResultLauncher, permissions, failed, grant)
}

fun Activity.preCheckStoragePermission(
activityResultLauncher: ActivityResultLauncher<String>,
permission: String,
failed: (msg: String) -> Unit = {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
},
grant: () -> Unit,
) {
if (isStoragePermissionGrated(permission)) {
grant.invoke()
return
}
kotlin.runCatching {
activityResultLauncher.launch(permission)
}.getOrElse {
failed.invoke(it.message ?: "Unknown error")
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ android.nonFinalResIds=false

majorVersion=2
minorVersion=9
patchVersion=2
patchVersion=3
Loading