Android security has traditionally been evaluated using a relatively simple signal: the device's Security Patch Level (SPL).
That model is becoming less useful as Android moves toward modular system updates, Mainline components, kernel updates, and more granular security fixes.
In September 2026, AndroidX introduced the stable Security State 1.1.0 library together with Security State Provider 1.0.0.
These libraries give security-sensitive Android applications a much richer way to understand the security posture of a device.
This article explains what changed, why it matters, and how Android developers can build applications that make better security decisions.
What is AndroidX Security State?
AndroidX Security State provides APIs for querying security information across different parts of an Android device.
Instead of thinking only about:
Security Patch Level = 2026-09-01
you can reason about several dimensions of the device security state:
Android Device
|
+--------------+--------------+
| | |
System Mainline Kernel
| | |
DSPL DSPL DSPL
| | |
+--------------+--------------+
|
SecurityPatchState
|
+--------------+--------------+
| | |
Updates CVE status Fully updated?
The stable androidx.security:security-state:1.1.0 release provides a unified security-state view, pending-update discovery, CVE verification, and a high-level device-update readiness check.
Source: Android Developers.
Why the old SPL-only approach is not enough
A common Android implementation looks like this:
val securityPatch = Build.VERSION.SECURITY_PATCH
Log.d("Security", "Patch: $securityPatch")
This can be useful, but it does not tell the whole story.
Android devices can receive updates through multiple mechanisms, including:
- Android system updates
- Google Play system / Mainline updates
- OEM updates
- Kernel security updates
- Supplemental security fixes
So this:
SPL = 2026-09-01
doesn't necessarily answer:
"Is this device fully protected against everything that is currently available?"
AndroidX Security State is designed to provide more granular information.
The three security patch concepts
The new security model is easier to understand when you separate three concepts.
1. Device Security Patch Level — DSPL
DSPL represents the security patch level currently installed on the device for a component.
Think:
What protection is installed right now?
2. Published Security Patch Level — PSPL
PSPL represents the latest patch level officially published for a component.
Think:
What is the latest security level that has been published?
3. Available Security Patch Level — ASPL
ASPL represents a security update that is available to the device and ready to be installed.
Think:
Is there a newer security update waiting for this device?
This distinction is extremely useful.
For example:
DSPL = 2026-08
PSPL = 2026-09
ASPL = 2026-09
Your application can now distinguish between:
Installed security state
vs
Published security state
vs
Available security update
What AndroidX Security State 1.1.0 provides
The stable release includes several important APIs.
SecurityPatchState
Provides a unified programmatic view of security patch levels across:
- System
- System modules / Mainline
- Kernel
queryAllAvailableUpdates()
Discovers available updates from registered on-device update providers.
fetchAvailableSecurityPatchLevel()
Aggregates available update information and returns the latest available security patch level.
areCvesPatched()
Allows applications to check whether specific CVEs have been resolved, including relevant vendor supplemental patch information.
isDeviceFullyUpdated()
Provides a high-level check for whether the device has installed all available security patches.
createVulnerabilityReportUrl()
Creates standardized vulnerability-report URLs for security information.
The library supports Kotlin Coroutines / Flow as well as Java ListenableFuture APIs.
Adding the dependency
For an Android application, add the stable Security State dependency:
dependencies {
implementation("androidx.security:security-state:1.1.0")
}
If you are implementing an OEM or privileged OTA/update provider, the companion provider library is:
dependencies {
implementation("androidx.security:security-state-provider:1.0.0")
}
The provider library is a different use case from the normal application-side security-state consumer.
A practical architecture
For a security-sensitive Android application, I would avoid scattering security checks throughout the UI.
Instead:
Android App
|
v
SecurityRepository
|
v
SecurityUseCase
|
v
AndroidX Security State
|
+------------+------------+
| | |
DSPL ASPL CVEs
| | |
+------------+------------+
|
v
SecurityPolicy
|
+----------+----------+
| |
Allow normal Show warning
access / restrict
This keeps the Android security implementation independent from Compose screens.
Repository example
A clean architecture approach could look like:
interface DeviceSecurityRepository {
suspend fun isDeviceFullyUpdated(): Boolean
suspend fun areCvesPatched(
cves: List<String>
): Boolean
}
Then the implementation can encapsulate AndroidX Security State.
class DeviceSecurityRepositoryImpl(
private val securityPatchState: SecurityPatchState
) : DeviceSecurityRepository {
override suspend fun isDeviceFullyUpdated(): Boolean {
return securityPatchState.isDeviceFullyUpdated()
}
override suspend fun areCvesPatched(
cves: List<String>
): Boolean {
return securityPatchState.areCvesPatched(cves)
}
}
API construction details can vary with the exact AndroidX release and integration environment, so check the current API reference before copying the constructor/setup code directly.
The important architectural idea is to keep the library behind your own repository boundary.
UseCase layer
With Clean Architecture:
class CheckDeviceSecurityUseCase(
private val repository: DeviceSecurityRepository
) {
suspend operator fun invoke(): Boolean {
return repository.isDeviceFullyUpdated()
}
}
Now your ViewModel doesn't need to know anything about AndroidX Security State.
ViewModel
class SecurityViewModel(
private val checkDeviceSecurity: CheckDeviceSecurityUseCase
) : ViewModel() {
private val _isSecure = MutableStateFlow<Boolean?>(null)
val isSecure = _isSecure.asStateFlow()
fun checkSecurity() {
viewModelScope.launch {
_isSecure.value = checkDeviceSecurity()
}
}
}
Jetpack Compose UI
The UI can remain extremely simple:
@Composable
fun SecurityScreen(
viewModel: SecurityViewModel
) {
val isSecure by viewModel.isSecure.collectAsState()
when (isSecure) {
null -> {
CircularProgressIndicator()
}
true -> {
Text("Device security is up to date")
}
false -> {
Text("Security updates are available")
}
}
}
Notice what is missing:
SecurityPatchState
Build.VERSION
CVE logic
OEM update logic
None of that belongs inside the Composable.
CVE-aware security decisions
One of the most interesting capabilities is CVE verification.
Imagine a banking application has a policy requiring a specific vulnerability to be patched.
Conceptually:
User opens banking app
|
v
Check device security state
|
v
Are required CVEs patched?
/ \
Yes No
| |
v v
Continue Warning /
restricted flow
For example:
val requiredCves = listOf(
"CVE-2026-XXXX"
)
val secure = repository.areCvesPatched(requiredCves)
This can be much more meaningful than simply checking a date string.
Security policy should be centralized
Don't do this:
if (Build.VERSION.SECURITY_PATCH < "2026-09-01") {
// block user
}
inside five different screens.
Instead:
data class SecurityPolicyResult(
val allowed: Boolean,
val reason: String?
)
and:
class EvaluateSecurityPolicyUseCase(
private val repository: DeviceSecurityRepository
) {
suspend operator fun invoke(): SecurityPolicyResult {
val updated = repository.isDeviceFullyUpdated()
return if (updated) {
SecurityPolicyResult(
allowed = true,
reason = null
)
} else {
SecurityPolicyResult(
allowed = false,
reason = "Security updates are available"
)
}
}
}
Now your business rules are testable.
Don't automatically block every outdated device
This is important.
A security-state API gives you information.
It does not mean every application should immediately refuse access when a device is not fully updated.
Your policy depends on your threat model.
For example:
News application
Outdated device
|
v
Allow access
|
v
Show optional security recommendation
Enterprise application
Outdated device
|
v
Evaluate company policy
|
+----> Allow
|
+----> Restrict sensitive features
Banking / high-security application
Outdated device
|
v
Check required CVEs
|
+----> Patched → Continue
|
+----> Not patched → Step-up / Restrict
Security should be risk-based rather than blindly date-based.
Security State vs Play Integrity
These technologies solve different problems.
| Capability | Security State | Play Integrity |
|---|---|---|
| Security patch state | Yes | Not the primary purpose |
| Available updates | Yes | No |
| CVE verification | Yes | No |
| Device/app integrity signals | No | Yes |
| Licensing / account abuse signals | No | No |
| Security posture | Strong focus | Different focus |
In a high-security application, they can potentially complement each other rather than replace each other.
Security State vs Build.VERSION.SECURITY_PATCH
The old approach:
Build.VERSION.SECURITY_PATCH
is still useful for simple compatibility or display logic.
But for a security policy:
Build.VERSION.SECURITY_PATCH
should not automatically be treated as the complete security posture of the device.
A better architecture is:
Basic compatibility
|
v
Build.VERSION APIs
Security posture
|
v
AndroidX Security State
What about Android 16?
Android 16 also adds several developer-facing security, performance, and system capabilities.
For example, Android 16 introduces system-triggered profiling for important events such as cold-start profiling and ANR-related traces, giving developers better visibility into production performance problems.
It also adds other platform improvements around accessibility, notifications, predictive back, adaptive refresh rate, and job diagnostics.
So Android 16 is not just another API-level bump.
It is increasingly giving developers better tools for understanding how their applications behave on real devices.
A security-aware Android architecture
For a modern Android application, I would structure security-related code like this:
app/
│
├── data/
│ └── security/
│ └── DeviceSecurityRepositoryImpl.kt
│
├── domain/
│ ├── model/
│ │ └── SecurityPolicyResult.kt
│ │
│ ├── repository/
│ │ └── DeviceSecurityRepository.kt
│ │
│ └── usecase/
│ ├── CheckDeviceSecurityUseCase.kt
│ └── EvaluateSecurityPolicyUseCase.kt
│
└── presentation/
└── security/
├── SecurityViewModel.kt
└── SecurityScreen.kt
This is especially useful if you're already following:
MVVM
+
Clean Architecture
+
UseCase
+
Dependency Injection
Testing strategy
Security code should be testable without requiring a real device for every test.
Test your policy separately:
@Test
fun `fully updated device is allowed`() = runTest {
fakeRepository.isFullyUpdated = true
val result = useCase()
assertTrue(result.allowed)
}
And:
@Test
fun `outdated device is restricted`() = runTest {
fakeRepository.isFullyUpdated = false
val result = useCase()
assertFalse(result.allowed)
}
Then keep AndroidX-specific integration tests separate.
This gives you:
Business-rule tests
+
Android integration tests
instead of coupling everything to a physical device.
When should you use AndroidX Security State?
It's particularly interesting for:
- Banking applications
- Fintech applications
- Enterprise apps
- Healthcare applications
- MDM solutions
- Security tools
- Antivirus applications
- Corporate device management
- Apps handling highly sensitive data
For a normal consumer application, you may only need a lightweight security recommendation.
The bigger Android security trend
The interesting part isn't just one new AndroidX library.
The larger trend is:
Old Android security model
Patch Date
↓
Simple decision
Modern Android security model
Device State
↓
Component State
↓
Available Updates
↓
Vulnerability State
↓
Application Threat Model
↓
Security Policy
That is a much better foundation for security-sensitive applications.
Key Takeaways
If you're an Android developer in 2026, these are the important points:
- Don't treat one patch-date string as the complete security posture.
- AndroidX Security State 1.1.0 is now stable.
- DSPL, PSPL, and ASPL provide more granular security information.
- CVE verification enables vulnerability-specific decisions.
isDeviceFullyUpdated()can simplify high-level security checks.- Keep security policy inside your domain layer.
- Don't put security decisions directly inside Compose UI.
- Don't block outdated devices without a clear threat model.
- Combine security signals when your application's risk justifies it.
- Test security policy independently from Android platform APIs.
Final Thoughts
Android security is moving toward a more detailed and actionable model.
Instead of asking:
"What is the device's security patch date?"
developers can increasingly ask:
"What security state is this device actually in, what updates are available, and are the vulnerabilities relevant to my application already patched?"
That shift is important for anyone building security-sensitive Android applications.
For Android developers working with Kotlin, Jetpack Compose, Clean Architecture, and modern security practices, AndroidX Security State is worth adding to your 2026 Android learning roadmap.
Official References
- AndroidX Security State release notes: https://developer.android.com/jetpack/androidx/releases/security
- AndroidX Security State announcement: https://developer.android.com/blog/posts/introducing-the-android-x-security-state-libraries-a-unified-view-of-device-security
- Publish device security state: https://developer.android.com/privacy-and-security/publish-device-security-state
- Android 16 features: https://developer.android.com/about/versions/16/features
- Android developer verification: https://developer.android.com/developer-verification
About the Author
Padmakar Garg is an Android Developer focused on Kotlin, Jetpack Compose, Clean Architecture, mobile security, system design, and open-source Android development.
He enjoys exploring how Android applications work beyond the UI layer — from networking and background processing to encryption, device security, performance, and scalable architecture.
Top comments (0)