繁体   English   中英

如何使用自动完成文本视图修复 Google Places 建议

[英]How to fix Google Places suggestion with Autocomplete Textview

我正在尝试使用自动完成文本视图实现 Google Places 建议,但它没有向我显示建议。 我发现我的 API 密钥接受请求,但它不返回任何内容。 我还完成了 API 密钥的计费帐户。

主程序

public class Main extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener {
    private Button searchdonar,register;
    private EditText bloodgroup;
    private TextView responseview;
    private AutoCompleteTextView autocompletelocation;
    private PlaceAutocompleteAdapter placeAutocompleteAdapter;
    private PlacesClient placesClient;
    private LatLngBounds latLngBounds = new LatLngBounds(
            new LatLng(-40,-168 ),new LatLng(71,136));
    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        searchdonar = (Button) findViewById(R.id.searchdonar);
        register = (Button) findViewById(R.id.register);

        bloodgroup = (EditText) findViewById(R.id.bloodgroup);

        // Initialize Places.
        if(!Places.isInitialized()){
            Places.initialize(getApplicationContext(), "API_KEY");
        }

        // Create a new Places client instance.
        placesClient = Places.createClient(this);

        initAutoCompleteTextView();

        register.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent Intent = new Intent(Main.this,PhoneAuth.class);
                Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(Intent);
            }
        });

        searchdonar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String Bloodgroup = bloodgroup.getText().toString().trim().toLowerCase();
                String Location = autocompletelocation.getText().toString().trim().toLowerCase();

                final String bloodgroup_location = Bloodgroup + "_" + Location;

                Intent Intent = new Intent(Main.this,Userprofile.class);
                Intent.putExtra("bloodgroup_location",bloodgroup_location);
                Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(Intent);
            }
        });
    }

    private void initAutoCompleteTextView() {

        autocompletelocation = findViewById(R.id.location);
        autocompletelocation.setThreshold(1);
        autocompletelocation.setOnItemClickListener(autocompleteClickListener);
        placeAutocompleteAdapter = new PlaceAutocompleteAdapter(this, placesClient);
        autocompletelocation.setAdapter(placeAutocompleteAdapter);
    }

    private AdapterView.OnItemClickListener autocompleteClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            try {
                final AutocompletePrediction item = placeAutocompleteAdapter.getItem(i);
                String placeID = null;
                if (item != null) {
                    placeID = item.getPlaceId();
                }

                List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS
                        , Place.Field.LAT_LNG);

                FetchPlaceRequest request = null;
                if (placeID != null) {
                    request = FetchPlaceRequest.builder(placeID, placeFields)
                            .build();
                }

                if (request != null) {
                    placesClient.fetchPlace(request).addOnSuccessListener(new OnSuccessListener<FetchPlaceResponse>() {
                        @SuppressLint("SetTextI18n")
                        @Override
                        public void onSuccess(FetchPlaceResponse task) {

                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            e.printStackTrace();
                        }
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    };
}

PlaceAutocompleteAdapter.java

public class PlaceAutocompleteAdapter extends ArrayAdapter<AutocompletePrediction> implements Filterable {
    private ArrayList<AutocompletePrediction> mResultList;
    private PlacesClient placesClient;

    PlaceAutocompleteAdapter(Context context, PlacesClient placesClient) {
        super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
        this.placesClient = placesClient;
    }

    @Override
    public int getCount() {
        return mResultList.size();
    }

    @Override
    public AutocompletePrediction getItem(int position) {
        return mResultList.get(position);
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        View row = super.getView(position, convertView, parent);

        AutocompletePrediction item = getItem(position);

        TextView textView1 = row.findViewById(android.R.id.text1);
        TextView textView2 = row.findViewById(android.R.id.text2);
        if (item != null) {
            textView1.setText(item.getPrimaryText(null));
            textView2.setText(item.getSecondaryText(null));
        }

        return row;
    }

    @NonNull
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {

                FilterResults results = new FilterResults();

                // We need a separate list to store the results, since
                // this is run asynchronously.
                ArrayList<AutocompletePrediction> filterData = new ArrayList<>();

                // Skip the autocomplete query if no constraints are given.
                if (charSequence != null) {
                    // Query the autocomplete API for the (constraint) search string.
                        filterData = getAutocomplete(charSequence);
                }

                results.values = filterData;
                if (filterData != null) {
                    results.count = filterData.size();
                } else {
                    results.count = 0;
                }

                return results;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults results) {

                if (results != null && results.count > 0) {
                    // The API returned at least one result, update the data.
                    mResultList = (ArrayList<AutocompletePrediction>) results.values;
                    notifyDataSetChanged();
                } else {
                    // The API did not return any results, invalidate the data set.
                    notifyDataSetInvalidated();
                }
            }

            @Override
            public CharSequence convertResultToString(Object resultValue) {
                // Override this method to display a readable result in the AutocompleteTextView
                // when clicked.
                if (resultValue instanceof AutocompletePrediction) {
                    return ((AutocompletePrediction) resultValue).getFullText(null);
                } else {
                    return super.convertResultToString(resultValue);
                }
            }
        };
    }

    private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {

        //Create a RectangularBounds object.
        RectangularBounds bounds = RectangularBounds.newInstance(
                new LatLng(-40, -80),
                new LatLng(70, 168));


        final FindAutocompletePredictionsRequest.Builder requestBuilder =
                FindAutocompletePredictionsRequest.builder()
                        .setQuery(constraint.toString())
                        .setCountry("") //Use only in specific country
                        // Call either setLocationBias() OR setLocationRestriction().
                        .setLocationBias(bounds)
                        .setSessionToken(AutocompleteSessionToken.newInstance())
                        .setTypeFilter(TypeFilter.ADDRESS);

        Task<FindAutocompletePredictionsResponse> results =
                placesClient.findAutocompletePredictions(requestBuilder.build());

        //Wait to get results.
        try {
            Tasks.await(results, 1, TimeUnit.SECONDS);
        } catch (ExecutionException | InterruptedException | TimeoutException e) {
            e.printStackTrace();
        }

        if (results.isSuccessful()) {
            if (results.getResult() != null) {

                return (ArrayList<AutocompletePrediction>) results.getResult().getAutocompletePredictions();
            }
            return null;
        } else {
            return null;
        }
    }
}

