Stop using deprecated API to manage Permissions request from Fragment

This commit is contained in:
Benoit Marty 2020-10-07 10:53:37 +02:00
parent 182158c3af
commit a7f034f500
5 changed files with 90 additions and 139 deletions

View File

@ -22,6 +22,7 @@ import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
@ -105,7 +106,7 @@ fun checkPermissions(permissionsToBeGrantedBitMap: Int,
activity: Activity,
requestCode: Int,
@StringRes rationaleMessage: Int = 0): Boolean {
return checkPermissions(permissionsToBeGrantedBitMap, activity, null, requestCode, rationaleMessage)
return checkPermissions(permissionsToBeGrantedBitMap, activity, null, null, requestCode, rationaleMessage)
}
/**
@ -117,9 +118,9 @@ fun checkPermissions(permissionsToBeGrantedBitMap: Int,
*/
fun checkPermissions(permissionsToBeGrantedBitMap: Int,
fragment: Fragment,
requestCode: Int,
@StringRes rationaleMessage: Int = 0): Boolean {
return checkPermissions(permissionsToBeGrantedBitMap, fragment.activity, fragment, requestCode, rationaleMessage)
@StringRes rationaleMessage: Int = 0,
allGranted: (Boolean) -> Unit): Boolean {
return checkPermissions(permissionsToBeGrantedBitMap, fragment.activity, fragment, allGranted, 0, rationaleMessage)
}
/**
@ -143,6 +144,7 @@ fun checkPermissions(permissionsToBeGrantedBitMap: Int,
private fun checkPermissions(permissionsToBeGrantedBitMap: Int,
activity: Activity?,
fragment: Fragment?,
allGranted: ((Boolean) -> Unit)?,
requestCode: Int,
@StringRes rationaleMessage: Int
): Boolean {
@ -222,7 +224,10 @@ private fun checkPermissions(permissionsToBeGrantedBitMap: Int,
.setOnCancelListener { Toast.makeText(activity, R.string.missing_permissions_warning, Toast.LENGTH_SHORT).show() }
.setPositiveButton(R.string.ok) { _, _ ->
if (permissionsListToBeGranted.isNotEmpty()) {
fragment?.requestPermissions(permissionsListToBeGranted.toTypedArray(), requestCode)
fragment?.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
allGranted?.invoke(result.keys.all { result[it] == true })
}
?.launch(permissionsListToBeGranted.toTypedArray())
?: run {
ActivityCompat.requestPermissions(activity, permissionsListToBeGranted.toTypedArray(), requestCode)
}
@ -262,7 +267,10 @@ private fun checkPermissions(permissionsToBeGrantedBitMap: Int,
.show()
*/
} else {
fragment?.requestPermissions(permissionsArrayToBeGranted, requestCode)
fragment?.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
allGranted?.invoke(result.keys.all { result[it] == true })
}
?.launch(permissionsArrayToBeGranted)
?: run {
ActivityCompat.requestPermissions(activity, permissionsArrayToBeGranted, requestCode)
}
@ -307,43 +315,6 @@ private fun updatePermissionsToBeGranted(activity: Activity,
return isRequestPermissionRequested
}
/**
* Helper method to process [.PERMISSIONS_FOR_AUDIO_IP_CALL]
* on onRequestPermissionsResult() methods.
*
* @param context App context
* @param grantResults permissions granted results
* @return true if audio IP call is permitted, false otherwise
*/
fun onPermissionResultAudioIpCall(context: Context, grantResults: IntArray): Boolean {
val arePermissionsGranted = allGranted(grantResults)
if (!arePermissionsGranted) {
Toast.makeText(context, R.string.permissions_action_not_performed_missing_permissions, Toast.LENGTH_SHORT).show()
}
return arePermissionsGranted
}
/**
* Helper method to process [.PERMISSIONS_FOR_VIDEO_IP_CALL]
* on onRequestPermissionsResult() methods.
* For video IP calls, record audio and camera permissions are both mandatory.
*
* @param context App context
* @param grantResults permissions granted results
* @return true if video IP call is permitted, false otherwise
*/
fun onPermissionResultVideoIpCall(context: Context, grantResults: IntArray): Boolean {
val arePermissionsGranted = allGranted(grantResults)
if (!arePermissionsGranted) {
Toast.makeText(context, R.string.permissions_action_not_performed_missing_permissions, Toast.LENGTH_SHORT).show()
}
return arePermissionsGranted
}
/**
* Return true if all permissions are granted, false if not or if permission request has been cancelled
*/

View File

