简介面向 Android 应用开发者的 SDK Platform 33 离线资源包对应 Android 13 与 API 级别 33主要服务于需要在集成开发环境或命令行中指定平台版本进行构建的开发者可有效解决 SDK 平台缺失、联网下载缓慢或版本不匹配导致的构建失败问题。压缩包共 2000 个文件其中 1974 个 xml 为系统框架资源、属性定义与设备配置22 个 html 为 API 参考页面4 个 txt 为版本说明整体约 60.84MB便于离线归档、快速部署与多机器迁移。已有 855 人学习下载。作为 SDK 的离线平台包放入 platforms 对应目录后即可被 Android Studio 识别供开发者编译、调试与模拟运行确保应用适配 Android 13 的权限模型、界面特性和行为变更。包内框架资源文件还可作为查阅系统配置的离线素材配合文档能更深入理解平台结构、资源类型与开发要求对需要精确控制 targetSdkVersion 或维护旧工程兼容性的团队尤其实用。1. 把 targetSdkVersion 提到 33 那天Android 13 会先给你点颜色看看当你的应用第一次在 Android 13 设备上弹出那个细化后的位置权限弹窗时你会发现旧代码里所有围绕 READ_EXTERNAL_STORAGE 的兼容逻辑几乎全部作废。这不是某个厂商的魔改而是 android-33 这套 SDK 把运行时权限和前台服务类型的规则彻底重写了。这份笔记是我把模拟项目X从 API 31 迁到 android-33 时整理的完整记录覆盖 SDK 目录拆解、命令行安装、Gradle 参数配合、模拟器调试和五个高频翻车现场。适合正在适配 Android 13 的开发者也适合刚拿到 android-33 离线包不知道往哪放的新人。你能按步骤走完也能少踩几个我已经踩过的坑。2. Android SDK 33 到底装了什么目录结构与三条落地路径2.1 platforms/android-33 目录里每个文件都不是摆设先从最常见的离线包说起。一个完整的 android-33 SDK 组件最先打开的就是platforms/android-33目录。这里最关键的文件是android.jar它不是你应用运行时的依赖而是编译期使用的桩文件。我在某公司接手过一个老项目同事直接把android.jar塞进 libs 当普通 jar 用结果编译能过、一运行就NoSuchMethodError这就是没搞懂它本质。android-33 的android.jar里包含的是对外公开的 API 类和方法签名。真正的实现逻辑都在设备系统的 framework 里不会打进你的 APK。所以你在compileSdk 33下调用新 API编译期没问题运行期要看设备系统版本。目录下还有data/res和data/scripts等辅助资源这些是模拟器或系统镜像用的不需要直接动。关键要注意platform目录的版本号必须精确到android-33而不是android-31或android-34。Gradle 依赖compileSdk时会去查找platforms/android-版本号这个确切目录多一个字符、少一个字符都会报错。2.2 三种把 android-33 放进 SDK 目录的路径路径一官方 sdkmanager 命令行安装。我一般是这么操作# 先安装 platform-tools保证 adb 存在 sdkmanager --install platform-tools # 再装 android-33 platform 和匹配的 build-tools sdkmanager --install platforms;android-33 build-tools;33.0.2 # 查看是否装好 sdkmanager --list_installed注意分号是必须的SDK 内部目录名就是用分号分隔的。build-tools版本我建议选33.0.2它修复了 33.0.0 在 Windows 上偶发的路径过长问题。如果你用 Android Studio 自带的 SDK Manager图形界面勾选同一项效果一样但命令行的好处是能直接看到下载目录是否完整。路径二离线包手动放置。很多下载资源是打包好的platforms/android-33目录。拿到以后别解压到桌面也别改文件名。我一般会直接把它放到ANDROID_HOME指向的 SDK 目录下比如~/Library/Android/sdk/platforms/Windows 上默认是%LOCALAPPDATA%\Android\Sdk。放完后必须检查一点目录下要有个android-33文件夹里面必须包含android.jar。如果发给你的人把版本号写成 32但内容又是 33 的那基本是这个包被改过名风险很大。路径三通过 Gradle 自动补齐。如果你在build.gradle里写compileSdk 33而本机没有对应 platform新版 Gradle 会自动下载。但前提是build-tools版本也要匹配否则会卡在 “SDK Build Tools 33.0.0” 缺失这一步。这三条路径的核心共同点Android SDK 是“按目录识别”的不是按注册表识别。目录里的文件结构、版本号都严格依赖官方结构。我见过有人把android.jar单独拿出来改名为android33.jar想塞给 Gradle最后只能得到一个诡异的aapt2 compile failed。2.3 build-tools、platform-tools 和 emulator 各自负责什么为什么安装 android-33 时要求同时安装 build-tools因为build-tools里包含aapt2、zipalign、d8等工具它们负责把资源编译、DEX 打包和 APK 对齐。platform-tools里是adb、fastboot负责设备和模拟器交互。emulator目录则是模拟器本体。组件目录关键文件职责和 android-33 的关系platforms/android-33android.jar、data/res编译期 API 桩与资源compileSdk 指向它build-tools/33.0.2aapt2、d8、zipalign资源打包与 DEX 化版本必须 编译要求platform-toolsadb、fastboot设备通讯版本太老会导致 adb 异常emulatoremulator 可执行文件运行 AVD系统镜像需匹配 API 33很多时候你下载的“android-33 离线包”只包含platformbuild-tools是单独的压缩包别漏掉。没有build-tools你连 APK 都打不出来因为单靠 Gradle 内部默认工具链并不能自动补齐所有版本。2.4 下载中断后怎么判断包是坏的这是血泪经验。我有一次用sdkmanager时网络波动中断再次安装时它直接跳过解压导致platforms/android-33目录里没有android.jar。运行 Gradle 时报Expected file android.jar at ... doesnt exist。解决方法是进入 SDK 目录把platforms/android-33整个文件夹删除然后重新执行sdkmanager --install。半成品别指望它能自愈删干净重来反而是最快的。如果你是从网盘下载的离线包最好检查一层platforms/android-33下应该有android.jar、package.xml、data目录和source.properties。打开source.properties确认Pkg.Revision33。如果版本号符合但目录名是 32那大概率是发包人改错了目录名。这种我遇到过直接把目录名改回android-33即可但前提是android.jar内容没有被替换过。目录名和内部信息不一致时宁可不装。3. 把 android-33 真正用进工程Gradle 参数与命令行实测3.1 compileSdk、targetSdk、buildToolsVersion 的三角关系先解释三个参数的区别。compileSdk只是编译期平台targetSdk决定系统兼容模式buildToolsVersion决定打包工具版本。很多人把compileSdk和targetSdk理解成同一个东西实际差别很大。参数推荐值作用常见误区compileSdk33定义可用的 API 级别写成 targetSdkVersion 33 不够targetSdk33运行时权限与行为变更保持 33 才能触发 Android 13 新特性buildToolsVersion33.0.2打包工具版本过高/过低都会让 Gradle 重新下载Android 13 的行为变更比如通知要运行时权限、媒体权限拆分都取决于targetSdkVersion是否大于等于 33。如果你compileSdk是 33 而targetSdk是 31代码里可以调用 SDK 33 的新 API但系统不会触发新的权限模型。这很容易造成“我用了新 API 但表现还是老的”的错觉。我见过不少项目升级完compileSdk却忘了改targetSdk结果用户反馈没有适配效果最终排查半天才找到根因。另外buildToolsVersion在 Android Studio 新版本里可以省略Gradle 会使用默认版本。但如果你项目里显式指定了就以你指定的为准。显式指定的好处是可复现坏处是版本不对就报错。我一般会保持显式指定方便多个终端统一。3.2 一个最小可用工程配置样例下面是我在模拟项目 X 里用过的精简配置android { compileSdk 33 buildToolsVersion 33.0.2 defaultConfig { applicationId com.example.demo minSdk 24 targetSdk 33 versionCode 1 versionName 1.0 } }这里compileSdk 33是关键Gradle 会去 SDK 目录查找platforms/android-33。注意我写的是33而不是33新版 AGP 允许整数写法。然后targetSdk 33必须写在defaultConfig里。如果你用了某些第三方依赖它们可能自带targetSdk覆盖那就需要靠 Gradle 的冲突策略强制统一。补充一点如果你在settings.gradle里配置了pluginManagement的repositories确保google()在里面否则自动下载 SDK 和 build-tools 会失败。这个看似废话但很多人复制老项目模板时忘了加导致每次构建都提示“无法解析资源”。3.3 命令行编译流程我不一直开 Android Studio很多适配验证直接在终端跑# 先确认本机 ANDROID_HOME 指向 sdk echo $ANDROID_HOME # 清理旧构建 ./gradlew clean # 编译 debug apk ./gradlew assembleDebug # 如果只需要检查编译期错误 ./gradlew compileDebugJavaWithJavac完成后 APK 在app/build/outputs/apk/debug/app-debug.apk。接着用 adb 装到 Android 13 手机上测试adb install -r app/build/outputs/apk/debug/app-debug.apk注意第一次跑的时候Gradle 会检查compileSdk对应 platform 是否齐全。如果之前没装过它会提示Failed to find target with hash string android-33。这时候执行sdkmanager安装或者确认离线包的目录名。这一步最容易翻车因为 Gradle 不会自动定位到你自定义目录以外的路径。如果你把 SDK 放在非默认位置可以在项目根目录的local.properties里指定echo sdk.dir/path/to/your/sdk local.properties注意local.properties是本地文件不应该提交到版本控制。另一个方法是设置ANDROID_HOME环境变量Gradle 优先读这个。我本人习惯用ANDROID_HOME因为命令行脚本可以到处直接用。3.4 AGP 版本与 compileSdk 的匹配AGP 7.4 可以支持compileSdk 33AGP 8.0 以后对 SDK 版本和 JDK 版本都有对应要求。如果你在升级 compileSdk 时遇到compileSdkVersion is not supported大概率是 AGP 版本太低。这时候去build.gradle里升级 AGP 插件版本别只改 compileSdk。我见过有人把 AGP 从 4.2 直接改到 8.1结果 Gradle wrapper 版本跟着崩了一下从适配问题变成构建系统问题。所以升 compileSdk 前先看 AGP 对应的兼容矩阵。4. android-33 适配踩坑记录现象、原因、解决办法4.1 权限相关的坑通知、媒体文件、前台服务坑 1通知完全收不到或通知栏不显示。现象targetSdk升到 33 后应用自己的自定义通知在 Android 13 上不弹但日志里没有错误。原因Android 13 新增POST_NOTIFICATIONS运行时权限targetSdk 33下若未申请系统直接拦截所有通知显示。解决在AndroidManifest.xml中声明权限然后在代码里像申请位置权限那样请求uses-permission android:nameandroid.permission.POST_NOTIFICATIONS /val notificationPermission if (Build.VERSION.SDK_INT 33) { Manifest.permission.POST_NOTIFICATIONS } else return requestPermissionLauncher.launch(notificationPermission)注意requestPermissionLauncher是 Activity 里注册的ActivityResultLauncher。还有一个细节如果你在 targetSdk 32 时用NotificationChannel还能显示升到 33 后 channel 是否生效取决于权限申请的结果。所以要先申请权限再发通知顺序别反。坑 2读取媒体文件的旧权限失效。现象targetSdk 33继续用READ_EXTERNAL_STORAGE读图片库结果返回空列表。原因Android 13 把存储权限拆成了READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO旧权限在 targetSdk 33 下不再授权媒体文件。解决根据读取内容分别声明新权限。如果只读图片uses-permission android:nameandroid.permission.READ_MEDIA_IMAGES /代码里按版本判断val permission if (Build.VERSION.SDK_INT 33) { Manifest.permission.READ_MEDIA_IMAGES } else { Manifest.permission.READ_EXTERNAL_STORAGE }这两个权限不能同时申请否则系统弹窗会出现奇怪的重复授权提示。我是在某图像处理 Demo 上踩到的当时把新旧权限都写了授权界面直接卡死。坑 3前台服务启动崩溃报 MissingForegroundServiceTypeException。现象targetSdk 33下启动前台服务时突然抛MissingForegroundServiceTypeException。原因Android 13 要求 targetSdk 33 下必须给 service 指定foregroundServiceType否则系统不认为这是一个合法的前台服务。解决在 Manifest 里给 service 加类型比如定位服务service android:name.LocationService android:foregroundServiceTypelocation /同时启动代码里调startForeground时也要传入一样的类型。注意如果你的服务同时需要相机和麦克风类型可以写成camera|microphone但必须在启动时声明清楚。这类崩溃只在 Android 13 上出现所以很容易在真机适配时被忽略。4.2 构建与工具链的坑build-tools、NDK、模拟器坑 4编译时报Failed to find Build Tools revision 33.0.0。现象Gradle 提示找不到build-tools 33.0.0但你已经装了 33.0.2。原因项目里buildToolsVersion写死了33.0.0而本机只装了 33.0.2版本号不匹配Gradle 不会自动降级。解决要么把buildToolsVersion改成33.0.2要么额外安装 33.0.0。我一般直接改配置少装一个版本省空间。但如果有 native 代码还要检查 NDK 版本因为 NDK 的编译工具链也可能依赖特定 API。当时我把 NDK 从 25 升到 26才解决了undefined reference的问题。坑 5模拟器启动后 adb offline或者直接黑屏。现象AVD 使用 android-33 的系统镜像启动后adb devices显示 offline模拟器界面一直黑屏。原因platform-tools版本太旧和新的 emulator 镜像存在兼容问题或者模拟器里的 GPU 渲染缓存崩溃。解决先更新 platform-tools 到最新然后冷启动模拟器禁用快照emulator -avd your_avd_name -no-snapshot如果还不行删除~/.android/avd/your_avd_name.avd下的快照缓存文件再重新启动。这个坑很费时间因为黑屏不会报错只能抓 logcat 慢慢看。坑 6APK 运行时ClassNotFoundException但编译期一切正常。现象用targetSdk 33打包后在 Android 13 设备上运行某个类找不到但编译和安装都没问题。原因有可能是你引用的类只存在于android.jar的 stub 中运行时设备系统没有对应实现也就是用了隐藏 API也可能是 R8 混淆把本来需要的类剥离了。解决先用adb shell dumpsys package确认设备系统 SDK 版本再检查代码里是否使用了非公开 API。如果是隐藏 API改成反射或替换成官方支持的方法。R8 导致的就在proguard-rules.pro里加 keep 规则。这个问题和 android-33 本身关系不大但升级 targetSdk 后很多人顺手开了全量混淆结果把问题暴露出来了。5. 不用玄学用三条验证路径确认 android-33 已生效第一看 APK 解包后的 targetSdkVersion。用aapt2从 build-tools 里直接解析~/Android/sdk/build-tools/33.0.2/aapt2 dump badging app-debug.apk | grep -E sdkVersion|targetSdkVersion输出里能看到sdkVersion和targetSdkVersion。注意sdkVersion实际是最低版本targetSdkVersion才是我们要确认的 33。如果这个值还是 31说明 Gradle 配置没改对或者有依赖强行覆盖了 targetSdk。第二确认运行设备的系统版本避免在错误的设备上测试adb shell getprop ro.build.version.sdk adb shell getprop ro.build.version.release如果release不是 13 或更高那 Android 13 的权限新特性就不会表现。我见过有人拿一台 API 30 的设备测试 targetSdk 33 的通知权限结果正常显示转头换个 Android 13 手机就翻车。第三检查最终合并后的 Manifest确认uses-sdk标签里的实际值。Gradle 编译过程中会做多次 AndroidManifest 合并直接看中间产物最可靠cat app/build/intermediates/merged_manifest/debug/processDebugMainManifest/AndroidManifest.xml | grep uses-sdk这里显示的targetSdkVersion是合并完、各个依赖库互相覆盖后的最终值。从那以后我每次拿到新 SDK 或离线包都会先跑一遍aapt2 dump badging确认真正打进 APK 的版本和 Manifest 里的配置一致再上设备做权限冒烟。这个习惯帮我躲过不少“以为改了配置其实缓存没清”的坑希望你也能用上。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?