Google Places AutoComplete API在Instant Apps配置中出现API_NOT_CONNECTED错误 [英] Google Places AutoComplete API gives API_NOT_CONNECTED error in Instant Apps configuration
问题描述
我正在尝试将Google Places AutoComplete API添加到我的Android Instant Apps项目中.
I am trying to add Google Places AutoComplete API to my Android Instant Apps project.
I followed this sample to implement the API.
我的PlacesAdapter
课:
package net.epictimes.uvindex.autocomplete
import android.content.Context
import android.graphics.Typeface
import android.text.style.StyleSpan
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Filter
import android.widget.Filterable
import android.widget.TextView
import com.google.android.gms.common.data.DataBufferUtils
import com.google.android.gms.location.places.AutocompletePrediction
import com.google.android.gms.location.places.GeoDataClient
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.LatLngBounds
import com.google.android.gms.tasks.RuntimeExecutionException
import com.google.android.gms.tasks.Tasks
import timber.log.Timber
import java.util.concurrent.ExecutionException
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
class PlacesAdapter(context: Context, private val geoDataClient: GeoDataClient)
: ArrayAdapter<AutocompletePrediction>(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1), Filterable {
private val resultList = mutableListOf<AutocompletePrediction>()
private val styleBold = StyleSpan(Typeface.BOLD)
override fun getCount(): Int = resultList.size
override fun getItem(position: Int): AutocompletePrediction = resultList[position]
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val row = super.getView(position, convertView, parent)
// Sets the primary and secondary text for a row.
// Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
// styling based on the given CharacterStyle.
val item = getItem(position)
val textView1 = row.findViewById<View>(android.R.id.text1) as TextView
val textView2 = row.findViewById<View>(android.R.id.text2) as TextView
textView1.text = item.getPrimaryText(styleBold)
textView2.text = item.getSecondaryText(styleBold)
return row
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val results = FilterResults()
// We need a separate list to store the results, since
// this is run asynchronously.
var filterData: ArrayList<AutocompletePrediction>? = ArrayList()
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
filterData = getAutocomplete(constraint)
}
results.values = filterData
if (filterData != null) {
results.count = filterData.size
} else {
results.count = 0
}
return results
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
resultList.clear()
resultList.addAll(results.values as ArrayList<AutocompletePrediction>)
}
notifyDataSetChanged()
}
}
}
/**
* Submits an autocomplete query to the Places Geo Data Autocomplete API.
* Results are returned as frozen AutocompletePrediction objects, ready to be cached.
* Returns an empty list if no results were found.
* Returns null if the API client is not available or the query did not complete
* successfully.
* This method MUST be called off the main UI thread, as it will block until data is returned
* from the API, which may include a network request.
*
* @param constraint Autocomplete query string
* @return Results from the autocomplete API or null if the query was not successful.
* @see GeoDataClient.getAutocompletePredictions
* @see AutocompletePrediction.freeze
*/
private fun getAutocomplete(constraint: CharSequence): ArrayList<AutocompletePrediction>? {
Timber.d("Starting autocomplete query for: " + constraint)
val latLngBounds = LatLngBounds(LatLng(-34.041458, 150.790100), LatLng(-33.682247, 151.383362))
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
val results = geoDataClient.getAutocompletePredictions(constraint.toString(), latLngBounds, null)
// This method should have been called off the main UI thread. Block and wait for at most
// 60s for a result from the API.
try {
Tasks.await(results, 60, TimeUnit.SECONDS)
} catch (e: ExecutionException) {
Timber.e(e)
} catch (e: InterruptedException) {
Timber.e(e)
} catch (e: TimeoutException) {
Timber.e(e)
}
Timber.d("Query completed. Received " + results.result.count + " predictions.")
return try {
// Freeze the results immutable representation that can be stored safely.
DataBufferUtils.freezeAndClose<AutocompletePrediction, AutocompletePrediction>(results.result)
} catch (e: RuntimeExecutionException) {
// If the query did not complete successfully return null
Timber.e("Error getting autocomplete prediction API call", e)
null
}
}
}
当我以app
配置运行项目时,工作正常.
When I run the project in app
configuration it works fine.
但是当我在instantapp
配置中运行它时,它会抛出此错误:
But when I run it in instantapp
configuration it throws this:
D/PlacesAdapter: Starting autocomplete query for: is
E/GmsClient: unable to connect to service: com.google.android.gms.location.places.GeoDataApi on com.google.android.gms
E/PlacesAdapter: java.util.concurrent.ExecutionException: com.google.android.gms.common.api.ApiException: 17: API_NOT_CONNECTED
at com.google.android.gms.tasks.Tasks.zzc(Unknown Source:17)
at com.google.android.gms.tasks.Tasks.await(Unknown Source:53)
at net.epictimes.uvindex.autocomplete.PlacesAdapter.getAutocomplete(PlacesAdapter.kt:116)
at net.epictimes.uvindex.autocomplete.PlacesAdapter.access$getAutocomplete(PlacesAdapter.kt:25)
at net.epictimes.uvindex.autocomplete.PlacesAdapter$getFilter$1.performFiltering(PlacesAdapter.kt:64)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: com.google.android.gms.common.api.ApiException: 17: API_NOT_CONNECTED
at com.google.android.gms.common.internal.zzb.zzz(Unknown Source:14)
at com.google.android.gms.common.internal.zzbk.zzaa(Unknown Source:0)
at com.google.android.gms.common.internal.zzbl.zzs(Unknown Source:32)
at com.google.android.gms.common.api.internal.zzs.zzc(Unknown Source:46)
at com.google.android.gms.common.api.internal.zzs.setResult(Unknown Source:42)
at com.google.android.gms.common.api.internal.zzm.zzv(Unknown Source:17)
at com.google.android.gms.common.api.internal.zzc.zzt(Unknown Source:2)
at com.google.android.gms.common.api.internal.zzbr.zzx(Unknown Source:27)
at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source:386)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
W/Filter: An exception occured during performFiltering()!
com.google.android.gms.tasks.RuntimeExecutionException: com.google.android.gms.common.api.ApiException: 17: API_NOT_CONNECTED
at com.google.android.gms.tasks.zzn.getResult(Unknown Source:14)
at net.epictimes.uvindex.autocomplete.PlacesAdapter.getAutocomplete(PlacesAdapter.kt:123)
at net.epictimes.uvindex.autocomplete.PlacesAdapter.access$getAutocomplete(PlacesAdapter.kt:25)
at net.epictimes.uvindex.autocomplete.PlacesAdapter$getFilter$1.performFiltering(PlacesAdapter.kt:64)
at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: com.google.android.gms.common.api.ApiException: 17: API_NOT_CONNECTED
at com.google.android.gms.common.internal.zzb.zzz(Unknown Source:14)
at com.google.android.gms.common.internal.zzbk.zzaa(Unknown Source:0)
at com.google.android.gms.common.internal.zzbl.zzs(Unknown Source:32)
at com.google.android.gms.common.api.internal.zzs.zzc(Unknown Source:46)
at com.google.android.gms.common.api.internal.zzs.setResult(Unknown Source:42)
at com.google.android.gms.common.api.internal.zzm.zzv(Unknown Source:17)
at com.google.android.gms.common.api.internal.zzc.zzt(Unknown Source:2)
at com.google.android.gms.common.api.internal.zzbr.zzx(Unknown Source:27)
at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source:386)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
API_NOT_CONNECTED
错误代码在文档:
客户端尝试从无法调用API的方法中调用方法 连接.可能的原因包括:
The client attempted to call a method from an API that failed to connect. Possible reasons include:
- 该API先前无法连接,并出现可解决的错误,但用户拒绝了该解决方案.
- 该设备不支持GmsCore.
- 特定的API无法在此设备上连接.
- The API previously failed to connect with a resolvable error, but the user declined the resolution.
- The device does not support GmsCore.
- The specific API cannot connect on this device.
我在模拟器上更新了Google Play服务(它是11.7.46(470-175121617)BTW),但没有任何改变.
I updated the Google Play Services on the emulator (it's 11.7.46 (470-175121617) BTW) but it didn't changed anyting.
我将Google Play服务依赖项放入了base
模块中.我检查了合并的清单文件,它们都有Google Play API密钥.
I put my Google Play Services dependencies into the base
module. I checked the merged manifest files, they all have the Google Play API keys.
在 Android开发者网站中他们在受支持的 API列表中列出了Google Places API.
In the Android Developers site they listed Google Places API in the supported API list.
我正在其他功能模块中使用Google Location API,并且在app
和instantapp
配置中都可以使用.
I am using Google Location API in the other feature module and it is working in both app
and instantapp
configurations.
那我在做什么错了?
推荐答案
我决定使用GoogleApiClient连接API:
I decided to connect the API using the GoogleApiClient:
GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Places.GEO_DATA_API)
.build()
.connect()
但是在instantapp
配置中,连接尝试失败,状态码为API_UNAVAILABLE
.
But the connection attempt failed with status code API_UNAVAILABLE
in instantapp
configuration.
在 docs 中,API_UNAVAILABLE
表示该API不适用于Instant Apps:
In the docs, API_UNAVAILABLE
means that the API is not available for Instant Apps:
在调试使用Google Play服务库的即时应用程序时 除了以上列表中包含的内容外,您可能还会看到 调试输出中的API_UNAVAILABLE错误. API_UNAVAILABLE 错误表明该库尚未适应以下用途 Android Instant Apps.
When debugging an instant app that uses a Google Play services library other than those included in the list above, you may see the API_UNAVAILABLE error in your debugging output. The API_UNAVAILABLE error indicates that the library has not been adapted for usage in Android Instant Apps.
因此,我放下了Places AutoComplete,然后继续进行类似地理编码的操作.
So I dropped the Places AutoComplete and continued with something similar like geocoding.
这篇关于Google Places AutoComplete API在Instant Apps配置中出现API_NOT_CONNECTED错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!