google distance matrix with autocomplete on android-Collection of common programming errors

I am trying to do what the header is saying, which is to create an app with google distance matrix with autocomplete on android. So far, with my research and studying on the books myself, it is very difficult to come up with the code and I finally reach out here. So far I have gone to

https://developers.google.com/maps/documentation/distancematrix/#Introduction

and google directions document

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

All these links have not really helped me understand it and I do understand the concept of Requesting to the API address and it returning the JSON and I have to “Parse” the JSON and extract the necessary information, which is the distance in my case. but what I do not get is how I can create an autocomplete that has suggestion from the google maps distance matrix and also how I can send the origin and destination accordingly. It is really frustrating and this is what I have from the Claytical.com.

Here’s the 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 adapter;
public AutoCompleteTextView textview;
public Object s;

class GetPlaces extends AsyncTask
{
public ArrayAdapter adapter;
public AutoCompleteTextView textview;
Object s;


@Override
           // three dots is java for an array of strings
protected ArrayList doInBackground(String... args)
{

Log.d("gottaGo", "doInBackground");

ArrayList predictionsArr = new ArrayList();

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=");
        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 result)
{

Log.d("YourApp", "onPostExecute : " + result.size());
//update the adapter
ArrayAdapter adapter = new ArrayAdapter(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 adapter = new ArrayAdapter(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) {

}
});






}
}

and my main.xml





    

Lastly, here’s LOGCAT as requested.

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

It launches just fine and it brings up the auto complete textview but as soon as I type a letter, it crashes. Thanks for reading this far and Thank you in advance for your help!

  1. OK first thing is that your URL is malformed:

    https://maps.googleapis.com/maps/api/place/autocomplete/json?input=" + URLEncoder.encode(s.toString(), "UTF-8") + "&types=geocode&language=en&sensor=true&key=
    

    You need to replace with your API key for it to work. Next thing is how you form your JSON array. You need to replace

    JSONArray ja = new JSONArray(predictions.getString("predictions"));
    

    with

    JSONArray ja = new JSONArray(predictions.getJSONArray("predictions"));
    

    Next in your loop, replace

    JSONObject jo = (JSONObject) ja.get(i);
    

    with

    JSONObject jo = ja.getJSONObject(i);
    

    Try this and let me know how it goes.