Android:在 android Places Api 中提供自动自动建议?

Posted

技术标签:

【中文标题】Android:在 android Places Api 中提供自动自动建议?【英文标题】:Android : Providing auto autosuggestion in android places Api? 【发布时间】:2012-10-22 18:34:03 【问题描述】:

我对 android 谷歌地图非常陌生,我编写了以下程序,用于在 android 中显示自动建议在程序中。请看一次,让我知道我在哪里做错了。

   ExampleApp.java
package com.example.exampleapp;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater.Filter;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

import android.widget.Filterable;
import android.widget.Toast;

public class ExampleApp extends Activity implements OnItemClickListener

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
        autoCompView.setAdapter(new PlacesAutoCompleteAdapter(this, R.layout.list_item));
    

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
        // TODO Auto-generated method stub
        String str = (String) arg0.getItemAtPosition(arg2);
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    



class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable 
    private ArrayList<String> resultList;

    public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) 
        super(context, textViewResourceId);
    
    private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
    private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
    private static final String OUT_JSON = "/json";

    private static final String API_KEY = "";
    @Override
    public int getCount() 
        return resultList.size();
    

    @Override
    public String getItem(int index) 
        return resultList.get(index);
    

    @Override
    public android.widget.Filter getFilter() 
        Filter filter = new Filter() 
            protected FilterResults performFiltering(CharSequence constraint) 
                FilterResults filterResults = new FilterResults();
                if (constraint != null) 
                    // Retrieve the autocomplete results.
                    resultList = autocomplete(constraint.toString());

                    // Assign the data to the FilterResults
                 //   filterResults.values = resultList;
                  //  filterResults.count = resultList.size();
                
                return filterResults;
            

            private ArrayList<String> autocomplete(String input) 
                ArrayList<String> resultList = null;

                HttpURLConnection conn = null;
                StringBuilder jsonResults = new StringBuilder();
                try 
                    StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
                    sb.append("?sensor=false&key=" + API_KEY);
                    sb.append("&components=country:uk");
                    sb.append("&input=" + URLEncoder.encode(input, "utf8"));

                    URL url = new URL(sb.toString());
                    conn = (HttpURLConnection) url.openConnection();
                    InputStreamReader in = new InputStreamReader(conn.getInputStream());

                    // Load the results into a StringBuilder
                    int read;
                    char[] buff = new char[1024];
                    while ((read = in.read(buff)) != -1) 
                        jsonResults.append(buff, 0, read);
                    
                 catch (MalformedURLException e) 
                   // Log.e(LOG_TAG, "Error processing Places API URL", e);
                    return resultList;
                 catch (IOException e) 
                    //Log.e(LOG_TAG, "Error connecting to Places API", e);
                    return resultList;
                 finally 
                    if (conn != null) 
                        conn.disconnect();
                    
                

                try 
                    // Create a JSON object hierarchy from the results
                    JSONObject jsonObj = new JSONObject(jsonResults.toString());
                    JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");

                    // Extract the Place descriptions from the results
                    resultList = new ArrayList<String>(predsJsonArray.length());
                    for (int i = 0; i < predsJsonArray.length(); i++) 
                        resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
                    
                 catch (JSONException e) 
                   // Log.e(LOG_TAG, "Cannot process JSON results", e);
                

                return resultList;
            
            protected void publishResults(CharSequence constraint, FilterResults results) 
                if (results != null) 
                    notifyDataSetChanged();
                
                else 
                    notifyDataSetInvalidated();
                
            

            @Override
            public boolean onLoadClass(Class arg0) 
                // TODO Auto-generated method stub
                return false;
            ;
        return (android.widget.Filter) filter;
    


FilterResults.java

package com.example.exampleapp;

import java.util.ArrayList;

public class FilterResults 

    protected ArrayList<String> values;
    protected int count;




i write the above code but the application closed .please see once and let me know where i am doing mistake in the above code ?
Thanks in Advance..........

【问题讨论】:

请帮助我如何实现这一点? 嘿这是我的问题。直到出现错误才解决? 【参考方案1】:

这是我遇到类似问题时使用的代码片段。我给你一个建议,不要把你的整个代码放在一个 java 文件中。为您在代码中使用的每个不同任务创建单独的方法/类。它将帮助您更轻松地跟踪它。

