android - programacion - ¿Cómo abrir una aplicación estándar de Google Map desde mi aplicación?
google maps sin internet android (7)
A veces, si no hay ninguna aplicación asociada con geo: protocal, puede usar try-catch para obtener la excepción ActivityNotFoundException para manejarla.
Sucede cuando usas algún emulador como androVM que no está instalado en el mapa de google de forma predeterminada.
Una vez que el usuario presiona el botón en mi aplicación, me gustaría abrir la aplicación estándar de Google Map y mostrar una ubicación en particular. ¿Cómo puedo hacerlo? (sin usar com.google.android.maps.MapView
)
Compruebe esta página de google:
http://developer.android.com/guide/appendix/g-app-intents.html
Puede usar un URI del formulario
geo:latitude,longitude
para abrir el visor de mapas de Google y señalarlo a una ubicación.
Debe crear un objeto Intent
con un URI geográfico:
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
Si desea especificar una dirección, debe usar otra forma de geo-URI: geo:0,0?q=address
.
referencia: https://developer.android.com/guide/components/intents-common.html#Maps
También puede usar http://maps.google.com/maps como su URI
String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "&daddr=" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
o puede asegurarse de que solo se use la aplicación Google Maps, esto impide que aparezca el filtro de intención (diálogo), al usar
intent.setPackage("com.google.android.apps.maps");
al igual que:
String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "&daddr=" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
o puede agregar etiquetas a las ubicaciones agregando una cadena entre paréntesis después de cada conjunto de coordenadas, como sigue:
String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "(" + "Home Sweet Home" + ")&daddr=" + destinationLatitude + "," + destinationLongitude + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
Para utilizar la ubicación actual de los usuarios como punto de partida (desafortunadamente no he encontrado una forma de etiquetar la ubicación actual), simplemente deje el parámetro saddr
siguiente manera:
String uri = "http://maps.google.com/maps?daddr=" + destinationLatitude + "," + destinationLongitude + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
Para completar, si el usuario no tiene instalada la aplicación de mapas, entonces será una buena idea atrapar la ActivityNotFoundException, como dice @TonyQ, entonces podemos comenzar la actividad nuevamente sin la restricción de la aplicación de mapas, podemos estar bastante seguros que nunca llegaremos al Toast al final, ya que un navegador de Internet es una aplicación válida para lanzar también este esquema de url.
String uri = "http://maps.google.com/maps?daddr=" + 12f + "," + 2f + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
try
{
startActivity(intent);
}
catch(ActivityNotFoundException ex)
{
try
{
Intent unrestrictedIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(unrestrictedIntent);
}
catch(ActivityNotFoundException innerEx)
{
Toast.makeText(this, "Please install a maps application", Toast.LENGTH_LONG).show();
}
}
EDITAR:
Para obtener instrucciones, ahora se admite un intento de navegación con google.navigation
Uri navigationIntentUri = Uri.parse("google.navigation:q=" + 12f " +"," + 2f);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, navigationIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
También puede usar el siguiente fragmento de código, de esta manera se verifica la existencia de google maps antes de que se inicie el intento.
Uri gmmIntentUri = Uri.parse(String.format(Locale.ENGLISH,"geo:%f,%f", latitude, longitude));
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
Referencia: https://developers.google.com/maps/documentation/android-api/intents
Tengo una aplicación de muestra en la que preparo el intento y solo paso CITY_NAME en la intención de la actividad del marcador de mapas, que finalmente calcula la longitud y la latitud mediante Geocoder usando CITY_NAME.
A continuación se muestra el fragmento de código para iniciar la actividad del marcador de mapas y la completa MapsMarkerActivity.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} else if (id == R.id.action_refresh) {
Log.d(APP_TAG, "onOptionsItemSelected Refresh selected");
new MainActivityFragment.FetchWeatherTask().execute(CITY, FORECAS_DAYS);
return true;
} else if (id == R.id.action_map) {
Log.d(APP_TAG, "onOptionsItemSelected Map selected");
Intent intent = new Intent(this, MapsMarkerActivity.class);
intent.putExtra("CITY_NAME", CITY);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
public class MapsMarkerActivity extends AppCompatActivity
implements OnMapReadyCallback {
private String cityName = "";
private double longitude;
private double latitude;
static final int numberOptions = 10;
String [] optionArray = new String[numberOptions];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve the content view that renders the map.
setContentView(R.layout.activity_map);
// Get the SupportMapFragment and request notification
// when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// Test whether geocoder is present on platform
if(Geocoder.isPresent()){
cityName = getIntent().getStringExtra("CITY_NAME");
geocodeLocation(cityName);
} else {
String noGoGeo = "FAILURE: No Geocoder on this platform.";
Toast.makeText(this, noGoGeo, Toast.LENGTH_LONG).show();
return;
}
}
/**
* Manipulates the map when it''s available.
* The API invokes this callback when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user receives a prompt to install
* Play services inside the SupportMapFragment. The API invokes this method after the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
// Add a marker in Sydney, Australia,
// and move the map''s camera to the same location.
LatLng sydney = new LatLng(latitude, longitude);
// If cityName is not available then use
// Default Location.
String markerDisplay = "Default Location";
if (cityName != null
&& cityName.length() > 0) {
markerDisplay = "Marker in " + cityName;
}
googleMap.addMarker(new MarkerOptions().position(sydney)
.title(markerDisplay));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
/**
* Method to geocode location passed as string (e.g., "Pentagon"), which
* places the corresponding latitude and longitude in the variables lat and lon.
*
* @param placeName
*/
private void geocodeLocation(String placeName){
// Following adapted from Conder and Darcey, pp.321 ff.
Geocoder gcoder = new Geocoder(this);
// Note that the Geocoder uses synchronous network access, so in a serious application
// it would be best to put it on a background thread to prevent blocking the main UI if network
// access is slow. Here we are just giving an example of how to use it so, for simplicity, we
// don''t put it on a separate thread. See the class RouteMapper in this package for an example
// of making a network access on a background thread. Geocoding is implemented by a backend
// that is not part of the core Android framework, so we use the static method
// Geocoder.isPresent() to test for presence of the required backend on the given platform.
try{
List<Address> results = null;
if(Geocoder.isPresent()){
results = gcoder.getFromLocationName(placeName, numberOptions);
} else {
Log.i(MainActivity.APP_TAG, "No Geocoder found");
return;
}
Iterator<Address> locations = results.iterator();
String raw = "/nRaw String:/n";
String country;
int opCount = 0;
while(locations.hasNext()){
Address location = locations.next();
if(opCount == 0 && location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
country = location.getCountryName();
if(country == null) {
country = "";
} else {
country = ", " + country;
}
raw += location+"/n";
optionArray[opCount] = location.getAddressLine(0)+", "
+location.getAddressLine(1)+country+"/n";
opCount ++;
}
// Log the returned data
Log.d(MainActivity.APP_TAG, raw);
Log.d(MainActivity.APP_TAG, "/nOptions:/n");
for(int i=0; i<opCount; i++){
Log.i(MainActivity.APP_TAG, "("+(i+1)+") "+optionArray[i]);
}
Log.d(MainActivity.APP_TAG, "latitude=" + latitude + ";longitude=" + longitude);
} catch (Exception e){
Log.d(MainActivity.APP_TAG, "I/O Failure; do you have a network connection?",e);
}
}
}
Los enlaces caducan, de modo que he pegado el código completo anterior, pero por si acaso desea ver el código completo, está disponible en: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753
Usar el formato de cadena ayudará, pero debe tener cuidado con la configuración regional. En Alemania, el flotador se separará con una coma en lugar de un punto.
Usando String.format("geo:%f,%f",5.1,2.1);
en locale english el resultado será "geo:5.1,2.1"
pero con el alemán de configuración regional obtendrá "geo:5,1,2,1"
Debe usar la configuración regional en inglés para evitar este comportamiento.
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
Para establecer una etiqueta en el punto geográfico puedes extender tu geo uri usando:
!!! pero tenga cuidado con esto, el geo-uri aún está en desarrollo http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00
String uri = String.format(Locale.ENGLISH, "geo:%f,%f?z=%d&q=%f,%f (%s)",
latitude, longitude, zoom, latitude, longitude, label);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);