💻 Coding
Android targetSdk 35 Upgrade Planner: Stepwise 33 to 34 to 35 Hops, Edge to Edge Enforcement and WindowInsets Fixes, Foreground Service Types and the dataSync Timeout, Exported Receiver Flags, and a Play Target API Deadline Checklist
Move an Android app to targetSdk 35 without surprise crashes or broken layouts: the behavior changes you inherit at each API level, a code search list for each one, edge to edge and insets fixes for Views or Compose, foreground service declarations and timeout handling, a test matrix, and a staged Play rollout before the target API deadline.
0Reviews
Prompt
Act as a senior Android engineer who has raised targetSdk on production apps every year, upgrades one API level at a time, and turns each platform behavior change into a code search and a test. Inputs: - Current compileSdk, targetSdk, minSdk, Android Gradle Plugin, Kotlin, and Gradle versions: [BuildVersions] - UI stack: Views with AppCompat or Material, Jetpack Compose, or mixed; any custom toolbars, bottom bars, or full screen screens: [UiStack] - Background work: foreground services and what they do, WorkManager jobs, alarms, broadcast receivers registered in code, BOOT_COMPLETED usage: [BackgroundWork] - Dependencies that touch the platform: push, maps, media, camera, payments, analytics SDKs with versions: [PlatformDeps] - Release process: tracks used, rollout percentages, crash and ANR monitoring: [ReleaseProcess] - Output format: [Format] Generate: 1. A hop plan: if targetSdk is below 34, ship 34 first, then 35. Set compileSdk 35 first with no target change and fix build errors alone. 2. Toolchain floors: AGP, Gradle, and Kotlin versions that support compileSdk 35, with a note to check the AGP release notes for exact minimums. 3. API 34 changes to check if hopping from 33: runtime registered receivers must pass RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED, foreground services must declare a foregroundServiceType and its matching permission, exact alarms are not granted by default to new installs, and implicit intents to non exported components are blocked. For each: a grep pattern and the fix. 4. API 35 changes: edge to edge is enforced, so content draws behind the status and navigation bars. Give the insets fix for UiStack (ViewCompat.setOnApplyWindowInsetsListener and padding for Views, Scaffold or windowInsetsPadding for Compose), and a list of screens to inspect. Also cover the dataSync foreground service time limit with an onTimeout handler or a move to WorkManager, and restrictions on starting certain foreground service types from BOOT_COMPLETED. 5. A table mapping BackgroundWork items to the change that affects them and the fix. 6. A dependency matrix from PlatformDeps: current version, first version tested on API 35 if documented, and blocker yes or no. 7. A test matrix: devices or emulators on API 34 and 35, gesture and three button navigation, light and dark, large font, and a foldable or tablet if supported. 8. Rollout from ReleaseProcess: internal track, closed testing, then staged production percentages with crash and ANR thresholds to pause, and the Play target API deadline to confirm in Play Console. Constraints: - Show exact Gradle and manifest snippets. Mark anything not confirmed in the official behavior changes pages as "check Android 15 behavior changes". No em dashes.
Instructions
Replace every [bracket] with your details before running. Works on ChatGPT, Claude, and Gemini.
Generated Output
This image was generated using the prompt above.

Examples
Example Input
BuildVersions: compileSdk 34, targetSdk 33, minSdk 26, AGP 8.2, Kotlin 1.9.22, Gradle 8.2 UiStack: mostly Views with Material Components, a custom bottom navigation bar, two Compose screens (settings, onboarding) BackgroundWork: one foreground service that uploads photo backups (can run 20 minutes), a receiver registered in code for network changes, AlarmManager setExact for reminders, BOOT_COMPLETED restarts the upload service PlatformDeps: Firebase Messaging 23.4, Google Maps SDK 18.2, CameraX 1.3.1 ReleaseProcess: internal track, then production at 10, 50, 100 percent; Crashlytics Format: hop plan, changes table, snippets, test matrix, rollout
Example Output
1) HOP PLAN
- PR 1: compileSdk 35, targetSdk stays 33. Fix build only.
- Release A: targetSdk 34.
- Release B: targetSdk 35, two weeks later.
2) TOOLCHAIN
Move to a current AGP 8.x that supports compileSdk 35, Gradle to the version that AGP requires, Kotlin 2.0.x. Check the AGP release notes for the exact minimum.
3) API 34 CHANGES (Release A)
| Change | Search | Fix |
| Receiver export flag | registerReceiver( | ContextCompat.registerReceiver(context, receiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED) for the network receiver |
| FGS type required | <service and startForeground | android:foregroundServiceType="dataSync" plus FOREGROUND_SERVICE_DATA_SYNC permission |
| Exact alarms not granted by default | setExact | check canScheduleExactAlarms(); else use setWindow or ask via the settings screen. Reminders are user facing, so request the permission with an explanation |
| Implicit intents | Intent("com. | make internal intents explicit with setPackage or a component |
Manifest:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<service android:name=".backup.UploadService" android:foregroundServiceType="dataSync" android:exported="false" />
4) API 35 CHANGES (Release B)
Edge to edge:
- Views: in each activity, ViewCompat.setOnApplyWindowInsetsListener(root) { v, insets -> val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.updatePadding(top = bars.top, bottom = bars.bottom); insets }
- Custom bottom navigation bar: apply bottom inset padding to the bar itself, not the screen
- Compose screens: use Scaffold contentWindowInsets or Modifier.windowInsetsPadding(WindowInsets.systemBars)
- Inspect: home, photo grid, upload progress, settings, onboarding, any dialog with a bottom button
dataSync timeout:
- The upload can run 20 minutes, but dataSync services now have a daily time limit. Implement onTimeout(startId, fgsType) to stop cleanly, and move long backups to WorkManager with setExpedited or a long running worker
BOOT_COMPLETED:
- Do not start the dataSync service from the boot receiver; enqueue a WorkManager job instead. Check Android 15 behavior changes for the exact list of restricted types
5) BACKGROUND MAP
| Item | Affected by | Fix |
| Upload service | 34 type, 35 timeout, 35 boot rule | type + permission, onTimeout, WorkManager from boot |
| Network receiver | 34 export flag | RECEIVER_NOT_EXPORTED |
| Reminders setExact | 34 exact alarms | permission check and fallback |
6) DEPENDENCIES
| SDK | Now | Action |
| Firebase Messaging | 23.4 | update via the Firebase BoM |
| Maps SDK | 18.2 | update; check release notes for API 35 |
| CameraX | 1.3.1 | update to the current stable 1.4.x |
7) TEST MATRIX
Emulators API 34 and 35, a physical Pixel; gesture and three button navigation; dark mode; font scale 200 percent; airplane mode during upload; reboot during upload.
8) ROLLOUT
Internal track 3 days, then production 10 percent. Pause if crash free users drop below your baseline by 0.5 points or ANRs rise. Confirm the target API deadline in Play Console policy status.