Logcat 向我展示了这个:

An exception occurred during performFiltering()!
java.lang.ClassCastException:   
com.google.android.libraries.places.internal.hm cannot be cast to java.util.ArrayList
    at com.example.istiaque.donateblood.PlaceAutocompleteAdapter.getAutocomplete(PlaceAutocompleteAdapter.java:160)
    at com.example.istiaque.donateblood.PlaceAutocompleteAdapter.access$000(PlaceAutocompleteAdapter.java:34)
    at com.example.istiaque.donateblood.PlaceAutocompleteAdapter$1.performFiltering(PlaceAutocompleteAdapter.java:87)
    at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:165)
    at android.os.HandlerThread.run(HandlerThread.java:61)

在 PlaceAutocompleteAdapter 中,更改return (ArrayList<AutocompletePrediction>) results.getResult().getAutocompletePredictions(); return new ArrayList<>(results.getResult().getAutocompletePredictions());

public class PlaceAutocompleteAdapter extends ArrayAdapter<AutocompletePrediction> implements Filterable {
    private ArrayList<AutocompletePrediction> mResultList;
    private PlacesClient placesClient;

    PlaceAutocompleteAdapter(Context context, PlacesClient placesClient) {
        super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
        this.placesClient = placesClient;
    }

    @Override
    public int getCount() {
        return mResultList.size();
    }

    @Override
    public AutocompletePrediction getItem(int position) {
        return mResultList.get(position);
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        View row = super.getView(position, convertView, parent);

        AutocompletePrediction item = getItem(position);

        TextView textView1 = row.findViewById(android.R.id.text1);
        TextView textView2 = row.findViewById(android.R.id.text2);
        if (item != null) {
            textView1.setText(item.getPrimaryText(null));
            textView2.setText(item.getSecondaryText(null));
        }

        return row;
    }

