[UI/Settings] Add requesting camera permissions to pick image.

This commit is contained in:
Kuba Szczodrzyński 2021-03-25 17:43:43 +01:00
parent a5cbee2b45
commit dd6e536f88
2 changed files with 121 additions and 67 deletions

View File

@ -30,50 +30,62 @@ class MainActivityRequestHandler(val activity: MainActivity) {
private val requestData = mutableMapOf<Int, Any?>() private val requestData = mutableMapOf<Int, Any?>()
private val listeners = mutableMapOf<Int, (data: Any?) -> Unit>() private val listeners = mutableMapOf<Int, (data: Any?) -> Unit>()
private val manager
get() = app.permissionManager
fun requestLogin() = activity.startActivityForResult( fun requestLogin() = activity.startActivityForResult(
Intent(activity, LoginActivity::class.java), Intent(activity, LoginActivity::class.java),
REQUEST_LOGIN_ACTIVITY REQUEST_LOGIN_ACTIVITY
) )
fun requestHeaderBackground(listener: (Any?) -> Unit) { fun requestHeaderBackground(listener: (Any?) -> Unit) =
listeners[REQUEST_FILE_HEADER_BACKGROUND] = listener manager.requestCameraPermission(
activity.startActivityForResult( activity, 0, isRequired = false
CropImage.getPickImageChooserIntent( ) {
activity, listeners[REQUEST_FILE_HEADER_BACKGROUND] = listener
activity.getString(R.string.pick_image_intent_chooser_title), activity.startActivityForResult(
true, CropImage.getPickImageChooserIntent(
true activity,
), activity.getString(R.string.pick_image_intent_chooser_title),
REQUEST_FILE_HEADER_BACKGROUND true,
) true
} ),
REQUEST_FILE_HEADER_BACKGROUND
)
}
fun requestAppBackground(listener: (Any?) -> Unit) { fun requestAppBackground(listener: (Any?) -> Unit) =
listeners[REQUEST_FILE_APP_BACKGROUND] = listener manager.requestCameraPermission(
activity.startActivityForResult( activity, 0, isRequired = false
CropImage.getPickImageChooserIntent( ) {
activity, listeners[REQUEST_FILE_APP_BACKGROUND] = listener
activity.getString(R.string.pick_image_intent_chooser_title), activity.startActivityForResult(
true, CropImage.getPickImageChooserIntent(
true activity,
), activity.getString(R.string.pick_image_intent_chooser_title),
REQUEST_FILE_APP_BACKGROUND true,
) true
} ),
REQUEST_FILE_APP_BACKGROUND
)
}
fun requestProfileImage(profile: Profile, listener: (Any?) -> Unit) { fun requestProfileImage(profile: Profile, listener: (Any?) -> Unit) =
listeners[REQUEST_FILE_PROFILE_IMAGE] = listener manager.requestCameraPermission(
requestData[REQUEST_FILE_PROFILE_IMAGE] = profile activity, 0, isRequired = false
activity.startActivityForResult( ) {
CropImage.getPickImageChooserIntent( listeners[REQUEST_FILE_PROFILE_IMAGE] = listener
activity, requestData[REQUEST_FILE_PROFILE_IMAGE] = profile
activity.getString(R.string.pick_image_intent_chooser_title), activity.startActivityForResult(
true, CropImage.getPickImageChooserIntent(
true activity,
), activity.getString(R.string.pick_image_intent_chooser_title),
REQUEST_FILE_PROFILE_IMAGE true,
) true
} ),
REQUEST_FILE_PROFILE_IMAGE
)
}
private fun getFileInfo(uri: Uri): Pair<String, String?> { private fun getFileInfo(uri: Uri): Pair<String, String?> {
if (uri.scheme == "file") { if (uri.scheme == "file") {
@ -95,8 +107,7 @@ class MainActivityRequestHandler(val activity: MainActivity) {
val mimeType = if (mimeIndex != -1) it.getString(mimeIndex) else null val mimeType = if (mimeIndex != -1) it.getString(mimeIndex) else null
name to mimeType name to mimeType
} } else
else
null null
} ?: "unknown" to null } ?: "unknown" to null
} }
@ -178,7 +189,8 @@ class MainActivityRequestHandler(val activity: MainActivity) {
.getIntent(activity) .getIntent(activity)
activity.startActivityForResult(intent, REQUEST_CROP_PROFILE_IMAGE) activity.startActivityForResult(intent, REQUEST_CROP_PROFILE_IMAGE)
} else { } else {
val profile = requestData.remove(REQUEST_FILE_PROFILE_IMAGE) as? Profile ?: return val profile =
requestData.remove(REQUEST_FILE_PROFILE_IMAGE) as? Profile ?: return
val path = saveFile(uri, "profile${profile.id}") val path = saveFile(uri, "profile${profile.id}")
profile.image = path profile.image = path
listeners.remove(REQUEST_FILE_PROFILE_IMAGE)?.invoke(profile) listeners.remove(REQUEST_FILE_PROFILE_IMAGE)?.invoke(profile)

View File

@ -31,49 +31,91 @@ class PermissionManager(val app: App) : CoroutineScope {
override val coroutineContext: CoroutineContext override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
private fun isStoragePermissionGranted() = if (Build.VERSION.SDK_INT >= 23) { private fun isPermissionGranted(name: String) =
app.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED if (Build.VERSION.SDK_INT >= 23)
} else { app.checkSelfPermission(name) == PackageManager.PERMISSION_GRANTED
true else
true
private fun openPermissionSettings(activity: AppCompatActivity) {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", app.packageName, null)
intent.data = uri
activity.startActivity(intent)
} }
fun requestStoragePermission( private fun requestPermission(
activity: AppCompatActivity, activity: AppCompatActivity,
@StringRes permissionMessage: Int, @StringRes permissionMessage: Int,
onSuccess: suspend CoroutineScope.() -> Unit isRequired: Boolean = true,
permissionName: String,
onSuccess: suspend CoroutineScope.() -> Unit
) { ) {
launch { launch {
if (isStoragePermissionGranted()) { if (isPermissionGranted(permissionName)) {
onSuccess() onSuccess()
return@launch return@launch
} }
val result = activity.awaitAskPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE) val result = activity.awaitAskPermissions(permissionName)
when { when {
result.hasAllGranted() -> onSuccess() result.hasAllGranted() -> onSuccess()
result.hasRational() -> { result.hasRational() -> {
if (!isRequired) {
onSuccess()
return@launch
}
MaterialAlertDialogBuilder(activity) MaterialAlertDialogBuilder(activity)
.setTitle(R.string.permissions_required) .setTitle(R.string.permissions_required)
.setMessage(permissionMessage) .setMessage(permissionMessage)
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
requestStoragePermission(activity, permissionMessage, onSuccess) requestPermission(
} activity,
.setNegativeButton(R.string.cancel, null) permissionMessage,
.show() isRequired,
permissionName,
onSuccess
)
}
.setNegativeButton(R.string.cancel, null)
.show()
} }
result.hasPermanentDenied() -> { result.hasPermanentDenied() -> {
MaterialAlertDialogBuilder(activity) MaterialAlertDialogBuilder(activity)
.setTitle(R.string.permissions_required) .setTitle(R.string.permissions_required)
.setMessage(R.string.permissions_denied) .setMessage(R.string.permissions_denied)
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.ok) { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) openPermissionSettings(activity)
val uri = Uri.fromParts("package", app.packageName, null) }
intent.data = uri .setNegativeButton(R.string.cancel, null)
activity.startActivity(intent) .show()
}
.setNegativeButton(R.string.cancel, null)
.show()
} }
} }
} }
} }
fun requestStoragePermission(
activity: AppCompatActivity,
@StringRes permissionMessage: Int,
isRequired: Boolean = true,
onSuccess: suspend CoroutineScope.() -> Unit
) = requestPermission(
activity,
permissionMessage,
isRequired,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
onSuccess
)
fun requestCameraPermission(
activity: AppCompatActivity,
@StringRes permissionMessage: Int,
isRequired: Boolean = true,
onSuccess: suspend CoroutineScope.() -> Unit
) = requestPermission(
activity,
permissionMessage,
isRequired,
Manifest.permission.CAMERA,
onSuccess
)
} }