我试图在github中使用Google提供的代码。它由于某种原因不起作用。如果我能知道自己错在哪里,那将是一个很大的帮助。我在这里发布我的代码。 我没有收到任何错误,但自动填充建议不会显示。 我添加了谷歌API密钥。连接回调显示google api客户端已连接。
MainActivity.Java
package com.example.sid.organizer;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v4.app.NotificationCompat;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.PlaceBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener,GoogleApiClient.ConnectionCallbacks{
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if(mGoogleApiClient != null){
mGoogleApiClient.disconnect();
}
}
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
protected GoogleApiClient mGoogleApiClient;
private PlaceAutocompleteAdapter mAdapter;
private AutoCompleteTextView mAutocompleteView;
private TextView mPlaceDetailsText;
private static final String TAG = "MainActivity";
private TextView mPlaceDetailsAttribution;
private static final LatLngBounds BOUNDS_USA = new LatLngBounds(
new LatLng(32.6393,-117.004304), new LatLng(44.901184 ,-67.32254));
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
EditText add_alert_name;
ListView alert_list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Places.GEO_DATA_API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
// if(this.mGoogleApiClient == null){
// Toast.makeText(this, "Null", Toast.LENGTH_SHORT).show();
// }else{
// Toast.makeText(this, "Not null", Toast.LENGTH_SHORT).show();
// }
alert_list = (ListView) findViewById(R.id.alerts_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
AlertDialog.Builder alert_builder = new AlertDialog.Builder(MainActivity.this);
LayoutInflater layoutInflater = getLayoutInflater();
final View v = layoutInflater.inflate(R.layout.add_alert, null, false);
alert_builder.setView(v);
alert_builder.setTitle("Add Alert");
alert_builder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Get texts from the alerts
// Validate
// Add to local storage
add_alert_name = (EditText) v.findViewById(R.id.add_alert_name);
mAutocompleteView = (AutoCompleteTextView) v.findViewById(R.id.autocomplete_places);
String add_al_name = add_alert_name.getText().toString();
String add_al_loc = mAutocompleteView.getText().toString();
if(mAutocompleteView != null){
mAutocompleteView.setOnItemClickListener(mAutocompleteClickListener);
mPlaceDetailsText = (TextView) v.findViewById(R.id.place_details);
mPlaceDetailsAttribution = (TextView) v.findViewById(R.id.place_attribution);
// Set up the adapter that will retrieve suggestions from the Places Geo Data API that cover
// the entire world.
mAdapter = new PlaceAutocompleteAdapter(v.getContext(), mGoogleApiClient, BOUNDS_USA,
null);
mAutocompleteView.setAdapter(mAdapter);
}else{
Toast.makeText(MainActivity.this, "Auto is null", Toast.LENGTH_SHORT).show();
}
if(add_al_name != null || add_al_name != "" || add_al_loc != null || add_al_loc != ""){
new Alerts().AddAlert(add_al_name,add_al_loc);
}else{
Toast.makeText(MainActivity.this, "Incorrect Data", Toast.LENGTH_SHORT).show();
}
}
});
alert_builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert_builder.show();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
});
}
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
/*
Retrieve the place ID of the selected item from the Adapter.
The adapter stores each Place suggestion in a AutocompletePrediction from which we
read the place ID and title.
*/
final AutocompletePrediction item = mAdapter.getItem(position);
final String placeId = item.getPlaceId();
final CharSequence primaryText = item.getPrimaryText(null);
Log.i(TAG, "Autocomplete item selected: " + primaryText);
/*
Issue a request to the Places Geo Data API to retrieve a Place object with additional
details about the place.
*/
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
Toast.makeText(getApplicationContext(), "Clicked: " + primaryText,
Toast.LENGTH_SHORT).show();
Log.i(TAG, "Called getPlaceById to get Place details for " + placeId);
}
};
/**
* Callback for results from a Places Geo Data API query that shows the first place result in
* the details view on screen.
*/
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
// Request did not complete successfully
Log.e(TAG, "Place query did not complete. Error: " + places.getStatus().toString());
places.release();
return;
}
// Get the Place object from the buffer.
final Place place = places.get(0);
// Format details of the place for display and show it in a TextView.
mPlaceDetailsText.setText(formatPlaceDetails(getResources(), place.getName(),
place.getId(), place.getAddress(), place.getPhoneNumber(),
place.getWebsiteUri()));
// Display the third party attributions if set.
final CharSequence thirdPartyAttribution = places.getAttributions();
if (thirdPartyAttribution == null) {
mPlaceDetailsAttribution.setVisibility(View.GONE);
} else {
mPlaceDetailsAttribution.setVisibility(View.VISIBLE);
mPlaceDetailsAttribution.setText(Html.fromHtml(thirdPartyAttribution.toString()));
}
Log.i(TAG, "Place details received: " + place.getName());
places.release();
}
};
private static Spanned formatPlaceDetails(Resources res, CharSequence name, String id,
CharSequence address, CharSequence phoneNumber, Uri websiteUri) {
Log.e(TAG, res.getString(R.string.place_details, name, id, address, phoneNumber,
websiteUri));
return Html.fromHtml(res.getString(R.string.place_details, name, id, address, phoneNumber,
websiteUri));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed: ConnectionResult.getErrorCode() = "
+ connectionResult.getErrorCode());
// TODO(Developer): Check error code and notify the user of error state and resolution.
Toast.makeText(this,
"Could not connect to Google API Client: Error " + connectionResult.getErrorCode(),
Toast.LENGTH_SHORT).show();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionSuspended(int i) {
Toast.makeText(this, "Connection Suspended", Toast.LENGTH_SHORT).show();
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position){
case 0:
Alerts alerts = new Alerts();
return alerts;
case 1:
Deals deals = new Deals();
return deals;
case 2:
NearBy nearBy = new NearBy();
return nearBy;
default:
return null;
}
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "ALERTS";
case 1:
return "DEALS";
case 2:
return "NEAR BY";
}
return null;
}
}
@Override
protected void onPause() {
super.onPause();
// dialog.dismiss();
}
}
PlaceAutocompleteAdapter.java
package com.example.sid.organizer;
import android.content.Context;
import android.graphics.Typeface;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.util.Log;
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 android.widget.Toast;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.data.DataBufferUtils;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.AutocompletePredictionBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLngBounds;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import static android.R.attr.resource;
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private static final String TAG = "PlaceAutocompleteAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
/**
* Current results returned by this adapter.
*/
private ArrayList<AutocompletePrediction> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* @see android.widget.ArrayAdapter#ArrayAdapter(android.content.Context, int)
*/
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
@Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
@Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View 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.
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
/**
* 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();
// 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 (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
protected void publishResults(CharSequence constraint, 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);
}
}
};
}
/**
* Submits an autocomplete query to the Places Geo Data Autocomplete API.
* Results are returned as frozen AutocompletePrediction objects, ready to be cached.
* objects to store the Place ID and description that the API returns.
* 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 Places#GEO_DATA_API#getAutocomplete(CharSequence)
* @see AutocompletePrediction#freeze()
*/
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, 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.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
}
谢谢