Android plugin: integration steps

Build the AccessStamp Gradle plugin from source and apply it to an Android app.

Developer preview, version 0.1.0
Review candidates, not certification. The plugin reports source patterns that may be accessibility issues. Every finding needs a human to confirm or dismiss it. It does not certify compliance with the European Accessibility Act, WCAG or EN 301 549, and it is not a finished paid SDK. It is not published to the Gradle plugin portal. Pilot teams receive the source.

What it does today

  • Adds one Gradle task, accessStamp, to an Android module.
  • Scans XML layouts and Jetpack Compose source for a small set of patterns: image labels, input labels, small touch targets, text size in dp, and declared color contrast.
  • Writes an HTML report and a JSON report, with stable finding IDs, before the check fails the build.
  • Fails only on new unreviewed candidates once you have a baseline.
  • Can run your existing instrumentation task and read its fresh JUnit results as a separate runtime check.

What it does not do

  • It does not resolve styles, themes, includes, Java source, generated code or merged variant resources.
  • It does not crawl screens. Runtime checks cover only the screens your own tests visit.
  • Runtime checks have compiled but have not been run on a device or emulator. No runtime findings are claimed. You need an API 35 device or emulator to try them.
  • It does not upload your source or reports anywhere.

Requirements

  • JDK 17 and an internet connection for Gradle and Maven dependencies.
  • For the Android fixture only: Android SDK platform 35, build tools 34.0.0, and ANDROID_HOME or a local.properties file. The plugin tests and the SDK-free scan-fixture need no SDK.

Step 1: Get the source and build it

cd accessstamp
./gradlew :plugin:test :plugin:jar
./gradlew -p scan-fixture accessStamp

The second command runs the plugin on a small fixture with eight intentionally broken elements. You should see a report in scan-fixture/build/reports/accessstamp/.

Step 2: Include the plugin build in your app

Place the plugin directory outside your app build, for example as a sibling folder named accessstamp. In your app's settings.gradle.kts:

pluginManagement {
    includeBuild("../accessstamp")
    repositories { google(); mavenCentral(); gradlePluginPortal() }
}

Step 3: Apply and configure

In the Android app module's build.gradle.kts:

plugins {
    id("com.android.application")
    id("dev.accessstamp")
}
accessStamp {
    appId = "com.example.app"
    appVersion = "1.2.3"
    variant = "debug"
    journeys = listOf("Sign in", "Checkout")
    notTested = listOf("Password reset", "Screen reader manual review")
}

Values such as variant, the build identity and journey names are metadata you supply. They are recorded in the report as given, not checked. Journey names are an inventory, never proof that a journey was tested.

Step 4: Run it and read the report

./gradlew :app:accessStamp --continue

Open app/build/reports/accessstamp/report.html. The JSON file next to it is for tooling. Use --continue in CI so the report is written even when the task fails. The report lists the scanned source hash, the findings, and a coverage ledger of what was and was not tested.

Step 5: Review and baseline

Fix or review each candidate. If you accept existing debt, record why:

./gradlew :app:accessStampBaseline -PbaselineReason="Reviewed legacy debt, tracked in A11Y-123"

This replaces the baseline with the current findings. It never runs automatically. Review the diff and commit it. Blank reasons and malformed files fail the build. After that, accessStamp fails only on new candidates. Do not baseline without reading what you are accepting.

Optional: runtime checks

If your module already has instrumentation tests, point the plugin at the task:

accessStamp {
    runtimeTasks = listOf("connectedDebugAndroidTest")
}

Your tests must enable the accessibility checks themselves, with Espresso AccessibilityChecks.enable() for Views or enableAccessibilityChecks() for Compose. A passing JUnit result shows that tests ran, not that checks were enabled. Compose checks need API 34 or higher. See the fixture's androidTest folder for compiled examples.

Known limits

  • Finding IDs can change when elements are moved or renamed, or when Compose calls are inserted. Review baseline diffs.
  • The 48dp touch target rule is Android guidance, not a WCAG measurement.
  • No coverage figure is reported, by design.

Founding pilot How it works