PAYATHON 2026

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 后,建议设置以下限制:

  1. Android 应用使用的 key 应设置为 Android apps 限制,并填写包名和 SHA-1 证书指纹。
  2. API 限制应只包含项目实际使用的 API。
  3. 如果 Nearby Search 由后端调用,应为后端单独创建 key,并采用适合服务端的限制方式。
  4. 不要把未设置任何限制的 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。

备注:内容仅供参考。