1

Friends, Am able to fetch the latitude and longitude from SqliteDb to place a marker in google Map respectively. But my problem is 1. I want to draw a route from current location to the latitude and longitude fetched from Sqlite Db 2. The db values of Latitude and Longitude will be changed every 2 minutes and i want to change the place in marker accordingly and also route between the updated values and current location.

I have tried running the below code. It runs perfect in Main class but when I tried using thread it fails and since used timer for the same.

protected void mLocActivity() {

    db.open();
    class preciLoc extends TimerTask{
        @Override
        public void run() {

        Cursor cr = db.fetchone(sLoc, "pos_mark", tblName, "pho", null, null);

        if(cr.getCount()>0){                
        sLat =  cr.getString(cr.getColumnIndex("lat"));
        sLon =  cr.getString(cr.getColumnIndex("lon"));
        }

        LatLng orgLoc = new LatLng(mLatitude,mLongitude);
        LatLng desCur = new LatLng(Double.parseDouble(sLat), Double.parseDouble(sLon));
        String url = getDirectionsUrl(orgLoc, desCur);

        DownloadTask downloadTask = new DownloadTask();

        downloadTask.execute(url);
        rMap.moveCamera(CameraUpdateFactory.newLatLng(latLng))
        CameraPosition camPos1 = new CameraPosition.Builder()
                .target(destCurr).zoom(15).bearing(90).tilt(30).build();
        rMap.animateCamera(CameraUpdateFactory
                .newCameraPosition(camPos1));
        drawMarker(desCur);         
        }           
    }
    Timer timer = new Timer();
    timer.schedule(new preciLoc(), 50000);
}
Munchoo
  • 313
  • 1
  • 7
  • 22

1 Answers1

0

The solutions to your question are :-

  1. The following code is used to display route from one point to another-

public class DirectionsJSONParser {
 
 /** Receives a JSONObject and returns a list of lists containing latitude and longitude */
 public List<List<HashMap<String,String>>> parse(JSONObject jObject){
  
  List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
  JSONArray jRoutes = null;
  JSONArray jLegs = null;
  JSONArray jSteps = null; 
  
  try {   
   
   jRoutes = jObject.getJSONArray("routes");
   
   /** Traversing all routes */
   for(int i=0;i<jRoutes.length();i++){   
    jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
    List path = new ArrayList<HashMap<String, String>>();
    
    /** Traversing all legs */
    for(int j=0;j<jLegs.length();j++){
     jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
     
     /** Traversing all steps */
     for(int k=0;k<jSteps.length();k++){
      String polyline = "";
      polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
      List<LatLng> list = decodePoly(polyline);
      
      /** Traversing all points */
      for(int l=0;l<list.size();l++){
       HashMap<String, String> hm = new HashMap<String, String>();
       hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
       hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
       path.add(hm);      
      }        
     }
     routes.add(path);
    }
   }
   
  } catch (JSONException e) {   
   e.printStackTrace();
  }catch (Exception e){   
  }
  
  
  return routes;
 } 
 
 
 /**
  * Method to decode polyline points  
  * */
    private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<LatLng>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }

        return poly;
    }
}

Include the above class and then add the following codes to the class where you want to display the route to the map-

