迁移到 Places API,无法解析 GEO_DATA_API GeoDataApi
migrating to Places API, cannot resolve GEO_DATA_API GeoDataApi
我正在按照 here 所述,使用兼容性库完成从已删除的 Places SDK 迁移到 Places API 的过程。在尝试迁移之前,一切都运行良好。我
1) 更新了我的依赖项
2) 更改我的导入语句
3) Min SDK 已经是 21
我收到两个(看似相关的)错误。 cannot find symbol variable GEO_DATA_API
和 cannot find symbol variable GeoDataApi
代码
googleApiClient = new GoogleApiClient.Builder(PlacesActivity.this)
.addApi(Places.GEO_DATA_API) //***HERE***
.enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.build();
和
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (googleApiClient !=null) {
PendingResult<AutocompletePredictionBuffer> results = Places.GeoDataApi.getAutocompletePredictions( // ***AND HERE***
googleApiClient,
constraint.toString(),
latLngBounds,
autocompleteFilter
);
// Wait for predictions, set the timeout.
AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
//auto complete fail
autocompletePredictions.release();
return null;
}
//auto complete success
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList<PlaceAutocomplete> resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(), prediction.getFullText(null)));
}
// Buffer release
autocompletePredictions.release();
return resultList;
}
return null;
}
问题一:找不到符号变量GEO_DATA_API
解决方案一:
首先让我们了解 Places.GEO_DATA_API
的用法
它说 "The Geo Data API provides access to getting information about places by place ID, autocompleting a user's search query by name or address, and adding new places to Google's Places database."
来源 (https://developers.google.com/android/reference/com/google/android/gms/location/places/GeoDataApi)
So if we want to get place information from place id then we have to
use below code:
// Define a Place ID.
String placeId = "INSERT_PLACE_ID_HERE";
// Specify the fields to return (in this example all fields are returned).
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields).build();
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
Log.i(TAG, "Place found: " + place.getName());
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place not found: " + exception.getMessage());
}
});
问题2:找不到符号变量GeoDataApi
方案二:作为新地方api表示"Use findAutocompletePredictions() to return place predictions in response to user search queries. findAutocompletePredictions() functions similarly to getAutocompletePredictions()."
来源 (https://developers.google.com/places/android-sdk/client-migration)
So to get auto complete predictions we can use below code:
// Create a new token for the autocomplete session. Pass this to FindAutocompletePredictionsRequest,
// and once again when the user makes a selection (for example when calling fetchPlace()).
AutocompleteSessionToken token = AutocompleteSessionToken.newInstance();
// Create a RectangularBounds object.
RectangularBounds bounds = RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363),
new LatLng(-33.858754, 151.229596));
// Use the builder to create a FindAutocompletePredictionsRequest.
FindAutocompletePredictionsRequest request = FindAutocompletePredictionsRequest.builder()
// Call either setLocationBias() OR setLocationRestriction().
.setLocationBias(bounds)
//.setLocationRestriction(bounds)
.setCountry("au")
.setTypeFilter(TypeFilter.ADDRESS)
.setSessionToken(token)
.setQuery(query)
.build();
placesClient.findAutocompletePredictions(request).addOnSuccessListener((response) -> {
for (AutocompletePrediction prediction : response.getAutocompletePredictions()) {
Log.i(TAG, prediction.getPlaceId());
Log.i(TAG, prediction.getPrimaryText(null).toString());
}
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "Place not found: " + apiException.getStatusCode());
}
});
需要重新编写整个代码。这是获取纬度、经度和名称的工作代码(例如)
public class MainActivity extends AppCompatActivity {
String TAG = "placeautocomplete";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Places.
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(this);
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
// Specify the types of place data to return.
autocompleteFragment.setPlaceFields(Arrays.asList(
Place.Field.NAME,
Place.Field.LAT_LNG
));
// Set up a PlaceSelectionListener to handle the response.
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
String name = place.getName();
double lat, lng;
if (place.getLatLng() !=null){
lat =place.getLatLng().latitude;
lng =place.getLatLng().longitude;
}
//do something
}
@Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
}
}
示例xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<android.support.v7.widget.CardView
android:id="@+id/idCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp"
>
<fragment
android:id="@+id/autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
用 GeoDataClient 替换 GoogleApiClient
mGoogleApiClient = Places.getGeoDataClient(this, null);
用 AutocompletePredictionBufferResponse 替换 AutocompletePredictionBuffer
私有 ArrayList getAutocomplete(CharSequence 约束){
if (mGoogleApiClient != null) {
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
Task<AutocompletePredictionBufferResponse> results = mGoogleApiClient.getAutocompletePredictions(constraint.toString(), null, mPlaceFilter);
// 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 (ExecutionException | InterruptedException | TimeoutException e) {
Utils.handleException(e);
}
AutocompletePredictionBufferResponse autocompletePredictions = results.getResult();
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
return null;
}
我正在按照 here 所述,使用兼容性库完成从已删除的 Places SDK 迁移到 Places API 的过程。在尝试迁移之前,一切都运行良好。我
1) 更新了我的依赖项
2) 更改我的导入语句
3) Min SDK 已经是 21
我收到两个(看似相关的)错误。 cannot find symbol variable GEO_DATA_API
和 cannot find symbol variable GeoDataApi
代码
googleApiClient = new GoogleApiClient.Builder(PlacesActivity.this)
.addApi(Places.GEO_DATA_API) //***HERE***
.enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.build();
和
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (googleApiClient !=null) {
PendingResult<AutocompletePredictionBuffer> results = Places.GeoDataApi.getAutocompletePredictions( // ***AND HERE***
googleApiClient,
constraint.toString(),
latLngBounds,
autocompleteFilter
);
// Wait for predictions, set the timeout.
AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
//auto complete fail
autocompletePredictions.release();
return null;
}
//auto complete success
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList<PlaceAutocomplete> resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(), prediction.getFullText(null)));
}
// Buffer release
autocompletePredictions.release();
return resultList;
}
return null;
}
问题一:找不到符号变量GEO_DATA_API
解决方案一: 首先让我们了解 Places.GEO_DATA_API
的用法它说 "The Geo Data API provides access to getting information about places by place ID, autocompleting a user's search query by name or address, and adding new places to Google's Places database."
来源 (https://developers.google.com/android/reference/com/google/android/gms/location/places/GeoDataApi)
So if we want to get place information from place id then we have to use below code:
// Define a Place ID.
String placeId = "INSERT_PLACE_ID_HERE";
// Specify the fields to return (in this example all fields are returned).
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields).build();
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
Log.i(TAG, "Place found: " + place.getName());
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place not found: " + exception.getMessage());
}
});
问题2:找不到符号变量GeoDataApi
方案二:作为新地方api表示"Use findAutocompletePredictions() to return place predictions in response to user search queries. findAutocompletePredictions() functions similarly to getAutocompletePredictions()."
来源 (https://developers.google.com/places/android-sdk/client-migration)
So to get auto complete predictions we can use below code:
// Create a new token for the autocomplete session. Pass this to FindAutocompletePredictionsRequest,
// and once again when the user makes a selection (for example when calling fetchPlace()).
AutocompleteSessionToken token = AutocompleteSessionToken.newInstance();
// Create a RectangularBounds object.
RectangularBounds bounds = RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363),
new LatLng(-33.858754, 151.229596));
// Use the builder to create a FindAutocompletePredictionsRequest.
FindAutocompletePredictionsRequest request = FindAutocompletePredictionsRequest.builder()
// Call either setLocationBias() OR setLocationRestriction().
.setLocationBias(bounds)
//.setLocationRestriction(bounds)
.setCountry("au")
.setTypeFilter(TypeFilter.ADDRESS)
.setSessionToken(token)
.setQuery(query)
.build();
placesClient.findAutocompletePredictions(request).addOnSuccessListener((response) -> {
for (AutocompletePrediction prediction : response.getAutocompletePredictions()) {
Log.i(TAG, prediction.getPlaceId());
Log.i(TAG, prediction.getPrimaryText(null).toString());
}
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "Place not found: " + apiException.getStatusCode());
}
});
需要重新编写整个代码。这是获取纬度、经度和名称的工作代码(例如)
public class MainActivity extends AppCompatActivity {
String TAG = "placeautocomplete";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Places.
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(this);
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
// Specify the types of place data to return.
autocompleteFragment.setPlaceFields(Arrays.asList(
Place.Field.NAME,
Place.Field.LAT_LNG
));
// Set up a PlaceSelectionListener to handle the response.
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
String name = place.getName();
double lat, lng;
if (place.getLatLng() !=null){
lat =place.getLatLng().latitude;
lng =place.getLatLng().longitude;
}
//do something
}
@Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
}
}
示例xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<android.support.v7.widget.CardView
android:id="@+id/idCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp"
>
<fragment
android:id="@+id/autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
用 GeoDataClient 替换 GoogleApiClient
mGoogleApiClient = Places.getGeoDataClient(this, null);
用 AutocompletePredictionBufferResponse 替换 AutocompletePredictionBuffer
私有 ArrayList getAutocomplete(CharSequence 约束){
if (mGoogleApiClient != null) {
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
Task<AutocompletePredictionBufferResponse> results = mGoogleApiClient.getAutocompletePredictions(constraint.toString(), null, mPlaceFilter);
// 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 (ExecutionException | InterruptedException | TimeoutException e) {
Utils.handleException(e);
}
AutocompletePredictionBufferResponse autocompletePredictions = results.getResult();
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
return null;
}