这是我的 PlacesAutoCompleteAdapter.java 文件。

package com.inukshk.adapter;

import java.util.ArrayList;

import android.content.Context;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;

import com.inukshk.CreateInukshk.CreateInukshk;

public class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements
        Filterable 
    private ArrayList<String> resultList;

    public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) 
        super(context, textViewResourceId);
    

    @Override
    public int getCount() 
        return resultList.size();
    

    @Override
    public String getItem(int index) 
        return resultList.get(index);
    

    @Override
    public Filter getFilter() 
        Filter filter = new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence constraint) 
                FilterResults filterResults = new FilterResults();
                if (constraint != null) 
                    // Retrieve the autocomplete results.

                    resultList = CreateInukshk.autocomplete(constraint
                            .toString());

                    // Assign the data to the FilterResults
                    filterResults.values = resultList;
                    filterResults.count = resultList.size();
                
                return filterResults;
            

            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults results) 
                if (results != null && results.count > 0) 
                    notifyDataSetChanged();
                 else 
                    notifyDataSetInvalidated();
                
            
        ;
        return filter;
    

这是您在 Activity 的 OnCreate() 中必须执行的操作。

autoCompView = (AutoCompleteTextView) findViewById(R.id.editloc);
        autoCompView.setAdapter(new PlacesAutoCompleteAdapter(this,
                R.layout.list_item));

这是我在应用程序中使用的静态字符串。

private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
    private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
    private static final String OUT_JSON = "/json";
    private static final String API_KEY = "YOUR API KEY";

最后这里是您将在适配器中使用的方法。

public static ArrayList<String> autocomplete(String input) 

        ArrayList<String> resultList = null;

        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();
        try 
            StringBuilder sb = new StringBuilder(PLACES_API_BASE
                    + TYPE_AUTOCOMPLETE + OUT_JSON);
            sb.append("?sensor=false&key=" + API_KEY);
            // sb.append("&components=country:uk");
            sb.append("&input=" + URLEncoder.encode(input, "utf8"));

            URL url = new URL(sb.toString());
            conn = (HttpURLConnection) url.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());

            // Load the results into a StringBuilder
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) 
                jsonResults.append(buff, 0, read);
            
         catch (MalformedURLException e) 
            Log.e(TAG, "Error processing Places API URL", e);
            return resultList;
         catch (IOException e) 
            Log.e(TAG, "Error connecting to Places API", e);
            return resultList;
         finally 
            if (conn != null) 
                conn.disconnect();
            
        

        try 
            // Create a JSON object hierarchy from the results
            JSONObject jsonObj = new JSONObject(jsonResults.toString());
            JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");

            // Extract the Place descriptions from the results
            resultList = new ArrayList<String>(predsJsonArray.length());
            for (int i = 0; i < predsJsonArray.length(); i++) 
                resultList.add(predsJsonArray.getJSONObject(i).getString(
                        "description"));
            

         catch (JSONException e) 
            Log.e(TAG, "Cannot process JSON results", e);
        

        return resultList;
    

已编辑:

我猜你已经指定了 list_item.xml 如下。

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_ android:layout_ />

试试看。希望对你有帮助。

更新:

You have to manually attach the debugger while the emulator says "Waiting for debugger to attach". In Netbean's menu bar, click "Debug", then "Attach Debugger...". You have to select your package from the "Process" drop down list, and then click "Attach". That should do it.
This works in Netbeans 7 anyway.

或者你也可以试试下面的东西。

You have two choices: connect a debugger, or kill the process.

Looking at your logcat, you have at least two different desktop applications that are trying to connect to each application process, which is where the "Ignoring second debugger" messages are coming from.

This would happen if you were, say, running Eclipse with the ADT plugin, and the stand-alone DDMS at the same time. I don't know what you're running or what the netbeans plugin does, but I would start by figuring out if you have two different things fighting for control.

已编辑: HOW TO GET TEXT OF AutoCompleteTextView

只需编写这段代码sn-p。

autoCompView.setOnItemClickListener(new OnItemClickListener() 

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) 
                // TODO Auto-generated method stub
                YOURTEXT = autoCompView.getText().toString();
                //new AsyncGetAutoPlace().execute(autoCompView.getText()
                //      .toString().trim());
            
        );

