如何在公开仓库中隐藏AndroidManifest里的Google Maps密钥
问题定位与解决方案
1. 检查属性文件加载逻辑是否正确
先确认模块级build.gradle.kts里读取mapskey.properties的代码没有路径或键名错误:
// 加载mapskey.properties文件 val mapsKeyProps = Properties().apply { // 若文件在项目根目录用rootProject.rootDir,在模块根目录用projectDir load(FileInputStream(File(rootProject.rootDir, "mapskey.properties"))) } android { defaultConfig { // 读取文件中的密钥,配置到manifest占位符 val apiKey = mapsKeyProps.getProperty("GOOGLE_MAPS_API_KEY") ?: "" manifestPlaceholders["googleKey"] = apiKey } }
- 核对
mapskey.properties里的键名(比如GOOGLE_MAPS_API_KEY=xxx)和gradle中getProperty的参数完全一致; - 确认文件路径:如果文件放在模块根目录,就把
rootProject.rootDir换成projectDir。
2. 排查manifestPlaceholders无效的核心原因
- 缓存与同步问题:修改gradle后必须执行
Sync Project with Gradle Files,再依次执行Build > Clean Project和Build > Rebuild Project,必要时手动删除项目的build文件夹和.gradle/caches目录,旧缓存会导致占位符未被正确替换; - 密钥为空校验:在gradle中添加日志输出,确认读取到的密钥非空:
val apiKey = mapsKeyProps.getProperty("GOOGLE_MAPS_API_KEY") ?: "" println("Loaded Google Maps Key: $apiKey") manifestPlaceholders["googleKey"] = apiKey
同步gradle后查看控制台输出,若为空则说明属性文件未被正确读取;
- Manifest占位符写法:确认
<meta-data>标签的value属性拼写完全正确:
<meta-data android:name="com.google.android.geo.API_KEY" android:value="${googleKey}" />
3. 为什么单独用resValue会报错?
Google Maps SDK要求Manifest中<meta-data>的密钥必须是直接字符串,而resValue生成的是资源引用(如@string/google_maps_key),SDK不支持通过资源引用读取密钥,因此这种方式本身就不可行,无需尝试。
4. 其他关键排查点
local.properties的特殊处理:若用local.properties存储密钥,需通过project.properties读取,且文件内键名不能有空格:
val apiKey = project.properties["GOOGLE_MAPS_API_KEY"] as? String ?: ""
- 密钥权限验证:即使密钥读取正确,若未配置对应Android应用的SHA-1和包名,地图仍会空白。可在Logcat中搜索
Google Maps关键词,查看是否有密钥验证失败的日志; - 对比BuildConfig逻辑:既然
buildConfigField能正确读取密钥,可对比其与manifestPlaceholders的读取逻辑是否一致,比如:
buildConfigField("String", "GOOGLE_MAPS_KEY", "\"${apiKey}\"")
若BuildConfig中的密钥正确,说明属性文件读取无问题,问题集中在Manifest占位符替换环节。
内容的提问来源于stack exchange,提问作者Tonnie
相关产品推荐
相关产品推荐

