我在一个 Android 应用程序中实现了新的自动完成 place sdk,但它没有显示尼日利亚的大部分地方。例如,当我输入时,spar PH
它应该SPAR PH, Forces Avenue, Port Harcourt, Nigeria
在建议中显示位置,但不显示。还有其他例子也不起作用。这适用于自动完成 Place API,但不适用于新的 autocomplete。
活动代码
公共类 LocationPickActivity 扩展 BaseActivity 实现 OnMapReadyCallback、GoogleMap.OnCameraMoveListener、GoogleMap.OnCameraIdleListener、GoogleApiClient.ConnectionCallbacks、GoogleApiClient.OnConnectionFailedListener、LocationPickIView { private static final LatLngBounds BOUNDS_INDIA = new LatLngBounds(new LatLng(-0, 0), new LatLng(0, 0) )); 私有位置 mLastKnownLocation;受保护的 GoogleApiClient mGoogleApiClient;@BindView(R.id.appbar) AppBarLayout 应用栏;@BindView(R.id.toolbar) 工具栏工具栏;@BindView(R.id.source) 编辑文本源;@BindView(R.id.destination) EditText 目标;@BindView(R.id.destination_layout) 线性布局目标布局;@BindView(R.id.home_address_layout) 线性布局 homeAddressLayout; @BindView(R.id.work_address_layout) 线性布局工作地址布局;@BindView(R.id.home_address) TextView homeAddress; @BindView(R.id.work_address) TextView 工作地址;@BindView(R.id.locations_rv) RecyclerView locationsRv; @BindView(R.id.location_bs_layout) CardView locationBsLayout; @BindView(R.id.dd) CoordinatorLayout dd; 布尔 isEnableIdle = false; @BindView(R.id.llSource) 线性布局 llSource; 布尔 isEnableIdle = false; @BindView(R.id.llSource) 线性布局 llSource; 布尔 isEnableIdle = false; @BindView(R.id.llSource) 线性布局 llSource;
private boolean isLocationRvClick = false;
private boolean isSettingLocationClick = false;
private boolean mLocationPermissionGranted;
private GoogleMap mGoogleMap;
private String s_address;
private Double s_latitude;
private Double s_longitude;
private FusedLocationProviderClient mFusedLocationProviderClient;
private BottomSheetBehavior mBottomSheetBehavior;
private Boolean isEditable = true;
private UserAddress home, work = null;
private LocationPickPresenter<LocationPickActivity> presenter = new LocationPickPresenter<>();
private EditText selectedEditText;
private PlacesAutoCompleteAdapter mAutoCompleteAdapter;
//Base on action we are show/hide view and setResults
private String actionName = Constants.LocationActions.SELECT_SOURCE;
PlacesClient placesClient =null;
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
if (isEditable) if (!s.toString().equals("") && mGoogleApiClient.isConnected()) {
locationsRv.setVisibility(View.VISIBLE);
mAutoCompleteAdapter.getFilter().filter(s.toString());
if (mBottomSheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED)
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
} else if (!mGoogleApiClient.isConnected()) Log.e("ERROR", "API_NOT_CONNECTED");
if (s.toString().equals("")) locationsRv.setVisibility(View.GONE);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
@Override
public int getLayoutId() {
return R.layout.activity_location_pick;
}
@Override
public void initView() {
buildGoogleApiClient();
ButterKnife.bind(this);
presenter.attachView(this);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Places.initialize(getApplicationContext(), getString(R.string.google_map_key));
placesClient = Places.createClient(this);
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mBottomSheetBehavior = BottomSheetBehavior.from(locationBsLayout);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
mAutoCompleteAdapter = new PlacesAutoCompleteAdapter(this, R.layout.list_item_location, mGoogleApiClient, BOUNDS_INDIA);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
locationsRv.setLayoutManager(mLinearLayoutManager);
locationsRv.setAdapter(mAutoCompleteAdapter);
source.addTextChangedListener(filterTextWatcher);
destination.addTextChangedListener(filterTextWatcher);
source.setOnFocusChangeListener((view, hasFocus) -> {
if (hasFocus) selectedEditText = source;
});
destination.setOnFocusChangeListener((view, hasFocus) -> {
if (hasFocus) selectedEditText = destination;
});
destination.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) {
setResult(Activity.RESULT_OK, new Intent());
finish();
return true;
}
return false;
});
source.setText(MvpApplication.RIDE_REQUEST.containsKey(Constants.RIDE_REQUEST.SRC_ADD)
? TextUtils.isEmpty(Objects.requireNonNull(MvpApplication.RIDE_REQUEST.get(Constants.RIDE_REQUEST.SRC_ADD)).toString())
? ""
: String.valueOf(MvpApplication.RIDE_REQUEST.get(Constants.RIDE_REQUEST.SRC_ADD))
: "");
destination.setText(MvpApplication.RIDE_REQUEST.containsKey(Constants.RIDE_REQUEST.DEST_ADD)
? TextUtils.isEmpty(Objects.requireNonNull(MvpApplication.RIDE_REQUEST.get(Constants.RIDE_REQUEST.DEST_ADD)).toString())
? ""
: String.valueOf(MvpApplication.RIDE_REQUEST.get(Constants.RIDE_REQUEST.DEST_ADD))
: "");
locationsRv.addOnItemTouchListener(new RecyclerItemClickListener(this, (view, position) -> {
if (mAutoCompleteAdapter.getItemCount() == 0) return;
final PlacesAutoCompleteAdapter.PlaceAutocomplete item = mAutoCompleteAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
Log.i("LocationPickActivity", "Autocomplete item selected: " + item.address);
List<Field> placeFields = Arrays.asList(Field.LAT_LNG);
);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
actionName = bundle.getString("actionName",Constants.LocationActions.SELECT_SOURCE);
if (!TextUtils.isEmpty(actionName) && actionName.equalsIgnoreCase(Constants.LocationActions.SELECT_SOURCE)) {
destination.setCursorVisible(false);
source.setCursorVisible(true);
source.requestFocus();
selectedEditText = source;
}else if (!TextUtils.isEmpty(actionName) && actionName.equalsIgnoreCase(Constants.LocationActions.SELECT_DESTINATION)){
source.setCursorVisible(false);
destination.setCursorVisible(true);
destination.setText("");
destination.requestFocus();
selectedEditText = destination;
}else if (!TextUtils.isEmpty(actionName) && actionName.equals(Constants.LocationActions.CHANGE_DESTINATION)){
llSource.setVisibility(View.GONE);
source.setHint(getString(R.string.select_location));
selectedEditText = destination;
}else if (!TextUtils.isEmpty(actionName) && (actionName.equals(Constants.LocationActions.SELECT_HOME)|| actionName.equals(Constants.LocationActions.SELECT_WORK))){
destinationLayout.setVisibility(View.GONE);
selectedEditText = destination;
source.setText("");
source.setHint(getString(R.string.select_location));
} else{
destinationLayout.setVisibility(View.VISIBLE);
llSource.setVisibility(View.VISIBLE);
source.setHint(getString(R.string.pickup_location));
selectedEditText = source;
}
}
presenter.address();
}
private void setLocationText(String address, LatLng latLng, boolean isLocationRvClick,
boolean isSettingLocationClick) {
if (address != null && latLng != null) {
isEditable = false;
selectedEditText.setText(address);
isEditable = true;
if (selectedEditText.getTag().equals("source")) {
s_address = address;
s_latitude = latLng.latitude;
s_longitude = latLng.longitude;
MvpApplication.RIDE_REQUEST.put(Constants.RIDE_REQUEST.SRC_ADD, address);
MvpApplication.RIDE_REQUEST.put(Constants.RIDE_REQUEST.SRC_LAT, latLng.latitude);
MvpApplication.RIDE_REQUEST.put(Constants.RIDE_REQUEST.SRC_LONG, latLng.longitude);
}
if (selectedEditText.getTag().equals("destination")) {
MvpApplication.RIDE_REQUEST.put(Constants.RIDE_REQUEST.DEST_ADD, address);
MvpApplication.RIDE_REQUEST.put(Constants.RIDE_REQUEST.DEST_LAT, latLng.latitude);
MvpApplication.RIDE_REQUEST.put(Constants.RIDE_REQUEST.DEST_LONG, latLng.longitude);
if (isLocationRvClick) {
// Done functionality called...
setResult(Activity.RESULT_OK, new Intent());
finish();
}
}
} else {
isEditable = false;
selectedEditText.setText("");
locationsRv.setVisibility(View.GONE);
isEditable = true;
if (selectedEditText.getTag().equals("source")) {
MvpApplication.RIDE_REQUEST.remove(Constants.RIDE_REQUEST.SRC_ADD);
MvpApplication.RIDE_REQUEST.remove(Constants.RIDE_REQUEST.SRC_LAT);
MvpApplication.RIDE_REQUEST.remove(Constants.RIDE_REQUEST.SRC_LONG);
}
if (selectedEditText.getTag().equals("destination")) {
MvpApplication.RIDE_REQUEST.remove(Constants.RIDE_REQUEST.DEST_ADD);
MvpApplication.RIDE_REQUEST.remove(Constants.RIDE_REQUEST.DEST_LAT);
MvpApplication.RIDE_REQUEST.remove(Constants.RIDE_REQUEST.DEST_LONG);
}
}
if (isSettingLocationClick) {
hideKeyboard();
locationsRv.setVisibility(View.GONE);
}
}
@Override
public void onResume() {
super.onResume();
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) {
Log.v("Google API", "Connecting");
mGoogleApiClient.connect();
}
}
@Override
public void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
Log.v("Google API", "Dis-Connecting");
mGoogleApiClient.disconnect();
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@OnClick({R.id.source, R.id.destination, R.id.reset_source, R.id.reset_destination, R.id.home_address_layout, R.id.work_address_layout})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.source:
break;
case R.id.destination:
break;
case R.id.reset_source:
selectedEditText = source;
source.requestFocus();
setLocationText(null, null, isLocationRvClick, isSettingLocationClick);
break;
case R.id.reset_destination:
destination.requestFocus();
selectedEditText = destination;
setLocationText(null, null, isLocationRvClick, isSettingLocationClick);
break;
case R.id.home_address_layout:
if (home != null)
setLocationText(home.getAddress(),
new LatLng(home.getLatitude(), home.getLongitude()),
isLocationRvClick, isSettingLocationClick);
break;
case R.id.work_address_layout:
if (work != null)
setLocationText(work.getAddress(),
new LatLng(work.getLatitude(), work.getLongitude()),
isLocationRvClick, isSettingLocationClick);
break;
}
}
@Override
public void onCameraIdle() {
try {
CameraPosition cameraPosition = mGoogleMap.getCameraPosition();
if (isEnableIdle) {
String address = getAddress(cameraPosition.target);
System.out.println("onCameraIdle " + address);
hideKeyboard();
setLocationText(address, cameraPosition.target, isLocationRvClick, isSettingLocationClick);
}
isEnableIdle = true;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onCameraMove() {
System.out.println("LocationPickActivity.onCameraMove");
}
@Override
public void onMapReady(GoogleMap googleMap) {
try {
// Google map custom style...
googleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.style_json));
} catch (Resources.NotFoundException e) {
Log.d("Map:Style", "Can't find style. Error: ");
}
this.mGoogleMap = googleMap;
getLocationPermission();
updateLocationUI();
getDeviceLocation();
}
void getDeviceLocation() {
try {
if (mLocationPermissionGranted) {
Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(this, task -> {
if (task.isSuccessful() && task.getResult() != null) {
mLastKnownLocation = task.getResult();
mGoogleMap.moveCamera(CameraUpdateFactory
.newLatLngZoom(new LatLng(
mLastKnownLocation.getLatitude(),
mLastKnownLocation.getLongitude()
), DEFAULT_ZOOM));
} else {
Log.d("Map", "Current location is null. Using defaults.");
Log.e("Map", "Exception: %s", task.getException());
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
}
});
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
public void getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
mLocationPermissionGranted = true;
else
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS_FINE_LOCATION);
}
private void updateLocationUI() {
if (mGoogleMap == null) return;
try {
if (mLocationPermissionGranted) {
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
mGoogleMap.setOnCameraMoveListener(this);
mGoogleMap.setOnCameraIdleListener(this);
} else {
mGoogleMap.setMyLocationEnabled(false);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
mLastKnownLocation = null;
getLocationPermission();
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
mLocationPermissionGranted = false;
if (requestCode == REQUEST_ACCESS_FINE_LOCATION)
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
updateLocationUI();
getDeviceLocation();
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
}
@Override
public void onConnectionSuspended(int i) {
Log.v("Google API Callback", "Connection Suspended");
Log.v("Code", String.valueOf(i));
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.v("Error Code", String.valueOf(connectionResult.getErrorCode()));
Toast.makeText(this, "API_NOT_CONNECTED", Toast.LENGTH_SHORT).show();
}
@Override
public void onBackPressed() {
if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
else super.onBackPressed();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.location_pick_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_done:
if (!TextUtils.isEmpty(actionName) && actionName.equals(Constants.LocationActions.SELECT_HOME) || actionName.equals(Constants.LocationActions.SELECT_WORK)){
Intent intent = new Intent();
intent.putExtra(Constants.RIDE_REQUEST.SRC_ADD, s_address);
intent.putExtra(Constants.RIDE_REQUEST.SRC_LAT, s_latitude);
intent.putExtra(Constants.RIDE_REQUEST.SRC_LONG, s_longitude);
setResult(Activity.RESULT_OK, intent);
finish();
} else {
setResult(Activity.RESULT_OK, new Intent());
finish();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onSuccess(AddressResponse address) {
if (address.getHome().isEmpty()) homeAddressLayout.setVisibility(View.GONE);
else {
home = address.getHome().get(address.getHome().size() - 1);
homeAddress.setText(home.getAddress());
homeAddressLayout.setVisibility(View.VISIBLE);
}
if (address.getWork().isEmpty()) workAddressLayout.setVisibility(View.GONE);
else {
work = address.getWork().get(address.getWork().size() - 1);
workAddress.setText(work.getAddress());
workAddressLayout.setVisibility(View.VISIBLE);
}
}
@Override
public void onError(Throwable e) {
handleError(e);
}
@Override
protected void onDestroy() {
presenter.onDetach();
super.onDestroy();
}
}
public class PlacesAutoCompleteAdapter extends RecyclerView.Adapter<PlacesAutoCompleteAdapter.PredictionHolder> implements Filterable {
private static final String TAG = "PlacesAutoAdapter";
private ArrayList<PlaceAutocomplete> mResultList = new ArrayList<>();
private GoogleApiClient mGoogleApiClient;
private LatLngBounds mBounds;
private Context mContext;
private int layout;
private CharacterStyle STYLE_BOLD;
private CharacterStyle STYLE_NORMAL;
PlacesClient placesClient =null;
public PlacesAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient, LatLngBounds bounds) {
mContext = context;
layout = resource;
mGoogleApiClient = googleApiClient;
mBounds = bounds;
STYLE_BOLD = new StyleSpan(Typeface.BOLD);
STYLE_NORMAL = new StyleSpan(Typeface.NORMAL);
if (!Places.isInitialized()) {
Places.initialize(context, context.getString(R.string.google_api_key));
}
placesClient = Places.createClient(context);
}
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the filter for the current set of autocomplete results.
*/
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
// The API successfully returned results.
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
//notifyDataSetInvalidated();
}
}
};
}
private ArrayList getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i("", "Starting autocomplete query for: " + constraint);
// Create a new token for the autocomplete session. Pass this to FindAutocompletePredictionsRequest,
取地方())。AutocompleteSessionToken 令牌 = AutocompleteSessionToken.newInstance();
FindAutocompletePredictionsRequest request = FindAutocompletePredictionsRequest.builder()
.setTypeFilter(TypeFilter.ADDRESS)
.setSessionToken(token)
.setQuery(constraint.toString())
.build();
ArrayList<PlaceAutocomplete> resultList = new ArrayList<>();
placesClient.findAutocompletePredictions(request).addOnSuccessListener((response) -> {
for (AutocompletePrediction prediction : response.getAutocompletePredictions()) {
Log.i(TAG, prediction.getPlaceId());
Log.i(TAG, prediction.getPrimaryText(null).toString());
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(), prediction.getPrimaryText(STYLE_NORMAL),
prediction.getFullText(STYLE_BOLD)));
}
}).addOnFailureListener((exception) -> {
return resultList;
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
@NonNull
@Override
public PredictionHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = Objects.requireNonNull(layoutInflater).inflate(layout, viewGroup, false);
return new PredictionHolder(convertView);
}
@Override
public void onBindViewHolder(@NonNull PredictionHolder mPredictionHolder, final int i) {
mPredictionHolder.area.setText(mResultList.get(i).area);
mPredictionHolder.address.setText(mResultList.get(i).address.toString()
.replace(mResultList.get(i).area + ", ", ""));
}
@Override
public int getItemCount() {
return (mResultList == null) ? 0 : mResultList.size();
}
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
class PredictionHolder extends RecyclerView.ViewHolder {
private TextView address, area;
PredictionHolder(View itemView) {
super(itemView);
area = itemView.findViewById(R.id.area);
address = itemView.findViewById(R.id.address);
}
}
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence address, area;
PlaceAutocomplete(CharSequence placeId, CharSequence area, CharSequence address) {
this.placeId = placeId;
this.area = area;
this.address = address;
}
@Override
public String toString() {
return area.toString();
}
}
}