Android 14 is a consolidation release. Fewer flashy user-facing features, more platform hardening around permissions, background work, and app installability. If your app touches alarms, foreground services, or media picking, this is the release where "it still works on 13" stops being good enough. What follows changes call sites, not just settings toggles.
#Predictive back gets real transitions
Android 13 shipped predictive back as an opt-in gesture preview. Android 14 is where the real cross-activity and cross-task animations land, and where more system surfaces participate by default once you opt in. Already set android:enableOnBackInvokedCallback="true" in the manifest and migrated off onBackPressed() to OnBackInvokedCallback? The animated preview comes for free. Apps that haven't migrated keep the old instant back behavior, which will look increasingly out of place as more of the system adopts it.
Use it when: any screen with a meaningful "back" concept — dismissing a details screen, closing a bottom sheet — benefits from the depth/scale preview instead of an abrupt cut.
#Per-app language and grammatical inflection
Per-app language preferences shipped in Android 13. Android 14 adds a Grammatical Inflection API so apps that support gendered language can ask the system for the user's preferred grammatical gender and adjust generated strings accordingly. It's opt-in. Only useful if you're already doing per-string localization work for gendered languages, and most apps outside that space can ignore it.
#Partial access to photos and videos
The photo picker is now backed by a real permission model. Users can grant access to a specific subset of photos and videos instead of all-or-nothing, via the new READ_MEDIA_VISUAL_USER_SELECTED permission.
class MediaViewModel {
fun registerPicker(activity: ComponentActivity, onPicked: (Uri?) -> Unit) {
val picker = activity.registerForActivityResult(
ActivityResultContracts.PickVisualMedia()
) { uri -> onPicked(uri) }
picker.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
}
Use it when: your app only needs to read media the user actively picks. Skip the broad READ_MEDIA_IMAGES/READ_MEDIA_VIDEO permissions entirely if the picker covers your use case — you'll avoid a permission prompt most users are reluctant to grant.
#Foreground service types are mandatory
Every foreground service must now declare a foregroundServiceType in the manifest and pass a matching type when calling startForeground(). Miss that on API 34 and it throws at runtime.
class LocationTrackingService : Service() {
override fun onCreate() {
super.onCreate()
val notification = buildNotification()
ServiceCompat.startForeground(
this,
NOTIFICATION_ID,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
)
}
}
Use it when: you already run a foreground service. There's no opting out. Audit every startForeground() call site before you bump targetSdkVersion.
#Exact alarms are opt-in again
SCHEDULE_EXACT_ALARM is no longer granted automatically at install for apps targeting API 34. The restrictive posture that started for some app categories in Android 13 is now the default everywhere. Check before you schedule.
val alarmManager = context.getSystemService(AlarmManager::class.java)
if (alarmManager.canScheduleExactAlarms()) {
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
triggerAtMillis,
pendingIntent
)
} else {
context.startActivity(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM_PERMISSION))
}
Use it when: alarms drive genuinely time-critical, user-facing behavior — an alarm clock, a calendar reminder. For "roughly around this time" work, WorkManager or inexact alarms avoid the permission entirely.
#Safer implicit intents
Apps targeting API 34 can no longer implicitly launch an internal, non-exported component unless the intent matches an <intent-filter> exactly. That closes a long-standing intent-redirection vector. It also silently breaks any internal launch that relies on implicit extras matching rather than an explicit component, so audit intents that cross package boundaries via reflection or dynamic class loading.
#minSdkVersion enforced at install time
The Package Installer now refuses to install an APK whose minSdkVersion exceeds the device's API level. Previously only app stores checked this, not the platform itself. Side-loading an old APK on too-old a device now fails cleanly instead of installing something broken.
android {
defaultConfig {
minSdk = 26
targetSdk = 34
}
}
#What to adopt first
- Foreground service types and exact alarms are not optional — they're runtime crashes or permission denials the moment you set
targetSdkVersion = 34. Do these first, before anything else on this list. - Photo picker migration pays for itself in permission-grant rates; do it even if you're not raising
targetSdkVersionyet, since the picker is available via AndroidX back to API 21. - Predictive back is cosmetic-only risk — safe to adopt opportunistically per-screen, not an all-or-nothing migration.
- Everything here assumes
targetSdkVersion 34. If yourminSdkis still below 26, most of these checks need runtime guards (Build.VERSION.SDK_INT >=) rather than being unconditional.