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

View File

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