我正在尝试做标题所说的内容,即在Android上创建一个带有google距离矩阵和自动完成功能的应用。到目前为止,我自己研究和研究这些书籍,很难想出代码,我终于到了这里。到目前为止,我已经去了
https://developers.google.com/maps/documentation/distancematrix/#Introduction
和google指示文档
http://www.claytical.com/blog/android-dynamic-autocompletion-using-google-places-api http://www.stackoverflow.com/questions/9142885/geocoder-autocomplete-in-android http://www.stackoverflow.com/questions/6456090/android-google-map-finding-distance/6456161#6456161
所有这些链接并没有真正帮助我理解它,我确实理解请求API地址的概念,它返回JSON,我必须“解析”JSON并提取必要的信息,这是距离我的情况。但我没有得到的是如何创建一个自动完成,其中包含谷歌地图距离矩阵的建议,以及我如何相应地发送原点和目的地。这真是令人沮丧,这就是我从Claytical.com获得的。
这是main.java
package com.example.autocomplete;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
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.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
public class Main extends Activity {
/** Called when the activity is first created. */
public ArrayAdapter<String> adapter;
public AutoCompleteTextView textview;
public Object s;
class GetPlaces extends AsyncTask<String, Void, ArrayList<String>>
{
public ArrayAdapter<String> adapter;
public AutoCompleteTextView textview;
Object s;
@Override
// three dots is java for an array of strings
protected ArrayList<String> doInBackground(String... args)
{
Log.d("gottaGo", "doInBackground");
ArrayList<String> predictionsArr = new ArrayList<String>();
try
{
URL googlePlaces = new URL(
// URLEncoder.encode(url,"UTF-8");
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input="+ URLEncoder.encode(s.toString(), "UTF-8") +"&types=geocode&language=en&sensor=true&key=<yourapikeygoeshere>");
URLConnection tc = googlePlaces.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
String line;
StringBuffer sb = new StringBuffer();
//take Google's legible JSON and turn it into one big string.
while ((line = in.readLine()) != null) {
sb.append(line);
}
//turn that string into a JSON object
JSONObject predictions = new JSONObject(sb.toString());
//now get the JSON array that's inside that object
JSONArray ja = new JSONArray(predictions.getString("predictions"));
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
//add each entry to our array
predictionsArr.add(jo.getString("description"));
}
} catch (IOException e)
{
Log.e("YourApp", "GetPlaces : doInBackground", e);
} catch (JSONException e)
{
Log.e("YourApp", "GetPlaces : doInBackground", e);
}
return predictionsArr;
}
//then our post
@Override
protected void onPostExecute(ArrayList<String> result)
{
Log.d("YourApp", "onPostExecute : " + result.size());
//update the adapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), R.layout.item_list);
adapter.setNotifyOnChange(true);
//attach the adapter to textview
textview.setAdapter(adapter);
for (String string : result)
{
Log.d("YourApp", "onPostExecute : result = " + string);
adapter.add(string);
adapter.notifyDataSetChanged();
}
Log.d("YourApp", "onPostExecute : autoCompleteAdapter" + adapter.getCount());
}
private Context getBaseContext() {
// TODO Auto-generated method stub
return null;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_list);
final AutoCompleteTextView textView = (AutoCompleteTextView)
findViewById(R.id.autoCompleteTextView1);
adapter.setNotifyOnChange(true);
textView.setAdapter(adapter);
textView.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count%3 == 1) {
adapter.clear();
GetPlaces task = new GetPlaces();
//now pass the argument in the textview to the task
task.execute(textView.getText().toString());
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable s) {
}
});
}
}
和我的main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#dddddd">
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginTop="10dp" >
<requestFocus></requestFocus>
</AutoCompleteTextView>
最后,这是LOGCAT的要求。
05-14 17:41:38.163: E/Trace(1390): error opening trace file: No such file or directory (2)
05-14 17:41:39.323: D/gralloc_goldfish(1390): Emulator without GPU emulation detected.
05-14 17:41:45.284: D/gottaGo(1390): doInBackground
05-14 17:41:45.296: W/dalvikvm(1390): threadid=11: thread exiting with uncaught exception (group=0x40a13300)
05-14 17:41:45.314: E/AndroidRuntime(1390): FATAL EXCEPTION: AsyncTask #1
05-14 17:41:45.314: E/AndroidRuntime(1390): java.lang.RuntimeException: An error occured while executing doInBackground()
05-14 17:41:45.314: E/AndroidRuntime(1390): at android.os.AsyncTask$3.done(AsyncTask.java:299)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-14 17:41:45.314: E/AndroidRuntime(1390): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.lang.Thread.run(Thread.java:856)
05-14 17:41:45.314: E/AndroidRuntime(1390): Caused by: java.lang.NullPointerException
05-14 17:41:45.314: E/AndroidRuntime(1390): at com.example.autocomplete.Main$GetPlaces.doInBackground(Main.java:54)
05-14 17:41:45.314: E/AndroidRuntime(1390): at com.example.autocomplete.Main$GetPlaces.doInBackground(Main.java:1)
05-14 17:41:45.314: E/AndroidRuntime(1390): at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-14 17:41:45.314: E/AndroidRuntime(1390): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-14 17:41:45.314: E/AndroidRuntime(1390): ... 5 more
05-14 17:41:47.584: I/Choreographer(1390): Skipped 31 frames! The application may be doing too much work on its main thread.
05-14 17:41:47.904: I/Process(1390): Sending signal. PID: 1390 SIG: 9
它启动很好,它会显示自动完整的文本视图,但只要我输入一个字母,它就会崩溃。 感谢您阅读本文,并提前感谢您的帮助!
答案 0 :(得分:0)
首先确定您的网址格式错误:
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=" + URLEncoder.encode(s.toString(), "UTF-8") + "&types=geocode&language=en&sensor=true&key=<yourapikeygoeshere>
您需要将<yourapikeygoeshere>
替换为API密钥才能生效。接下来是你如何形成你的JSON数组。你需要替换
JSONArray ja = new JSONArray(predictions.getString("predictions"));
带
JSONArray ja = new JSONArray(predictions.getJSONArray("predictions"));
接下来在循环中,替换
JSONObject jo = (JSONObject) ja.get(i);
与
JSONObject jo = ja.getJSONObject(i);
试试这个,让我知道它是怎么回事。
答案 1 :(得分:0)
我在开发过程中也使用相同的代码来设计自动完成文本视图我面临同样的问题并最终修复它。
两个人需要在Google控制台中启用“Google Place API for Android”和“Google Place API for Web Services”。
你还需要用URLEncoder.encode(args [0] .toString(),“UTF-8”)替换URLEncoder.encode(s.toString(),“UTF-8”)
我希望这会对你有所帮助。