【讨论】:

FilterResults 我如何调用它? 请提供建议,以便我转发 你必须导入android.widget.Filter;导入 android.widget.Filterable; "FilterResults 我如何调用它?"对不起,但我没明白。您在导入时遇到任何问题? "运行它会关闭吗?"意味着你正在逼近?【参考方案2】:

我们必须先添加计费凭据...所以,在谷歌开发者控制台上创建一个项目并完成计费部分。

添加变量

//Autocomplete for location ----------------------------------------------
ArrayList<String> names;
String browserKey = "AIzaSyA.....................";
String url;
private static final String TAG_RESULT = "predictions";
ArrayAdapter<String> adapter;

在 oncreate 中添加此代码

    edtLocation = (AutoCompleteTextView) findViewById(R.id
            .edt_location);
    edtLocation.setThreshold(1);


    names = new ArrayList<String>();
    edtLocation.addTextChangedListener(new TextWatcher() 

        public void afterTextChanged(Editable s) 

        

        public void beforeTextChanged(CharSequence s, int start, int count,
                                      int after) 

        

        public void onTextChanged(CharSequence s, int start, int before,
                                  int count) 

            if (s.toString().length() <= 6) 

                names = new ArrayList<String>();
                updateList(s.toString());


            


        
    );

在你的活动中添加这个方法

  //Method to get location suggestion
public void updateList(String place) 
    String input = "";

    try 
        input = "input=" + URLEncoder.encode(place, "utf-8");
     catch (UnsupportedEncodingException e1) 
        e1.printStackTrace();
    

    String output = "json";
    String parameter = input + "&types=(regions)&sensor=true&key="
            + browserKey;

    url = "https://maps.googleapis.com/maps/api/place/autocomplete/"
            + output + "?" + parameter;


    Log.e("browsekey", browserKey);
    Log.e("URL-LOCation", url);

    JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, url,
            null, new Response.Listener<JSONObject>() 

        @Override
        public void onResponse(JSONObject response) 

            System.out.println("keyresponse==>>" + response.toString());

            try 

                JSONArray ja = response.getJSONArray(TAG_RESULT);

                for (int i = 0; i < ja.length(); i++) 
                    JSONObject c = ja.getJSONObject(i);
                    String description = c.getString("description");
                    Log.d("description", description);
                    names.add(description);
                

                adapter = new ArrayAdapter<String>(
                        getApplicationContext(),
                        android.R.layout.simple_list_item_1, names) 
                    @Override
                    public View getView(int position,
                                        View convertView, ViewGroup parent) 
                        View view = super.getView(position, convertView, parent);
                        TextView text = (TextView) view.findViewById(android.R.id.text1);
                        text.setTextColor(Color.BLACK);
                        return view;
                    
                ;
                edtLocation.setAdapter(adapter);
                adapter.notifyDataSetChanged();
             catch (Exception e) 
            
        
    , new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 
        
    );
    MyApplication.getInstance().addToReqQueue(jsonObjReq, "jreq");

添加MyApplication类调用webservice

public class MyApplication extends Application 

private RequestQueue mRequestQueue;
private static MyApplication mInstance;

@Override
public void onCreate() 
    super.onCreate();
    mInstance = this;


public static synchronized MyApplication getInstance() 
    return mInstance;


public RequestQueue getReqQueue() 
    if (mRequestQueue == null) 
        mRequestQueue = Volley.newRequestQueue(getApplicationContext());
    

    return mRequestQueue;


public <T> void addToReqQueue(Request<T> req, String tag) 

    getReqQueue().add(req);


public <T> void addToReqQueue(Request<T> req) 

    getReqQueue().add(req);


public void cancelPendingReq(Object tag) 
    if (mRequestQueue != null) 
        mRequestQueue.cancelAll(tag);
    

【讨论】:

以上是关于Android:在 android Places Api 中提供自动自动建议?的主要内容,如果未能解决你的问题,请参考以下文章

适用于 Android 的 Google Places API 未显示

获取适用于 Android 的 Google Places API 密钥

无法解决:com.google.android.libraries.places:1.0.0:

如何使用 Android Places API AutocompleteFilter

在 Android 中,在列表中显示 Google Places JSON 数据?

程序类型已存在:com.google.android.gms.location.places.zza