Android Studio 使用 Autocomplete 和 Google Maps Nearby Places 需
明确结论
使用 Google Places API 的地址自动补全(Autocomplete)和附近地点搜索(Nearby Search),通常需要:
- 创建 Google Cloud 项目;
- 为项目关联有效的 Cloud Billing account;
- 启用所需的 Maps Platform API;
- 使用 API key 调用服务。
关联 billing account 并不等于购买固定订阅,也不会因为“启用结算”就自动产生月费。Google 根据实际调用的 SKU 和请求量计费。如果用量一直在当前适用的免费使用额度内,通常不会产生实际费用;超过免费额度的部分则可能直接计费。
免费额度、SKU 分类和价格可能发生调整,因此不要只参考旧文章中“每月赠送固定金额”之类的说法。提交项目之前,应以 Google Maps Platform 控制台显示的当前价格和额度为准。
为什么仍然要求绑定结算账户
绑定结算账户主要是为了验证项目身份,并确保超出免费额度的请求可以正常结算。即使预计用量很少,Places API 也可能要求项目保持有效的结算状态,否则请求可能返回以下错误:
REQUEST_DENIED
BillingNotEnabledMapError
The provided API key is invalid
Autocomplete、Place Details、Nearby Search 和 Maps SDK for Android 可能分别对应不同的计费 SKU。一次界面操作也可能触发多种请求,因此不能简单地把“搜索一次”理解为只计一次调用。
推荐的配置步骤
先在 Google Cloud Console 中创建一个专门用于课程作业的项目,为它关联 billing account,然后只启用项目实际需要的 API,例如:
Maps SDK for Android
Places API (New)
创建 API key 后,建议设置以下限制:
- Android 应用使用的 key 应设置为 Android apps 限制,并填写包名和 SHA-1 证书指纹。
- API 限制应只包含项目实际使用的 API。
- 如果 Nearby Search 由后端调用,应为后端单独创建 key,并采用适合服务端的限制方式。
- 不要把未设置任何限制的 API key 提交到公开的 GitHub 仓库。
在 Android 项目中,可以通过资源或构建配置注入 key,避免将它直接写入业务代码:
<!-- AndroidManifest.xml -->
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
</application>
具体的 Gradle 注入方式取决于项目使用的 Android Gradle Plugin 版本,但基本原则不变:不要把真实 key 写入公开源码。
Autocomplete 示例
使用 Places SDK for Android 时,需要先初始化 SDK,再配置自动补全组件。下面是 Kotlin 示例。字段名称可能随 SDK 版本变化,请以当前 SDK 文档为准。
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.widget.AutocompleteSupportFragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (!Places.isInitialized()) {
Places.initialize(applicationContext, BuildConfig.MAPS_API_KEY)
}
val autocompleteFragment =
supportFragmentManager.findFragmentById(
R.id.autocomplete_fragment
) as AutocompleteSupportFragment
autocompleteFragment.setPlaceFields(
listOf(
Place.Field.ID,
Place.Field.NAME,
Place.Field.ADDRESS,
Place.Field.LAT_LNG
)
)
}
}
只请求界面确实需要的字段。额外请求 Place Details 字段可能进入不同的计费 SKU,从而增加费用。
Nearby Search 示例
Places API (New) 的 Nearby Search 更适合通过自己的后端调用,以免将可用于 Web Service 请求的 key 暴露在 APK 中:
curl -X POST \
'https://places.googleapis.com/v1/places:searchNearby' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: YOUR_SERVER_API_KEY' \
-H 'X-Goog-FieldMask: places.id,places.displayName,places.location' \
-d '{
"includedTypes": ["restaurant"],
"maxResultCount": 10,
"locationRestriction": {
"circle": {
"center": {
"latitude": 41.3851,
"longitude": 2.1734
},
"radius": 1000.0
}
}
}'
不要随意将 X-Goog-FieldMask 写成 *。只返回需要的字段可以减少数据量,也能避免误请求计费等级更高的字段。
如何避免课程项目产生费用
可以同时采取以下措施:
- 在 Billing 中创建预算并设置邮件告警;
- 在 APIs & Services 中降低每日请求配额;
- 为不同用途分别创建 API key,并设置相应限制;
- 开发时避免因页面刷新、地图拖动或输入框变化而重复发送请求;
- 按照当前官方规则为 Autocomplete 正确使用 session token;
- 合理缓存 Nearby Search 结果,同时遵守 Google Maps Platform 的数据存储条款;
- 项目结束后禁用 API、删除 key,或解除项目与结算账户的关联。
预算告警通常只负责通知,不会自动停止服务。要防止调用量意外增长,需要设置 API quota、限制 key,并在代码中进行请求节流。
还需要注意什么
绑定银行卡时,支付机构可能产生小额预授权或验证记录。这不一定是正式的 API 使用费,具体情况取决于银行和结算地区。
普通大学演示项目的访问量较小时,往往可以保持在免费额度内,但无法保证完全不会收费。只要项目仍关联有效的结算账户,超额请求就可能产生费用。提交项目前应先核对当前 SKU 价格,设置较低的配额和预算告警,并在课程结束后及时停用相关 API。
备注:内容仅供参考。
