Mapas

Recomendaci贸n

No probar ejercicios que impliquen geolocalizaci贸n en el emulador. Unos funcionan, otros no, otros funcionan mal, etc.

Geolocalizaci贸n

La podemos obtener por 3 medios:

  • GPS: (el m谩s preciso y lento (puede tardar incluso m谩s de un minuto)). 2 metros de error.
  • Red m贸vil: El m贸vil detecta 3 antenas, hace un tri谩ngulo (el m茅todo se llama triangulaci贸n) y detecta la posici贸n (con un margen de error de 20, 50 m…) depende de la distancia con las antenas. En ciudad hay menos error que en el campo. Tarda unos segundos
  • Wi-Fi: Funciona si estoy conectado a una red WI-FI. El m贸vil detecta el SSID (nombre de la red) de la wi-fi y accede a una base de datos donde tiene registrada su ubicaci贸n.

La geolocalizacion del emulador no funciona correctamente pq no tiene ni gps, ni red movil ni han integrado la geolocalizaci贸n por wi-fi.
Para falsear la geolocalizaci贸n del emulador: window-> show view -> other -> emulator control
Habr谩 que asegurarse de tener el device seleccionado en el momento de pulsar el bot贸n de send.

Habr谩 que a帽adir los siguientes permisos:
<!--Localizaci贸n usando la red WI-FI: -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--Localizaci贸n usando el GPS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Location Manager

Vamos a mostrar las coordenadas en un TextView

Tendremos que solicitar permisos al usuario de forma similar a como lo hicimos cuando quer铆amos聽acceder a los contactos.

private static final int MY_PERMISSIONS_CODE = 999;

private TextView coordenadas;

private LocationManager locationManager;
private LocationListener listener = new LocationListener() {
	public void onLocationChanged(Location location) {
		coordenadas.setText("Latitud: " + location.getLatitude() + "Longitud: " + location.getLongitude());
	}

	@Override public void onStatusChanged(String provider, int status, Bundle extras) {}
	@Override public void onProviderEnabled(String provider) {}
	@Override public void onProviderDisabled(String provider) {}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.mapas_locationmanager);
	coordenadas = findViewById(R.id.coordenadas);
	locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
	checkPermisions();
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
	switch (requestCode) {
		case MY_PERMISSIONS_CODE: {
			if (grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED) {
				requestLocation();
			} else {
				// permission denied, boo! Disable the  functionality that depends on this permission.
			}
		}
	}
}

public void onResume() {
	super.onResume();
	requestLocation();
}

public void onPause() {
	super.onPause();
	locationManager.removeUpdates(listener);
}

private void checkPermisions() {
	if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
		if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
				ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
			ActivityCompat.requestPermissions(this,
					new String[]{
							Manifest.permission.ACCESS_FINE_LOCATION,
							Manifest.permission.ACCESS_COARSE_LOCATION,
							Manifest.permission.INTERNET,
					},
					MY_PERMISSIONS_CODE);
		} else {
			requestLocation();
		}
	} else {
		requestLocation();
	}
}

@SuppressLint("MissingPermission")
private void requestLocation() {
	locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, listener);
	locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0, listener);
}

A帽adir un mapa

驴Qu茅 es un fragmento?

Es una parte de una Activity, que tiene su propio ciclo de vida, recibe sus propios eventos de entrada, y que se puede a帽adir o quitar din谩micamente.

Paso 1: Cargar las librer铆as

  1. Obtener una Map API Key (modo debug)https://cloud.google.com/console 鈫 Seleccionamos en la barra horizontal superior el proyecto actual y se abrir谩 un panel que nos permitir谩 crear un nuevo proyecto 鈫 Create Project 鈫 APIs 鈫 go to the api’s overview 鈫 enable API 鈫 Maps SDK for Android 鈫 Enable 鈫 Credentials 鈫 Credenciales en APIs y servicios 鈫 Create Credentials 鈫 Clave de API 鈫 anotamos la API key.
  2. Vista Android 鈫 Gradle Scripts 鈫 build.gradle (de m贸dulo) 鈫 en dependencias a帽ado lo siguiente:
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-base:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'

