QML Application Permissions

Many features of today's devices and operating systems can have significant privacy, security, and performance implications if misused. It's therefore increasingly common for platforms to require explicit consent from the user before accessing these features.

The Qt Qml Core module exposes the Qt C++ Application Permissions functionality to QML via a set of permission types that can be used to check or request permission in a cross platform manner.

BluetoothPermission

Access to the user's Bluetooth peripherals

CalendarPermission

Access to the user's calendar

CameraPermission

Access to the user's camera

ContactsPermission

Access to the user's contacts

LocationPermission

Access to the user's location

MicrophonePermission

Access to the user's microphone

Usage

To check and request a specific permission in your application, include an instance of the appropriate permission type, and set any of its properties if needed:

 CalendarPermission {
     id: calendarPermission
     accessMode: CalendarPermission.ReadWrite
 }

The type can be used to check the current state of the permissions, for example to drive a state based UI:

 states: [
     State {
         name: "waitingForPermission"
         when: calendarPermission.status == Qt.PermissionStatus.Undetermined
         PropertyChanges { target: permissionRequestItem; visible: true }
     },
     State {
         name: "permissionDenied"
         when: calendarPermission.status == Qt.PermissionStatus.Denied
         PropertyChanges { target: permissionDeniedItem; visible: true }
     }
 ]

In the example above, two permission specific items will be overlaid if the permission status is not granted. The request UI could perhaps look like:

 Rectangle {
     id: permissionRequestItem
     anchors.fill: parent
     visible: false

     Text {
         anchors.centerIn: parent
         text: qsTr("We need your permission to access the calendar."
             + "Please tap this screen to request permission.")

     }

     MouseArea {
         anchors.fill: parent
         onClicked: calendarPermission.request()
     }
 }

With a corresponding denied UI:

 Rectangle {
     id: permissionDeniedItem
     anchors.fill: parent
     color: "red"
     visible: false
     Text {
         anchors.centerIn: parent
         text: qsTr("We need your permission to access the calendar,"
             + "but permission was not granted. Please resolve.")
     }
 }

Changing permission properties

The properties of a permission can be changed, even after a request has been initiated by calling `request()`. This will update the status, if it changes a result of the new property values, but will not result in an automatic request using the new set of properties.

For example, if upgrading an already granted calendar permission for access mode Qt.CalendarPermission.ReadOnly to Qt.CalendarPermission.ReadWrite, the platform will respond in one of three ways:

  • By implicitly granting the extended permission, for example because the platform doesn't distinguish between the two access modes, which will result in no state change.
  • By moving the status back to Undetermined, so that the user can be consulted again for access to the now extended permission.
  • By moving the status to Denied, for example if permissions can not be upgraded once initially requested.

All these states should then move the application's UI into the appropriate state, where the user is informed of the new state, with the possibility of requesting the new permission if possible, or reverting to a less extensive permission.

Interaction between permission items

Although the permission state is ultimately tied to the underlying application, each permission item reports its own status independently of all other items, and needs to be independently requested if needed.

For example, requesting calendar access for one item will not update the status of another CalendarPermission item, even if these have the exact same properties.