AFPermissions

actual object AFPermissions

Provides functionality for checking and requesting runtime permissions on Android.

This object manages permission requests by associating them with a PermissionHost, which is typically tied to a ComponentActivity.

Important: Before requesting any permissions, you must call AFPermissions.getOrCreateHost(activity) during the onCreate() lifecycle method of your Activity or Fragment to ensure proper handling of permission results.

Sample Usage:

// In your Activity or Fragment's onCreate/onCreateView:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AFPermissions.registerLifecycle(this) // 'this' refers to the ComponentActivity
// ... rest of your onCreate logic
}

// To check if a permission is granted:
lifecycleScope.launch {
if (AFPermissions.isPermissionGranted(Permission.CAMERA)) {
// Camera permission is granted, proceed with camera operations
} else {
// Camera permission is not granted
}
}

// To request a permission:
lifecycleScope.launch {
try {
AFPermissions.requestPermission(Permission.CAMERA)
// The system dialog will be shown to the user.
// You'll typically check the permission status again after this call,
// or rely on the PermissionHost to notify you of the result.
} catch (e: Exception) {
// Handle potential errors, e.g., if getOrCreateHost was not called.
Log.e("Permissions", "Error requesting permission", e)
}
}
actual object AFPermissions

AFPermissions provides functions to check and request permissions on iOS.

This object is the iOS-specific implementation of the AFPermissions expect declaration. It uses the native iOS APIs to interact with the permission system.

Sample Usage (Swift):

Since this Kotlin code is compiled to be used from Swift in a Kotlin Multiplatform Mobile (KMM) project, the way you call it from Swift will involve the generated framework.

import UIKit
import AFCore // Import your shared module

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
checkAndRequestCamera()
checkLocation()
}

func checkAndRequestCamera() {
// AFPermissions functions are suspend functions, so they need to be called
// from a coroutine scope. In Swift, this is often handled by a helper
// or by using libraries that bridge Kotlin coroutines to Swift (e.g., KMP-NativeCoroutines).

// For simplicity, this example uses a basic completion handler approach.
// In a real app, you'd likely use a more robust solution for handling suspend functions.

AFPermissions.shared.isPermissionGranted(permission: Permission.camera) { [weak self] isGranted, error in
guard let self = self else { return }
if let error = error {
print("Error checking camera permission: \(error.localizedDescription)")
return
}

if let isGranted = isGranted?.boolValue, isGranted {
print("Camera permission is already granted.")
// Proceed with camera functionality
} else {
print("Camera permission is not granted. Requesting...")
AFPermissions.shared.requestPermission(permission: Permission.camera) { _, error in
if let error = error {
print("Error requesting camera permission: \(error.localizedDescription)")
return
}
// After this call, the system dialog will be shown to the user.
actual object AFPermissions

Singleton entry point for checking and requesting runtime permissions (camera, location, notifications, physical activity, …).

It uses the expect/actual mechanism to provide platform-specific implementations (Android runtime permissions, iOS authorization APIs).

Platform & threading

  • getPermissionStatus and requestPermission are suspend and must be called from a coroutine; they complete on the platform's permission callback. Invoke them from the main/UI dispatcher so the system prompt is presented correctly.

  • On Android, the system prompt is hosted by the activity registered via AFPermissions.registerLifecycle(activity) (typically in MainActivity.onCreate). The SDK owns the request/result plumbing, so do not pass a Context and do not register your own ActivityResultContracts.RequestPermission for these permissions.

  • On iOS, requests are routed to the relevant system authorization API; see per-permission notes on requestPermission for usage-description-key and "Allow Once" / Reduced Accuracy caveats.

Usage

// Check status first, then request only if needed.
if (AFPermissions.getPermissionStatus(Permission.CAMERA) != PermissionStatus.GRANTED) {
val result = AFPermissions.requestPermission(Permission.CAMERA)
if (result == PermissionStatus.GRANTED) {
startScanner()
}
}

Note: The actual implementation of these methods varies by platform (e.g., Android, iOS).

Functions

Link copied to clipboard

API 28+ uses LocationManager.isLocationEnabled; older releases fall back to Settings.Secure.LOCATION_MODE.

Returns whether the system-level Location Services master switch is on (Settings → Privacy & Security → Location Services on iOS, or Settings → Location on Android). When false, no app on the device can receive location data, regardless of per-app authorization, and geofencing reports com.advantahealth.api.geofencing.model.AFGeofencingStatus.LOCATION_SERVICES_DISABLED.

Returns whether the system-level Location Services master switch is on (Settings → Privacy & Security → Location Services on iOS, or Settings → Location on Android). When false, no app on the device can receive location data, regardless of per-app authorization, and geofencing reports com.advantahealth.api.geofencing.model.AFGeofencingStatus.LOCATION_SERVICES_DISABLED.

Link copied to clipboard
actual suspend fun getPermissionStatus(permission: Permission): PermissionStatus

Returns the current authorization state of the specified permission without presenting a system prompt.

actual suspend fun getPermissionStatus(permission: Permission): PermissionStatus

Returns the current authorization state of the specified permission without presenting a system prompt.

actual suspend fun getPermissionStatus(permission: Permission): PermissionStatus

Returns the current authorization state of the specified permission without presenting a system prompt.

Link copied to clipboard
fun granted(perm: String): Boolean
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
isLocationAccuracyReduced
Link copied to clipboard

Returns true when location is granted at approximate accuracy only — the member granted ACCESS_COARSE_LOCATION but not ACCESS_FINE_LOCATION (the Android 12+ "Approximate" / "Precise location off" choice). Geofencing and automatic visit detection are unreliable in this state.

Returns true when the user has granted location with Reduced Accuracy — i.e. the iOS 14+ "Precise Location" toggle is off.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
actual fun openAppSettings()

Opens the per-app Settings page so the user can change individual permission grants for the consumer app (camera, notifications, location authorization, etc.).

actual fun openAppSettings()

Opens the per-app Settings page so the user can change individual permission grants for the consumer app (camera, notifications, location authorization, etc.).

actual fun openAppSettings()

Opens the per-app Settings page so the user can change individual permission grants for the consumer app (camera, notifications, location authorization, etc.).

Link copied to clipboard

Launches ACTION_LOCATION_SOURCE_SETTINGS, falling back to the general Settings page on devices that strip the intent.

Opens the iOS Settings app at the AFCore consumer's app settings page. iOS exposes no documented deep-link to the system Location Services master switch, so this falls back to the app's settings page.

Opens the platform Settings page where the user can toggle the Location Services master switch.

Link copied to clipboard
Link copied to clipboard
fun openNotificationsSettings(context: Context = AFContextProvider.get())
Link copied to clipboard

Call from Activity.onCreate() (or a base activity)

Link copied to clipboard
actual suspend fun requestPermission(permission: Permission): PermissionStatus

Backwards-compat API: request and ignore status (logs it)

actual suspend fun requestPermission(permission: Permission): PermissionStatus

Requests the specified permission.

actual suspend fun requestPermission(permission: Permission): PermissionStatus

Requests the specified permission.

Link copied to clipboard
Link copied to clipboard

Optional: call from Activity.onDestroy() if you want explicit cleanup