3. Adem谩s, en el layout habr谩 que a帽adir el siguiente c贸digo que representar谩 el mapa:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>

Paso 2: modificar el AndroidManifest.xml

	<meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyDKH-mnui5hMmO3wnTdrmXy4V5IVs6KTR8" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>
</manifest>

Paso 3: A帽adir el mapa en el c贸digo Java

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
	protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	SupportMapFragment mapFragment  = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
	mapFragment.getMapAsync(this);
}

Centrar mapa en la posici贸n del usuario y seguirlo

@SuppressLint("MissingPermission")
private void requestLocation() {
	Location currentLocation = null;
	for(String provider: locationManager.getAllProviders()){
		Location aux = locationManager.getLastKnownLocation(provider);
		if(aux!=null){
			Log.d("traza", "best Provider " + provider);
			currentLocation = aux;
			break;
		}
	}
	if (currentLocation!=null) {
		updateMapaWith(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()));
	}
	Log.d("traza", "last location " + currentLocation);
	locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, listener);
	locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0, listener);
}

private void updateMapaWith(LatLng latLng){
	if (googleMap != null) {
		CameraPosition camPos = new CameraPosition.Builder()
		.target(latLng)   //Centramos el mapa en Madrid
		.zoom(19)          //Establecemos el zoom en 19
		.bearing(45)       //Establecemos la orientaci贸n con el noreste arriba
		.tilt(70)          //Bajamos el punto de vista de la c谩mara 70 grados
		.build();

		CameraUpdate camUpd = CameraUpdateFactory.newCameraPosition(camPos);
		googleMap.animateCamera(camUpd);
	}
}

A帽adir un marcador

googleMap.addMarker(new MarkerOptions()
	.position(new LatLng(41.431725, 2.192188))
	.snippet("Tadel Formaci贸")
	.title("Centre de formaci贸")
	.icon(BitmapDescriptorFactory.fromResource(R.drawable.escudo)));

Ejercicio Sqlite

Hacer una aplicaci贸n que utilizando una base de datos SqlLite situe en pantalla 3 puntos, identificados por el logo suministrado. Al pulsar sobre el logo, iremos a una pantalla d贸nde se mostrar谩 informaci贸n del enclave pulsado.

Recursos:

Utilizaremos el HashMap tabla para que al hacer click en un marker podamos obtener su id y a continuaci贸n pas谩rsela al siguiente activity:monumentos聽es un HashMap de objetos Monumento.

@Override
public boolean onMarkerClick(Marker arg0) {
	int idMonumento = tabla.get(arg0);			
	startActivity(new Intent(this,LugarActivity.class).putExtra(MONUMENTO, monumentos.get(idMonumento)));
	return true;
}
Para recibir el monumento:
Monumento monumento = (Monumento) getIntent().getExtras().getSerializable(GeolocalizacionCapasActivity.MONUMENTO);

Obtener la ubicaci贸n de cierto lugar

String direccion = "Camino de Rubin 2, Gij贸n";

Geocoder geocoder = new Geocoder(this);  
List<Address> addresses;
addresses = geocoder.getFromLocationName(direccion, 1);
if(addresses.size() > 0) {
	double latitude= addresses.get(0).getLatitude();
	double longitude= addresses.get(0).getLongitude();
	tv.setText("Latitud="+latitude+" Longitud="+longitude);
}

Rutas

Debemos activar la Directions API en la secci贸n API’s overview de la Google Developer Console.

Tambi茅n debemos activar la facturaci贸n para esta cuenta. Ojo con todo lo que ello conlleva.

