Получите широту и долготу из SQLite и поместите соответствующий маркер каждые две минуты Android

Друзья, я могу получить широту и долготу из SqliteDb, чтобы разместить маркер на карте Google соответственно. Но моя проблема 1. Я хочу нарисовать маршрут от текущего местоположения до широты и долготы, полученных из Sqlite Db 2. Значения db широты и долготы будут меняться каждые 2 минуты, и я хочу соответственно изменить место в маркере и также маршрут между обновленными значениями и текущим местоположением.

Я попытался запустить приведенный ниже код. Он отлично работает в основном классе, но когда я попытался использовать поток, он терпит неудачу и с тех пор использует таймер для того же.

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

person Munchoo    schedule 13.02.2015    source источник
comment
почему нельзя сначала загрузить все маркеры, а потом периодически показывать?   -  person Hades    schedule 13.02.2015
comment
@Hades маркеры меняются каждые 2 минуты. Это приложение, основанное на отслеживании курьера.   -  person Munchoo    schedule 13.02.2015


Ответы (1)


Решения вашего вопроса: -

  1. Следующий код используется для отображения маршрута из одной точки в другую:

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

Включите вышеуказанный класс, а затем добавьте следующие коды в класс, в котором вы хотите отобразить маршрут к карте:

/** 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;
}

Теперь вызов начинается следующим образом:

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

Здесь пользователь userLocation — это мое текущее местоположение, а dest_lat, dest_long — это широта и долгота пункта назначения, а в onPostExecute ParserTask строка «map.addPolyline (lineOptions);» добавляет маршрут на карту, поэтому замените его собственной картой.

  1. Теперь для этой проблемы создайте тему и поставьте сон на 2 минуты или больше. Внутри этого потока вызовите базу данных и извлеките lat, long и вызовите вышеуказанные методы (решение 1), таким образом, ваш маршрут будет обновляться каждые 2 минуты или более, и не забудьте вызвать map.clear(), чтобы очистить существующий маршрут .

Вот моя реализация timerTask и она отлично работает -

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

}

Здесь я установил постоянную задержку 10 секунд и начальную задержку 5 секунд, все работает нормально.

person Debu    schedule 13.02.2015
comment
первый вариант работает, но меня больше всего беспокоит второй момент, если я использую таймер, приложение падает. В моем коде выше я запускаю поток, используя timertask каждые 50 секунд. Поэтому любое решение для этого - person Munchoo; 13.02.2015
comment
попробуйте использовать timertask таким образом и изменить значения задержки. - person Debu; 13.02.2015
comment
Я получаю сообщение об ошибке, например, размещение маркера в основном потоке приводит к сбою при вставке отчета журнала ошибок java.lang.IllegalStateException: Not on the main thread at com.google.kacj.b(Unknown Source) at com.google. maps.api.android.lib6.c.bz.a(неизвестный источник) на com.google.maps.api.android.lib6.c.es.a(неизвестный источник) на com.google.android.gms.maps. internal.l.onTransact(SourceFile:167) в android.os.Binder.transact(Binder.java:361) в com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.addMarker(неизвестный источник) в com.google.android.gms.maps.GoogleMap.addMarker (неизвестный источник) - person Munchoo; 13.02.2015