PAYATHON 2026

使用 findAutocompletePredictions() 是否收费?

支付老李

结论

findAutocompletePredictions() 会产生可计费的 Places API 用量。设置 session token 不会让请求免费。

按照问题中引用的计费分类:

  • 只调用 findAutocompletePredictions(),用户选择结果后没有获取地点详情,对应 Autocomplete without Place Details(Per Session)。
  • 用户选择预测结果后,继续使用同一个 session token 调用地点详情接口,对应 Autocomplete with Place Details(Per Session)。

是否实际扣款,还要看当前账号的价格方案、免费额度、账单抵扣,以及 Google 当时采用的 SKU 规则。具体金额以 Google Maps Platform 控制台和最新价格表为准。

为什么属于 without Place Details

findAutocompletePredictions() 返回地点预测信息,包括:

  • 地点描述文本
  • placeId
  • 匹配范围
  • 地点类型等预测信息

它不会获取完整的地点详情。

下面这行代码只会把多次自动补全请求归入同一个搜索会话:

.setSessionToken(token)

一个会话是否属于 with Place Details,取决于它是否以地点详情请求结束,而不是有没有设置 token。

当前代码只有预测请求,没有后续的地点详情请求,因此应按 Autocomplete without Place Details 理解。

正确管理 session token

一次自动补全会话通常在用户开始输入时创建 token,并在以下任一情况发生时结束:

  • 用户选择某个预测结果,并使用同一个 token 请求地点详情;
  • 用户取消或关闭搜索;
  • 当前搜索流程结束。

多个互不相关的搜索不应长期共用同一个 token。

private var sessionToken: AutocompleteSessionToken? = null

fun queryPlaces(searchText: String) {
    if (sessionToken == null) {
        sessionToken = AutocompleteSessionToken.newInstance()
    }

    val request = FindAutocompletePredictionsRequest.builder()
        .setSessionToken(sessionToken!!)
        .setQuery(searchText)
        .build()

    placesClient.findAutocompletePredictions(request)
        .addOnSuccessListener { response ->
            searchResults = ArrayList(response.autocompletePredictions)
            adapter.notifyDataSetChanged()
        }
        .addOnFailureListener { exception ->
            if (exception is ApiException) {
                Log.e(
                    "searchtext",
                    "Autocomplete failed: ${exception.statusCode}",
                    exception
                )
            }
        }
}

如果用户关闭搜索但没有选择地点,应结束这次会话,并在下次搜索时创建新的 token:

fun cancelPlaceSearch() {
    sessionToken = null
}

如果需要获取 Place Details

用户选择一条预测结果后,可以通过该结果的 placeId 获取地点详情。这个请求要继续使用同一个 token:

fun selectPrediction(prediction: AutocompletePrediction) {
    val token = sessionToken ?: return

    val placeFields = listOf(
        Place.Field.ID,
        Place.Field.NAME,
        Place.Field.ADDRESS
    )

    val request = FetchPlaceRequest.builder(
        prediction.placeId,
        placeFields
    )
        .setSessionToken(token)
        .build()

    placesClient.fetchPlace(request)
        .addOnSuccessListener { response ->
            val place = response.place

            // 本次自动补全会话已经完成
            sessionToken = null
        }
        .addOnFailureListener { exception ->
            Log.e("places", "Place details request failed", exception)

            // 是否立即结束会话,可根据产品交互决定
            sessionToken = null
        }
}

完成以下流程,才算带 Place Details 的自动补全会话:

创建 token
    ↓
一次或多次 findAutocompletePredictions()
    ↓
用户选择预测结果
    ↓
使用同一个 token 调用 fetchPlace()
    ↓
结束会话

注意事项

  1. Session token 不是免费凭证

    它的作用是关联用户一次搜索过程中产生的多次预测请求,供 Google 按会话规则计费。

  2. 不要为每次按键创建新 token

    用户输入一个查询时可能触发多次请求,这些请求应共用同一个 token。

  3. 不要跨搜索复用 token

    用户选中结果、取消搜索或开始新的搜索后,应创建新的 token。

  4. 建议限制请求频率

    可以为输入框增加 debounce,例如等用户停止输入 300~500 毫秒后再调用接口,减少无意义的请求。具体延迟应根据应用的交互体验确定。

  5. 价格和 SKU 名称可能调整

    Google Maps Platform 的计费模型会更新。这里对 with Place Details 和 without Place Details 的判断,基于题目引用的会话计费模型。实际账单以当前官方价格表和 Google Cloud Billing 中显示的 SKU 为准。

备注:内容仅供参考。