@ -27,8 +27,6 @@ import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
import im.vector.app.core.utils.allGranted
import im.vector.app.core.utils.checkPermissions
import im.vector.app.features.crypto.verification.VerificationAction
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
@ -76,15 +74,11 @@ class VerificationChooseMethodFragment @Inject constructor(
}
override fun openCamera() {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this, PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
doOpenQRCodeScanner()
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CODE_LAUNCH_CAMERA && allGranted(grantResults)) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this) { allGranted ->
if (allGranted) {
doOpenQRCodeScanner()
}
}) {
doOpenQRCodeScanner()
}
}

View File

@ -91,18 +91,13 @@ import im.vector.app.core.utils.KeyboardStateUtils
import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL
import im.vector.app.core.utils.PERMISSIONS_FOR_VIDEO_IP_CALL
import im.vector.app.core.utils.PERMISSIONS_FOR_WRITING_FILES
import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_INCOMING_URI
import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_PICK_ATTACHMENT
import im.vector.app.core.utils.TextUtils
import im.vector.app.core.utils.allGranted
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.colorizeMatchingText
import im.vector.app.core.utils.copyToClipboard
import im.vector.app.core.utils.createJSonViewerStyleProvider
import im.vector.app.core.utils.createUIHandler
import im.vector.app.core.utils.isValidUrl
import im.vector.app.core.utils.onPermissionResultAudioIpCall
import im.vector.app.core.utils.onPermissionResultVideoIpCall
import im.vector.app.core.utils.openUrlInExternalBrowser
import im.vector.app.core.utils.saveMedia
import im.vector.app.core.utils.shareMedia
@ -234,11 +229,6 @@ class RoomDetailFragment @Inject constructor(
ActiveCallView.Callback {
companion object {
private const val AUDIO_CALL_PERMISSION_REQUEST_CODE = 1
private const val VIDEO_CALL_PERMISSION_REQUEST_CODE = 2
private const val SAVE_ATTACHEMENT_REQUEST_CODE = 3
/**
* Sanitize the display name.
*
@ -797,15 +787,35 @@ class RoomDetailFragment @Inject constructor(
roomDetailViewModel.pendingAction = startCallAction
if (isVideoCall) {
if (checkPermissions(PERMISSIONS_FOR_VIDEO_IP_CALL,
this, VIDEO_CALL_PERMISSION_REQUEST_CODE,
R.string.permissions_rationale_msg_camera_and_audio)) {
this,
R.string.permissions_rationale_msg_camera_and_audio) { allGranted ->
if (allGranted) {
(roomDetailViewModel.pendingAction as? RoomDetailAction.StartCall)?.let {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(it)
}
} else {
context?.toast(R.string.permissions_action_not_performed_missing_permissions)
cleanUpAfterPermissionNotGranted()
}
}) {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(startCallAction)
}
} else {
if (checkPermissions(PERMISSIONS_FOR_AUDIO_IP_CALL,
this, AUDIO_CALL_PERMISSION_REQUEST_CODE,
R.string.permissions_rationale_msg_record_audio)) {
this,
R.string.permissions_rationale_msg_record_audio) { allGranted ->
if (allGranted) {
(roomDetailViewModel.pendingAction as? RoomDetailAction.StartCall)?.let {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(it)
}
} else {
context?.toast(R.string.permissions_action_not_performed_missing_permissions)
cleanUpAfterPermissionNotGranted()
}
}) {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(startCallAction)
}
@ -1027,7 +1037,17 @@ class RoomDetailFragment @Inject constructor(
override fun onRichContentSelected(contentUri: Uri): Boolean {
// We need WRITE_EXTERNAL permission
return if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this@RoomDetailFragment, PERMISSION_REQUEST_CODE_INCOMING_URI)) {
return if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this@RoomDetailFragment) { allGranted ->
if (allGranted) {
val pendingUri = roomDetailViewModel.pendingUri
if (pendingUri != null) {
roomDetailViewModel.pendingUri = null
sendUri(pendingUri)
}
} else {
cleanUpAfterPermissionNotGranted()
}
}) {
sendUri(contentUri)
} else {
roomDetailViewModel.pendingUri = contentUri
@ -1417,52 +1437,11 @@ class RoomDetailFragment @Inject constructor(
// // }
// }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (allGranted(grantResults)) {
when (requestCode) {
SAVE_ATTACHEMENT_REQUEST_CODE -> {
sharedActionViewModel.pendingAction?.let {
handleActions(it)
sharedActionViewModel.pendingAction = null
}
}
PERMISSION_REQUEST_CODE_INCOMING_URI -> {
val pendingUri = roomDetailViewModel.pendingUri
if (pendingUri != null) {
roomDetailViewModel.pendingUri = null
sendUri(pendingUri)
}
}
PERMISSION_REQUEST_CODE_PICK_ATTACHMENT -> {
val pendingType = attachmentsHelper.pendingType
if (pendingType != null) {
attachmentsHelper.pendingType = null
launchAttachmentProcess(pendingType)
}
}
AUDIO_CALL_PERMISSION_REQUEST_CODE -> {
if (onPermissionResultAudioIpCall(requireContext(), grantResults)) {
(roomDetailViewModel.pendingAction as? RoomDetailAction.StartCall)?.let {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(it)
}
}
}
VIDEO_CALL_PERMISSION_REQUEST_CODE -> {
if (onPermissionResultVideoIpCall(requireContext(), grantResults)) {
(roomDetailViewModel.pendingAction as? RoomDetailAction.StartCall)?.let {
roomDetailViewModel.pendingAction = null
roomDetailViewModel.handle(it)
}
}
}
}
} else {
// Reset all pending data
roomDetailViewModel.pendingAction = null
roomDetailViewModel.pendingUri = null
attachmentsHelper.pendingType = null
}
private fun cleanUpAfterPermissionNotGranted() {
// Reset all pending data
roomDetailViewModel.pendingAction = null
roomDetailViewModel.pendingUri = null
attachmentsHelper.pendingType = null
}
// override fun onAudioMessageClicked(messageAudioContent: MessageAudioContent) {
@ -1579,7 +1558,16 @@ class RoomDetailFragment @Inject constructor(
private fun onSaveActionClicked(action: EventSharedAction.Save) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
&& !checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, SAVE_ATTACHEMENT_REQUEST_CODE)) {
&& !checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this) { allGranted ->
if (allGranted) {
sharedActionViewModel.pendingAction?.let {
handleActions(it)
sharedActionViewModel.pendingAction = null
}
} else {
cleanUpAfterPermissionNotGranted()
}
}) {
sharedActionViewModel.pendingAction = action
return
}
@ -1818,7 +1806,17 @@ class RoomDetailFragment @Inject constructor(
// AttachmentTypeSelectorView.Callback
override fun onTypeSelected(type: AttachmentTypeSelectorView.Type) {
if (checkPermissions(type.permissionsBit, this, PERMISSION_REQUEST_CODE_PICK_ATTACHMENT)) {
if (checkPermissions(type.permissionsBit, this) { allGranted ->
if (allGranted) {
val pendingType = attachmentsHelper.pendingType
if (pendingType != null) {
attachmentsHelper.pendingType = null
launchAttachmentProcess(pendingType)
}
} else {
cleanUpAfterPermissionNotGranted()
}
}) {
launchAttachmentProcess(type)
} else {
attachmentsHelper.pendingType = type

View File

@ -46,8 +46,6 @@ import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
import im.vector.app.core.utils.allGranted
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.copyToClipboard
import im.vector.app.core.utils.startSharePlainTextIntent
@ -288,7 +286,11 @@ class RoomProfileFragment @Inject constructor(
private var avatarCameraUri: Uri? = null
private fun onAvatarTypeSelected(isCamera: Boolean) {
if (isCamera) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this, PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this) { allGranted ->
if (allGranted) {
onAvatarTypeSelected(true)
}
}) {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(this)
}
} else {
@ -331,14 +333,6 @@ class RoomProfileFragment @Inject constructor(
super.onActivityResult(requestCode, resultCode, data)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (allGranted(grantResults)) {
when (requestCode) {
PERMISSION_REQUEST_CODE_LAUNCH_CAMERA -> onAvatarTypeSelected(true)
}
}
}
private fun onAvatarCropped(uri: Uri?) {
if (uri != null) {
roomProfileViewModel.handle(RoomProfileAction.ChangeRoomAvatar(uri, getFilenameFromUri(context, uri)))

View File

@ -48,9 +48,7 @@ import im.vector.app.core.preference.UserAvatarPreference
import im.vector.app.core.preference.VectorPreference
import im.vector.app.core.preference.VectorSwitchPreference
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
import im.vector.app.core.utils.TextUtils
import im.vector.app.core.utils.allGranted
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.getSizeOfFiles
import im.vector.app.core.utils.toast
@ -279,14 +277,6 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
session.integrationManagerService().removeListener(integrationServiceListener)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (allGranted(grantResults)) {
if (requestCode == PERMISSION_REQUEST_CODE_LAUNCH_CAMERA) {
onAvatarTypeSelected(true)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
@ -402,7 +392,11 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
private fun onAvatarTypeSelected(isCamera: Boolean) {
if (isCamera) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this, PERMISSION_REQUEST_CODE_LAUNCH_CAMERA)) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this) { allGranted ->
if (allGranted) {
onAvatarTypeSelected(true)
}
}) {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(this)
}
} else {