Search code examples
androidandroid-asynctaskandroid-maps-v2android-mapsandroid-runonuithread

Get Latitude and Longitude from SQLite and place respective marker for every two minutes android


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);
}

Solution

  • 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.