如何从Google Directions API获取距离和持续时间

时间:2013-06-17 20:08:51

标签: android xml google-direction


我正在开发一个Android应用,我在其中创建了一个活动,其中显示了从Google Directions API获取的路线列表。
使用的网址如下:http://maps.googleapis.com/maps/api/directions/xml?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false

结果是这样的:

<DirectionsResponse>
 <status>OK</status>
 <route>
  <summary>I-40 W</summary>
  <leg>
   <step>
    <travel_mode>DRIVING</travel_mode>
    <start_location>
     <lat>41.8507300</lat>
     <lng>-87.6512600</lng>
    </start_location>
    <end_location>
     <lat>41.8525800</lat>
     <lng>-87.6514100</lng>
    </end_location>
    <polyline>
     <points>a~l~Fjk~uOwHJy@P</points>
    </polyline>
    <duration>
     <value>19</value>
     <text>1 min</text>
    </duration>
    <html_instructions>Head <b>north</b> on <b>S Morgan St</b> toward <b>W Cermak Rd</b></html_instructions>
    <distance>
     <value>207</value>
     <text>0.1 mi</text>
    </distance>
   </step>
   ...
   ... additional steps of this leg
  ...
  ... additional legs of this route
   <duration>
    <value>74384</value>
    <text>20 hours 40 mins</text>
   </duration>
   <distance>
    <value>2137146</value>
    <text>1,328 mi</text>
   </distance>
   <start_location>
    <lat>35.4675602</lat>
    <lng>-97.5164276</lng>
   </start_location>
   <end_location>
    <lat>34.0522342</lat>
    <lng>-118.2436849</lng>
   </end_location>
   <start_address>Oklahoma City, OK, USA</start_address>
   <end_address>Los Angeles, CA, USA</end_address>
  <copyrights>Map data ©2010 Google, Sanborn</copyrights>
  <overview_polyline>
   <points>a~l~Fjk~uOnzh@vlbBtc~@tsE`vnApw{A`dw@~w\|tNtqf@l{Yd_Fblh@rxo@b}@xxSfytAblk@xxaBeJxlcBb~t@zbh@jc|Bx}C`rv@rw|@rlhA~dVzeo@vrSnc}Axf]fjz@xfFbw~@dz{A~d{A|zOxbrBbdUvpo@`cFp~xBc`Hk@nurDznmFfwMbwz@bbl@lq~@loPpxq@bw_@v|{CbtY~jGqeMb{iF|n\~mbDzeVh_Wr|Efc\x`Ij{kE}mAb~uF{cNd}xBjp]fulBiwJpgg@|kHntyArpb@bijCk_Kv~eGyqTj_|@`uV`k|DcsNdwxAott@r}q@_gc@nu`CnvHx`k@dse@j|p@zpiAp|gEicy@`omFvaErfo@igQxnlApqGze~AsyRzrjAb__@ftyB}pIlo_BflmA~yQftNboWzoAlzp@mz`@|}_@fda@jakEitAn{fB_a]lexClshBtmqAdmY_hLxiZd~XtaBndgC</points>
  </overview_polyline>
  <optimized_waypoint_index>0</optimized_waypoint_index>
  <optimized_waypoint_index>1</optimized_waypoint_index>
  <bounds>
   <southwest>
    <lat>34.0523600</lat>
    <lng>-118.2435600</lng>
   </southwest>
   <northeast>
    <lat>41.8781100</lat>
    <lng>-87.6297900</lng>
   </northeast>
  </bounds>
 </route>
</DirectionsResponse>

在列表的每个项目中,我想要显示<html_instructions>的{​​{1}},<text>孩子以及<distance> <text>孩子所包含的信息。 我能够使用此解析器获取<duration>标记的值:

<html_instructions>

如何修改此解析器以显示其他两个标记的值?

1 个答案:

答案 0 :(得分:0)

