I implemented the new autocomplete place sdk in an Android app but it does not show most of places for Nigeria. For example, when I enter spar PH
it should show the location SPAR PH, Forces Avenue, Port Harcourt, Nigeria
in the suggestion but doesn't. There are other examples that aren't working, too. This was working with the autocomplete Place API but not the new autocomplete .
activity code
public class LocationPickActivity extends BaseActivity implements 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)); private Location mLastKnownLocation; protected GoogleApiClient mGoogleApiClient; @BindView(R.id.appbar) AppBarLayout appbar; @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.source) EditText source; @BindView(R.id.destination) EditText destination; @BindView(R.id.destination_layout) LinearLayout destinationLayout; @BindView(R.id.home_address_layout) LinearLayout homeAddressLayout; @BindView(R.id.work_address_layout) LinearLayout workAddressLayout; @BindView(R.id.home_address) TextView homeAddress; @BindView(R.id.work_address) TextView workAddress; @BindView(R.id.locations_rv) RecyclerView locationsRv; @BindView(R.id.location_bs_layout) CardView locationBsLayout; @BindView(R.id.dd) CoordinatorLayout dd; boolean isEnableIdle = false; @BindView(R.id.llSource) LinearLayout 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,
fetchPlace()). AutocompleteSessionToken token = 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();
}
}
}
The Place Picker is deprecated as of January 29, 2019. This feature will be turned off on July 29, 2019, and will no longer be available after that date. You must install the compatibility library to continue using the Place Picker during the deprecation period. Once the deprecation period has ended, the Place Picker will no longer be available for use (including the version in the compatibility library).