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)
}
}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.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
suspendand 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 inMainActivity.onCreate). The SDK owns the request/result plumbing, so do not pass aContextand do not register your ownActivityResultContracts.RequestPermissionfor 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
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.
Returns the current authorization state of the specified permission without presenting a system prompt.
Returns the current authorization state of the specified permission without presenting a system prompt.
Returns the current authorization state of the specified permission without presenting a system prompt.
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.
Opens the per-app Settings page so the user can change individual permission grants for the consumer app (camera, notifications, location authorization, etc.).
Opens the per-app Settings page so the user can change individual permission grants for the consumer app (camera, notifications, location authorization, etc.).
Opens the per-app Settings page so the user can change individual permission grants for the consumer app (camera, notifications, location authorization, etc.).
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.
Call from Activity.onCreate() (or a base activity)
Backwards-compat API: request and ignore status (logs it)
Requests the specified permission.
Requests the specified permission.
Optional: call from Activity.onDestroy() if you want explicit cleanup