我能够通过在XMLParser类中添加另一个方法来解决这个问题:

public String getSecondValue(Element item, String str) {      
    NodeList n = item.getElementsByTagName(str);        
    return this.getElementValue(n.item(1));
}

以下是活动中的用法:

import java.util.ArrayList;
import java.util.HashMap;

import maps.XMLParser;

import org.apache.commons.lang3.StringEscapeUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;


public class DirectionsActivity extends ListActivity {

    String url = "";
    XMLParser parser;
    String xml = "";
    ArrayList<HashMap<String, String>> menuItems;

    // All static variables
    static final String KEY_STEP = "step"; // parent node
    static final String KEY_HTML_INSTRUCTIONS = "html_instructions";
    static final String KEY_DURATION = "duration";
    static final String KEY_DISTANCE = "distance";
    static final String KEY_TEXT = "text";



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

        Intent intent = this.getIntent();

        url = intent.getExtras().getString("url");
        System.out.println("---------------" + url);

        menuItems = new ArrayList<HashMap<String, String>>();

        parser = new XMLParser();

        DownloadTask downloadTask = new DownloadTask();

        // Start downloading XML data from Google Directions API
        downloadTask.execute(url);

        // selecting single ListView item
        ListView lv = getListView();        

        // listening to single listitem click
        lv.setOnItemClickListener(new OnItemClickListener() {

           @Override
           public void onItemClick(AdapterView<?> parent, View view,
                   int position, long id) {
               // getting values from selected ListItem
               String instruction = ((TextView) view.findViewById(R.id.instruction)).getText().toString();

               // Starting new intent
               Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
               in.putExtra(KEY_HTML_INSTRUCTIONS, instruction);

               startActivity(in);

           }
       });
    }

    /** A class to download data from Google Directions URL */
    private class DownloadTask extends AsyncTask<String, Void, String>{

        ListAdapter adapter;
        private ProgressDialog pd;

        @Override
        protected void onPreExecute() {
                 pd = new ProgressDialog(DirectionsActivity.this);
                 pd.setTitle("Processing...");
                 pd.setMessage("Calcolo direzione in corso dalla posizione corrente...");
                 pd.setCancelable(false);
                 pd.setIndeterminate(true);
                 pd.show();
        }

        // Downloading data in non-ui thread
        @Override
        protected String doInBackground(String... url) {

            // For storing data from web service
            String data = "";

            try{
                // Fetching the data from web service
                data = parser.getXmlFromUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;
        }

        // Executes in UI thread, after the execution of
        // doInBackground()
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result); 

            Document doc = parser.getDomElement(result); // getting DOM element

            NodeList nl = doc.getElementsByTagName(KEY_STEP);
            // looping through all item nodes <step>
            for (int i = 0; i < nl.getLength(); i++) {
                // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();
                Element e = (Element) nl.item(i);
                // adding each child node to HashMap key => value
                String escapedKeyHtmlInstructions = StringEscapeUtils.escapeHtml4(KEY_HTML_INSTRUCTIONS);
                // KEY_HTML_INSTRUCTIONS.replaceAll("\\<.*?>", "");
                map.put(KEY_HTML_INSTRUCTIONS, parser.getValue(e, escapedKeyHtmlInstructions));
                map.put(KEY_DURATION, parser.getValue(e, KEY_TEXT));
                map.put(KEY_DISTANCE, parser.getSecondValue(e, KEY_TEXT));

                // adding HashList to ArrayList
                menuItems.add(map);
            }

            // Adding menuItems to ListView
            adapter = new SimpleAdapter(DirectionsActivity.this, menuItems,R.layout.list_item,
                    new String[] { KEY_HTML_INSTRUCTIONS, KEY_DURATION, KEY_DISTANCE}, new int[] {
                            R.id.instruction, R.id.duration, R.id.distance});

            setListAdapter(adapter);

            pd.dismiss();
        }
    }

}