MainActivity.java
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, TaskLoadedCallback {

    private GoogleMap mMap;
    private MarkerOptions place1, place2;
    Button getDirection;
    private Polyline currentPolyline;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rutas);
        //27.658143,85.3199503
        //27.667491,85.3208583
        place1 = new MarkerOptions().position(new LatLng(22.3039, 70.8022)).title("Location 1");
        place2 = new MarkerOptions().position(new LatLng(23.0225, 72.5714)).title("Location 2");

        new FetchURL(MainActivity.this).execute(getUrl(place1.getPosition(), place2.getPosition(), "driving"), "driving");

        SupportMapFragment miMapa = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

        miMapa.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        Log.d("mylog", "Added Markers");
        mMap.addMarker(place1);
        mMap.addMarker(place2);

        CameraPosition googlePlex = CameraPosition.builder()
                .target(new LatLng(22.7739,71.6673))
                .zoom(7)
                .bearing(0)
                .tilt(45)
                .build();

        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(googlePlex), 5000, null);
    }

    private String getUrl(LatLng origin, LatLng dest, String directionMode) {
        // Origin of route
        String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
        // Destination of route
        String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
        // Mode
        String mode = "mode=" + directionMode;
        // Building the parameters to the web service
        String parameters = str_origin + "&" + str_dest + "&" + mode;
        // Output format
        String output = "json";
        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters + "&key=AIzaSyBKJ43pjK3x1GQjnO0zaYUwDJHdy5LiooU";
        return url;
    }

    @Override
    public void onTaskDone(Object... values) {
        if (currentPolyline != null)
            currentPolyline.remove();
        currentPolyline = mMap.addPolyline((PolylineOptions) values[0]);
    }
}
TaskLoadedCallback.java
public interface TaskLoadedCallback {
    void onTaskDone(Object... values);
}
FetchURL.java
public class FetchURL extends AsyncTask<String, Void, String> {
    Context mContext;
    String directionMode = "driving";

    public FetchURL(Context mContext) {
        this.mContext = mContext;
    }

    @Override
    protected String doInBackground(String... strings) {
        // For storing data from web service
        String data = "";
        directionMode = strings[1];
        try {
            // Fetching the data from web service
            data = downloadUrl(strings[0]);
            Log.d("mylog", "Background task data " + data.toString());
        } catch (Exception e) {
            Log.d("Background Task", e.toString());
        }
        return data;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        PointsParser parserTask = new PointsParser(mContext, directionMode);
        // Invokes the thread for parsing the JSON data
        parserTask.execute(s);
    }

    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();
            Log.d("mylog", "Downloaded URL: " + data.toString());
            br.close();
        } catch (Exception e) {
            Log.d("mylog", "Exception downloading URL: " + e.toString());
        } finally {
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
}
DataParser.java
public class DataParser {
    public List<List<HashMap<String, String>>> parse(JSONObject jObject) {

        List<List<HashMap<String, String>>> routes = new ArrayList<>();
        JSONArray jRoutes;
        JSONArray jLegs;
        JSONArray jSteps;
        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<>();
                /** 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<>();
                            hm.put("lat", Double.toString((list.get(l)).latitude));
                            hm.put("lng", Double.toString((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
     * Courtesy : https://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
     */
    private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<>();
        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;
    }
}
PointsParser.java
package com.pablomonteserin.mapas.rutas2;

import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolylineOptions;

import org.json.JSONObject;

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



public class PointsParser extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
    TaskLoadedCallback taskCallback;
    String directionMode = "driving";

    public PointsParser(Context mContext, String directionMode) {
        this.taskCallback = (TaskLoadedCallback) mContext;
        this.directionMode = directionMode;
    }

    // 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]);
            Log.d("mylog", jsonData[0].toString());
            DataParser parser = new DataParser();
            Log.d("mylog", parser.toString());

            // Starts parsing data
            routes = parser.parse(jObject);
            Log.d("mylog", "Executing routes");
            Log.d("mylog", routes.toString());

        } catch (Exception e) {
            Log.d("mylog", e.toString());
            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;
        PolylineOptions lineOptions = null;
        // Traversing through all the routes
        for (int i = 0; i < result.size(); i++) {
            points = new ArrayList<>();
            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);
            if (directionMode.equalsIgnoreCase("walking")) {
                lineOptions.width(3);
                lineOptions.color(Color.MAGENTA);
            } else {
                lineOptions.width(3);
                lineOptions.color(Color.RED);
            }
            Log.d("mylog", "onPostExecute lineoptions decoded");
        }

        // Drawing polyline in the Google Map for the i-th route
        if (lineOptions != null) {
            //mMap.addPolyline(lineOptions);
            taskCallback.onTaskDone(lineOptions);

        } else {
            Log.d("mylog", "without Polylines drawn");
        }
    }
}
Volver a: Android

Aviso Legal | Pol铆tica de privacidad