Skillquality 0.45

permissions

27 Android skills for AI agents (Claude Code, Codex, Cursor). Fixes Supabase auth, Hilt errors, design inconsistency, kapt→ksp, missing UiState states. Reduced my token bills 5×. FitGenZ AI shipped in 18 days.

Price
free
Protocol
skill
Verified
no

What it does

Android Runtime Permissions

Rule 1: Always use Accompanist Permissions in Compose

implementation(libs.accompanist.permissions)
// ✅ Single permission
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun CameraScreen() {
    val cameraPermission = rememberPermissionState(Manifest.permission.CAMERA)

    when {
        cameraPermission.status.isGranted -> {
            CameraPreview()
        }
        cameraPermission.status.shouldShowRationale -> {
            PermissionRationale(
                title = "Camera required",
                description = "This feature requires camera access to scan items.",
                onRequest = { cameraPermission.launchPermissionRequest() }
            )
        }
        else -> {
            // First time or permanently denied
            LaunchedEffect(Unit) { cameraPermission.launchPermissionRequest() }
        }
    }
}

// ✅ Multiple permissions
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun LocationScreen() {
    val locationPermissions = rememberMultiplePermissionsState(
        listOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )

    when {
        locationPermissions.allPermissionsGranted -> LocationContent()
        locationPermissions.shouldShowRationale -> PermissionRationale(
            title = "Location required",
            description = "We need your location to show nearby items.",
            onRequest = { locationPermissions.launchMultiplePermissionRequest() }
        )
        else -> LaunchedEffect(Unit) { locationPermissions.launchMultiplePermissionRequest() }
    }
}

Rule 2: Rationale dialog — always explain before requesting

// ✅ Standard permission rationale composable
@Composable
fun PermissionRationale(
    title: String,
    description: String,
    onRequest: () -> Unit,
    onDismiss: () -> Unit = {},
    onOpenSettings: (() -> Unit)? = null
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        icon = { Icon(Icons.Default.Info, contentDescription = null) },
        title = { Text(title) },
        text = { Text(description) },
        confirmButton = {
            TextButton(onClick = onRequest) { Text("Grant permission") }
        },
        dismissButton = {
            if (onOpenSettings != null) {
                TextButton(onClick = onOpenSettings) { Text("Open settings") }
            } else {
                TextButton(onClick = onDismiss) { Text("Not now") }
            }
        }
    )
}

// ✅ Open app settings when permanently denied
fun Context.openAppSettings() {
    startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
        data = Uri.fromParts("package", packageName, null)
    })
}

Rule 3: Declare permissions in AndroidManifest

<!-- Required in AndroidManifest.xml before requesting -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<!-- Storage — Android 13+ uses granular permissions -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Android 12 and below -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />

<!-- Notifications — required for Android 13+ -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<!-- Bluetooth — Android 12+ split permissions -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

Rule 4: Background location — separate request flow

// ✅ Request foreground location first, then background separately
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun BackgroundLocationScreen() {
    val foregroundLocation = rememberMultiplePermissionsState(
        listOf(Manifest.permission.ACCESS_FINE_LOCATION)
    )
    val backgroundLocation = rememberPermissionState(
        Manifest.permission.ACCESS_BACKGROUND_LOCATION
    )

    when {
        !foregroundLocation.allPermissionsGranted -> {
            // Step 1: request foreground first
            RequestForegroundLocation(onRequest = { foregroundLocation.launchMultiplePermissionRequest() })
        }
        !backgroundLocation.status.isGranted -> {
            // Step 2: only after foreground granted
            RequestBackgroundLocation(onRequest = { backgroundLocation.launchPermissionRequest() })
        }
        else -> BackgroundLocationContent()
    }
}

Common Mistakes

❌ Requesting permission without rationale — users deny without explanation ❌ Requesting multiple unrelated permissions at once — request only when needed ❌ Not handling permanently denied state — always offer "Open Settings" option ❌ Requesting background location before foreground — Android rejects this ❌ Missing permission in AndroidManifest — request will always be denied ❌ Requesting WRITE_EXTERNAL_STORAGE on Android 10+ — not needed, use scoped storage

Capabilities

skillsource-piyushverma0skill-permissionstopic-agent-skillstopic-ai-agenttopic-androidtopic-antigravitytopic-claude-codetopic-codextopic-cursortopic-gemini-clitopic-hilttopic-jetpack-composetopic-kotlintopic-material3

Install

Installnpx skills add piyushverma0/android-agent-skills
Transportskills-sh
Protocolskill

Quality

0.45/ 1.00

deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (5,511 chars)

Provenance

Indexed fromgithub
Enriched2026-05-18 19:09:10Z · deterministic:skill-github:v1 · v1
First seen2026-05-18
Last seen2026-05-18

Agent access