mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Fix some misunderstanding about the permissions request - step 2
This commit is contained in:
parent
80657251a5
commit
067349f602
13 changed files with 87 additions and 24 deletions
|
@ -26,6 +26,8 @@ import im.vector.app.R
|
|||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.utils.PERMISSIONS_ALL
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.onPermissionDeniedDialog
|
||||
import im.vector.app.core.utils.onPermissionDeniedSnackbar
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.databinding.ActivityDebugPermissionBinding
|
||||
import timber.log.Timber
|
||||
|
@ -34,6 +36,8 @@ class DebugPermissionActivity : VectorBaseActivity<ActivityDebugPermissionBindin
|
|||
|
||||
override fun getBinding() = ActivityDebugPermissionBinding.inflate(layoutInflater)
|
||||
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
private var lastPermissions = emptyList<String>()
|
||||
|
||||
override fun initUiAndData() {
|
||||
|
@ -67,12 +71,19 @@ class DebugPermissionActivity : VectorBaseActivity<ActivityDebugPermissionBindin
|
|||
}
|
||||
}
|
||||
|
||||
private var dialogOrSnackbar = false
|
||||
|
||||
private val launcher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
Toast.makeText(this, "All granted", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
if (deniedPermanently) {
|
||||
Toast.makeText(this, "Denied forever", Toast.LENGTH_SHORT).show()
|
||||
dialogOrSnackbar = !dialogOrSnackbar
|
||||
if (dialogOrSnackbar) {
|
||||
onPermissionDeniedDialog(R.string.denied_permission_camera)
|
||||
} else {
|
||||
onPermissionDeniedSnackbar(R.string.denied_permission_camera)
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.app.core.extensions.registerStartForActivityResult
|
|||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.onPermissionDeniedDialog
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.features.media.createUCropWithDefaultSettings
|
||||
import im.vector.lib.multipicker.MultiPicker
|
||||
|
@ -55,9 +56,11 @@ class GalleryOrCameraDialogHelper(
|
|||
|
||||
private val listener = fragment as? Listener ?: error("Fragment must implement GalleryOrCameraDialogHelper.Listener")
|
||||
|
||||
private val takePhotoPermissionActivityResultLauncher = fragment.registerForPermissionsResult { allGranted ->
|
||||
private val takePhotoPermissionActivityResultLauncher = fragment.registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
doOpenCamera()
|
||||
} else if (deniedPermanently) {
|
||||
activity.onPermissionDeniedDialog(R.string.denied_permission_camera)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import androidx.annotation.StringRes
|
|||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
|
@ -78,9 +79,22 @@ fun ComponentActivity.registerForPermissionsResult(lambda: (allGranted: Boolean,
|
|||
}
|
||||
}
|
||||
|
||||
fun Fragment.registerForPermissionsResult(allGranted: (Boolean) -> Unit): ActivityResultLauncher<Array<String>> {
|
||||
fun Fragment.registerForPermissionsResult(lambda: (allGranted: Boolean, deniedPermanently: Boolean) -> Unit): ActivityResultLauncher<Array<String>> {
|
||||
return registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
|
||||
allGranted.invoke(result.keys.all { result[it] == true })
|
||||
if (result.keys.all { result[it] == true }) {
|
||||
lambda(true, /* not used */ false)
|
||||
} else {
|
||||
if (permissionDialogDisplayed) {
|
||||
// A permission dialog has been displayed, so even if the user has checked the do not ask again button, we do
|
||||
// not tell the user to open the app settings
|
||||
lambda(false, false)
|
||||
} else {
|
||||
// No dialog has been displayed, so tell the user to go to the system setting
|
||||
lambda(false, true)
|
||||
}
|
||||
}
|
||||
// Reset
|
||||
permissionDialogDisplayed = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,3 +177,14 @@ fun VectorBaseActivity<*>.onPermissionDeniedSnackbar(@StringRes rationaleMessage
|
|||
openAppSettingsPage(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun FragmentActivity.onPermissionDeniedDialog(@StringRes rationaleMessage: Int) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.missing_permissions_title)
|
||||
.setMessage(rationaleMessage)
|
||||
.setPositiveButton(R.string.open_settings) { _, _ ->
|
||||
openAppSettingsPage(this)
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.core.extensions.hideKeyboard
|
|||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.onPermissionDeniedDialog
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.databinding.FragmentQrCodeScannerBinding
|
||||
import im.vector.app.features.userdirectory.PendingSelection
|
||||
|
@ -44,9 +45,11 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen
|
|||
return FragmentQrCodeScannerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
startCamera()
|
||||
} else if (deniedPermanently) {
|
||||
activity?.onPermissionDeniedDialog(R.string.denied_permission_camera)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,12 +23,14 @@ import android.view.ViewGroup
|
|||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.onPermissionDeniedDialog
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationAction
|
||||
|
@ -79,9 +81,11 @@ class VerificationChooseMethodFragment @Inject constructor(
|
|||
state.pendingRequest.invoke()?.transactionId ?: ""))
|
||||
}
|
||||
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
doOpenQRCodeScanner()
|
||||
} else if (deniedPermanently) {
|
||||
activity?.onPermissionDeniedDialog(R.string.denied_permission_camera)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ 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.onPermissionDeniedDialog
|
||||
import im.vector.app.core.utils.openUrlInExternalBrowser
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.core.utils.saveMedia
|
||||
|
@ -1062,14 +1063,16 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private val startCallActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val startCallActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
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)
|
||||
if (deniedPermanently) {
|
||||
activity?.onPermissionDeniedDialog(R.string.denied_permission_generic)
|
||||
}
|
||||
cleanUpAfterPermissionNotGranted()
|
||||
}
|
||||
}
|
||||
|
@ -1738,13 +1741,16 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private val saveActionActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val saveActionActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
sharedActionViewModel.pendingAction?.let {
|
||||
handleActions(it)
|
||||
sharedActionViewModel.pendingAction = null
|
||||
}
|
||||
} else {
|
||||
if (deniedPermanently) {
|
||||
activity?.onPermissionDeniedDialog(R.string.denied_permission_generic)
|
||||
}
|
||||
cleanUpAfterPermissionNotGranted()
|
||||
}
|
||||
}
|
||||
|
@ -1977,7 +1983,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
// AttachmentTypeSelectorView.Callback
|
||||
|
||||
private val typeSelectedActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val typeSelectedActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
val pendingType = attachmentsHelper.pendingType
|
||||
if (pendingType != null) {
|
||||
|
@ -1985,6 +1991,9 @@ class RoomDetailFragment @Inject constructor(
|
|||
launchAttachmentProcess(pendingType)
|
||||
}
|
||||
} else {
|
||||
if (deniedPermanently) {
|
||||
activity?.onPermissionDeniedDialog(R.string.denied_permission_generic)
|
||||
}
|
||||
cleanUpAfterPermissionNotGranted()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class ScanUserCodeFragment @Inject constructor()
|
|||
}
|
||||
}
|
||||
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted, _ ->
|
||||
if (allGranted) {
|
||||
startCamera()
|
||||
} else {
|
||||
|
|
|
@ -43,11 +43,11 @@ class ShowUserCodeFragment @Inject constructor(
|
|||
|
||||
val sharedViewModel: UserCodeSharedViewModel by activityViewModel()
|
||||
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
doOpenQRCodeScanner()
|
||||
} else {
|
||||
sharedViewModel.handle(UserCodeActions.CameraPermissionNotGranted)
|
||||
sharedViewModel.handle(UserCodeActions.CameraPermissionNotGranted(deniedPermanently))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,6 @@ sealed class UserCodeActions : VectorViewModelAction {
|
|||
data class SwitchMode(val mode: UserCodeState.Mode) : UserCodeActions()
|
||||
data class DecodedQRCode(val code: String) : UserCodeActions()
|
||||
data class StartChattingWithUser(val matrixItem: MatrixItem) : UserCodeActions()
|
||||
object CameraPermissionNotGranted : UserCodeActions()
|
||||
data class CameraPermissionNotGranted(val deniedPermanently: Boolean) : UserCodeActions()
|
||||
object ShareByText : UserCodeActions()
|
||||
}
|
||||
|
|
|
@ -86,7 +86,11 @@ class UserCodeActivity : VectorBaseActivity<ActivitySimpleBinding>(),
|
|||
UserCodeShareViewEvents.HideWaitingScreen -> views.simpleActivityWaitingView.isVisible = false
|
||||
is UserCodeShareViewEvents.ToastMessage -> Toast.makeText(this, it.message, Toast.LENGTH_LONG).show()
|
||||
is UserCodeShareViewEvents.NavigateToRoom -> navigator.openRoom(this, it.roomId)
|
||||
UserCodeShareViewEvents.CameraPermissionNotGranted -> onPermissionDeniedSnackbar(R.string.permissions_denied_qr_code)
|
||||
is UserCodeShareViewEvents.CameraPermissionNotGranted -> {
|
||||
if (it.deniedPermanently) {
|
||||
onPermissionDeniedSnackbar(R.string.permissions_denied_qr_code)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,6 @@ sealed class UserCodeShareViewEvents : VectorViewEvents {
|
|||
object HideWaitingScreen : UserCodeShareViewEvents()
|
||||
data class ToastMessage(val message: String) : UserCodeShareViewEvents()
|
||||
data class NavigateToRoom(val roomId: String) : UserCodeShareViewEvents()
|
||||
object CameraPermissionNotGranted : UserCodeShareViewEvents()
|
||||
data class CameraPermissionNotGranted(val deniedPermanently: Boolean) : UserCodeShareViewEvents()
|
||||
data class SharePlainText(val text: String, val title: String, val richPlainText: String) : UserCodeShareViewEvents()
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ class UserCodeSharedViewModel @AssistedInject constructor(
|
|||
is UserCodeActions.SwitchMode -> setState { copy(mode = action.mode) }
|
||||
is UserCodeActions.DecodedQRCode -> handleQrCodeDecoded(action)
|
||||
is UserCodeActions.StartChattingWithUser -> handleStartChatting(action)
|
||||
UserCodeActions.CameraPermissionNotGranted -> _viewEvents.post(UserCodeShareViewEvents.CameraPermissionNotGranted)
|
||||
is UserCodeActions.CameraPermissionNotGranted -> _viewEvents.post(UserCodeShareViewEvents.CameraPermissionNotGranted(action.deniedPermanently))
|
||||
UserCodeActions.ShareByText -> handleShareByText()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -386,12 +386,16 @@
|
|||
<string name="reset">Reset</string>
|
||||
<string name="start_chatting">Start Chatting</string>
|
||||
|
||||
<!-- Permissions denied forever -->
|
||||
<string name="denied_permission_generic">Some permissions are missing to perform this action, please grant the permissions from the system settings.</string>
|
||||
<string name="denied_permission_camera">To perform this action, please grant the Camera permission from the system settings.</string>
|
||||
|
||||
<!-- First param will be replace by the value of ongoing_conference_call_voice, and second one by the value of ongoing_conference_call_video -->
|
||||
<string name="ongoing_conference_call">Ongoing conference call.\nJoin as %1$s or %2$s</string>
|
||||
<string name="ongoing_conference_call_voice">Voice</string>
|
||||
<string name="ongoing_conference_call_video">Video</string>
|
||||
<string name="cannot_start_call">Cannot start the call, please try later</string>
|
||||
<string name="missing_permissions_title">Missing permissions</string>
|
||||
<string name="missing_permissions_warning">"Due to missing permissions, some features may be missing…</string>
|
||||
<string name="missing_permissions_error">"Due to missing permissions, this action is not possible.</string>
|
||||
<string name="missing_permissions_to_start_conf_call">You need permission to invite to start a conference in this room</string>
|
||||
|
|
Loading…
Reference in a new issue