Application Permissions¶
Managing 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 permission APIs allow the application to check or request permission for such features in a cross platform manner.
Usage¶
A feature that commonly requires user consent is access to the microphone of the device. An application for recording voice memos would perhaps look something like this initially:
void VoiceMemoWidget::onRecordingInitiated() { m_microphone->startRecording(); }
To ensure this application works well on platforms that require user consent for microphone access we would extend it like this:
void VoiceMemoWidget::onRecordingInitiated() { QMicrophonePermission microphonePermission; switch (qApp->checkPermission(microphonePermission)) { case Qt::PermissionStatus::Undetermined: qApp->requestPermission(microphonePermission, this, &VoiceMemoWidget::onRecordingInitiated); return; case Qt::PermissionStatus::Denied: m_permissionInstructionsDialog->show(); return; case Qt::PermissionStatus::Granted: m_microphone->startRecording(); } }
We first check if we already know the status of the microphone permission. If we don’t we initiate a permission request to determine the current status, which will potentially ask the user for consent. We connect the result of the request to the slot we’re already in, so that we get another chance at evaluating the permission status.
Once the permission status is known, either because we had been granted or denied permission at an earlier time, or after getting the result back from the request we just initiated, we redirect the user to a dialog explaining why we can not record voice memos at this time (if the permission was denied), or proceed to using the microphone (if permission was granted).
Note
On macOS and iOS permissions can currently only be requested for GUI applications.
Declaring Permissions¶
Some platforms require that the permissions you request are declared up front at build time.
Apple platforms¶
Each permission you request must be accompanied by a so called usage description string in the application’s Info.plist
file, describing why the application needs to access the given permission. For example:
<key>NSMicrophoneUsageDescription</key> <string>The microphone is used to record voice memos.</string>
The relevant usage description keys are described in the documentation for each permission type.
To ensure the relevant permission backend is included with your application, please point the build system to your custom Info.plist
.
Android¶
Each permission you request must be accompanied by a uses-permission
entry in the application’s AndroidManifest.xml
file. For example:
<manifest ...> <uses-permission android:name="android.permission.RECORD_AUDIO"/> </manifest>
The relevant permission names are described in the documentation for each permission type.
Available Permissions¶
The following permissions types are available:
Access the camera for taking pictures or videos.
Access the microphone for monitoring or recording sound.
Access Bluetooth peripherals.
Access the user’s location.
Access the user’s contacts.
Access the user’s calendar.
Best Practices¶
To ensure the best possible user experience for the end user we recommend adopting the following best practices for managing application permissions:
Request the minimal set of permissions needed. For example, if you only need access to the microphone, do not request camera permission just in case. Use the properties of individual permission types to limit the permission scope even further, for example
setAccessMode()
to request read only access.Request permissions in response to specific actions by the user. For example, defer requesting microphone permission until the user presses the button to record audio. Associating the permission request to a specific action gives the user a clearer context of why the permission is needed. Do not request all needed permission on startup.
Present extra context and explanation if needed. Sometimes the action by the user is not enough context. Consider presenting an explanation-dialog after the user has initiated the action, but before requesting the permission, so the user is aware of what’s about to happen when the system permission dialog subsequently pops up.
Be transparent and explicit about why permissions are needed. In explanation dialogs and usage descriptions, be transparent about why the particular permission is needed for your application to provide a specific feature, so users can make informed decisions.
Account for denied permissions. The permissions you request may be denied for various reasons. You should always account for this situation, by gracefully degrading the experience of your application, and presenting clear explanations the user about the situation.
Never request permissions from a library. The request of permissions should be done as close as possible to the user, where the information needed to make good decisions on the points above is available. Libraries can check permissions, to ensure they have the prerequisites for doing their work, but if the permission is undetermined or denied this should be reflected through the library’s API, so that the application in turn can request the necessary permissions.
See also