/** A method to download json data from url */
 private String downloadUrl(String strUrl) throws IOException {
  String data = "";
  InputStream iStream = null;
  HttpURLConnection urlConnection = null;
  try {
   URL url = new URL(strUrl);

   // Creating an http connection to communicate with url
   urlConnection = (HttpURLConnection) url.openConnection();

   // Connecting to url
   urlConnection.connect();

   // Reading data from url
   iStream = urlConnection.getInputStream();

   BufferedReader br = new BufferedReader(new InputStreamReader(
     iStream));

   StringBuffer sb = new StringBuffer();

   String line = "";
   while ((line = br.readLine()) != null) {
    sb.append(line);
   }

   data = sb.toString();

   br.close();

  } catch (Exception e) {
   Log.d("Exception while downloading url", e.toString());
  } finally {
   iStream.close();
   urlConnection.disconnect();
  }
  return data;
 }

 // Fetches data from url passed
 private class DownloadTask extends AsyncTask<String, Void, String> {

  // 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 = downloadUrl(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);

   ParserTask parserTask = new ParserTask();

   // Invokes the thread for parsing the JSON data
   parserTask.execute(result);

  }
 }

 /** A class to parse the Google Places in JSON format */
 private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

  // Parsing the data in non-ui thread
  @Override
  protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

   JSONObject jObject;
   List<List<HashMap<String, String>>> routes = null;

   try {
    jObject = new JSONObject(jsonData[0]);
    DirectionsJSONParser parser = new DirectionsJSONParser();

    // Starts parsing data
    routes = parser.parse(jObject);
   } catch (Exception e) {
    e.printStackTrace();
   }
   return routes;
  }

  // Executes in UI thread, after the parsing process
  @Override
  protected void onPostExecute(List<List<HashMap<String, String>>> result) {
   ArrayList<LatLng> points = null;
   PolylineOptions lineOptions = null;
   MarkerOptions markerOptions = new MarkerOptions();

   // Traversing through all the routes
   for (int i = 0; i < result.size(); i++) {
    points = new ArrayList<LatLng>();
    lineOptions = new PolylineOptions();

    // Fetching i-th route
    List<HashMap<String, String>> path = result.get(i);

    // Fetching all the points in i-th route
    for (int j = 0; j < path.size(); j++) {
     HashMap<String, String> point = path.get(j);

     double lat = Double.parseDouble(point.get("lat"));
     double lng = Double.parseDouble(point.get("lng"));
     LatLng position = new LatLng(lat, lng);

     points.add(position);
    }

    // Adding all the points in the route to LineOptions
    lineOptions.addAll(points);
    lineOptions.width(4);
    lineOptions.color(Color.RED);

   }

   // Drawing polyline in the Google Map for the i-th route
   map.addPolyline(lineOptions);
  }
 }

private String getDirectionsUrl(LatLng origin, LatLng dest) {

 // Origin of route
 String str_origin = "origin=" + origin.latitude + ","
   + origin.longitude;

 // Destination of route
 String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

 // Sensor enabled
 String sensor = "sensor=false";

 // Building the parameters to the web service
 String parameters = str_origin + "&" + str_dest + "&" + sensor;

 // Output format
 String output = "json";

 // Building the url to the web service
 String url = "https://maps.googleapis.com/maps/api/directions/"
   + output + "?" + parameters;

 return url;
}

Now the call starts as follows-

// Getting URL to the Google Directions API

String url = getDirectionsUrl(new LatLng(userLocation.getLatitude(),
        userLocation.getLongitude()), new LatLng(
        dest_lat, dest_long));

    DownloadTask downloadTask = new DownloadTask();

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

Here user userLocation is my current location and dest_lat, dest_long is the destination lat, long and in onPostExecute of ParserTask the line "map.addPolyline(lineOptions);" adds route to the map, so replace it with your own map.

  1. Now for this problem create a thread and put a sleep of 2 min or more. Inside that thread call the database and retrive the lat,long and call the above methods(solution 1) , thus your route gets refreshed on every 2 min or more and don't forget to call map.clear() to clear the existing route.

Here is my implementation of timerTask and its working fine -

public class Test extends Activity {

 Timer timer;
 preciLoc loc;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.test);
  ..........
  timer = new Timer();
  loc = new preciLoc();
  timer.schedule(loc,5000, 10000);
 }

 class preciLoc extends TimerTask {
  @Override
  public void run() {
   Log.e("preciLoc", timer.toString());
  }
 }

}

Here I have set a constant delay of 10 sec and a initial delay of 5 sec, its working fine.

Debu
  • 615
  • 7
  • 21
  • first option is working but my main worry is second point if i use timer the app crashes. In my code above i am running thread using timertask every 50 sec. So any solution for that – Munchoo Feb 13 '15 at 09:08
  • try to use the timertask in this way and change the delay values. – Debu Feb 13 '15 at 10:32
  • I am getting error like placing a marker on main thread lead to crashing am pasting the Log of error report java.lang.IllegalStateException: Not on the main thread at com.google.k.a.cj.b(Unknown Source) at com.google.maps.api.android.lib6.c.bz.a(Unknown Source) at com.google.maps.api.android.lib6.c.es.a(Unknown Source) at com.google.android.gms.maps.internal.l.onTransact(SourceFile:167) at android.os.Binder.transact(Binder.java:361) at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.addMarker(Unknown Source) at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source) – Munchoo Feb 13 '15 at 14:19