    @NonNull
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {

                FilterResults results = new FilterResults();

                // We need a separate list to store the results, since
                // this is run asynchronously.
                ArrayList<AutocompletePrediction> filterData = new ArrayList<>();

                // Skip the autocomplete query if no constraints are given.
                if (charSequence != null) {
                    // Query the autocomplete API for the (constraint) search string.
                        filterData = getAutocomplete(charSequence);
                }

                results.values = filterData;
                if (filterData != null) {
                    results.count = filterData.size();
                } else {
                    results.count = 0;
                }

                return results;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults results) {

                if (results != null && results.count > 0) {
                    // The API returned at least one result, update the data.
                    mResultList = (ArrayList<AutocompletePrediction>) results.values;
                    notifyDataSetChanged();
                } else {
                    // The API did not return any results, invalidate the data set.
                    notifyDataSetInvalidated();
                }
            }

            @Override
            public CharSequence convertResultToString(Object resultValue) {
                // Override this method to display a readable result in the AutocompleteTextView
                // when clicked.
                if (resultValue instanceof AutocompletePrediction) {
                    return ((AutocompletePrediction) resultValue).getFullText(null);
                } else {
                    return super.convertResultToString(resultValue);
                }
            }
        };
    }

    private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {

        //Create a RectangularBounds object.
        RectangularBounds bounds = RectangularBounds.newInstance(
                new LatLng(-40, -80),
                new LatLng(70, 168));


        final FindAutocompletePredictionsRequest.Builder requestBuilder =
                FindAutocompletePredictionsRequest.builder()
                        .setQuery(constraint.toString())
                        .setCountry("") //Use only in specific country
                        // Call either setLocationBias() OR setLocationRestriction().
                        .setLocationBias(bounds)
                        .setSessionToken(AutocompleteSessionToken.newInstance())
                        .setTypeFilter(TypeFilter.ADDRESS);

        Task<FindAutocompletePredictionsResponse> results =
                placesClient.findAutocompletePredictions(requestBuilder.build());

        //Wait to get results.
        try {
            Tasks.await(results, 1, TimeUnit.SECONDS);
        } catch (ExecutionException | InterruptedException | TimeoutException e) {
            e.printStackTrace();
        }

        if (results.isSuccessful()) {
            if (results.getResult() != null) {

               return new ArrayList<>(results.getResult().getAutocompletePredictions());
            }
            return null;
        } else {
            return null;
        }
    }
}

今天你不要创建一个类适配器。 关于地方自动填充的教程就在这里

代码:

AutocompleteSupportFragment autocompleteFragment; 
PlacesClient placesClient;
LatLng location;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout);

    // Initialize Places.
    Places.initialize(getApplicationContext(), getString(R.string.googleMapsAPI));
    // Create a new Places client instance.
    placesClient = Places.createClient(this);

    // Initialize the AutocompleteSupportFragment.
    autocompleteFragment = (AutocompleteSupportFragment)
            getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);

    // Specify the types of place data to return.
    autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));

    // 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.
            final LatLng location = place.getLatLng();
            Log.i(LOG_TAG, "Place: " + place.getName() + ", " + place.getId());
            getLocationPlace(place.getId());
        }

        @Override
        public void onError(Status status) {
            // TODO: Handle the error.
            Log.i(LOG_TAG, "An error occurred: " + status);
        }
    });
}

private void getLocationPlace(final String placeId) {
    // Specify the fields to return (in this example all fields are returned).
    List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG);
    // Construct a request object, passing the place ID and fields array.
    FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields).build();

    placesClient.fetchPlace(request).addOnSuccessListener(new OnSuccessListener<FetchPlaceResponse>() {
        @Override
        public void onSuccess(FetchPlaceResponse fetchPlaceResponse) {
            Place place = fetchPlaceResponse.getPlace();
            Log.d(LOG_TAG, "place = " + place.getLatLng());
            location = place.getLatLng();
        }
    });
}

并在布局中添加了一个片段:

 <fragment
        android:id="@+id/autocomplete_fragment"
        android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Address, City or Zip Code" />

我希望这可以帮助你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM