request static method

Future<RPPermissionStatus> request(
  1. RPPermissionType type, {
  2. List<HealthDataType> healthDataTypes = const [],
})

Asks the OS for type and returns the outcome.

If the participant has already granted the permission the OS does not show a dialog and RPPermissionStatus.granted is returned right away.

healthDataTypes is only used for RPPermissionType.health, which is not a single permission — see requestHealthData. Without it that type resolves to RPPermissionStatus.unsupported.

Never throws — a platform without an implementation for the permission resolves to RPPermissionStatus.unknown rather than interrupting the consent flow.

Implementation

static Future<RPPermissionStatus> request(
  RPPermissionType type, {
  List<HealthDataType> healthDataTypes = const [],
}) async {
  if (type == RPPermissionType.health) {
    return await requestHealthData(healthDataTypes);
  }

  // iOS grants background execution through declared background modes.
  if (type == RPPermissionType.ignoreBatteryOptimizations &&
      defaultTargetPlatform != TargetPlatform.android) {
    return RPPermissionStatus.unsupported;
  }

  try {
    // Background location requires the foreground one first, on both
    // platforms.
    if (type == RPPermissionType.locationAlways) {
      final foreground = _statusOf(
        await ph.Permission.locationWhenInUse.request(),
      );
      if (foreground != RPPermissionStatus.granted) return foreground;
    }

    // Android 12 replaced the Bluetooth permission - which is granted
    // without asking - with the "Nearby devices" pair. Asking for both in
    // one call shows a single dialog.
    if (type == RPPermissionType.bluetooth &&
        defaultTargetPlatform == TargetPlatform.android) {
      final statuses = await [
        ph.Permission.bluetoothScan,
        ph.Permission.bluetoothConnect,
      ].request();

      return statuses.values
          .map(_statusOf)
          .firstWhere(
            (status) => status != RPPermissionStatus.granted,
            orElse: () => RPPermissionStatus.granted,
          );
    }

    return _statusOf(await _permissionOf(type).request());
  } catch (error) {
    debugPrint('$RPPermissions - error requesting $type - error: $error');
    return RPPermissionStatus.unknown;
  }
}