如何从我的应用程序打开标准的Google Map应用程序?


140

用户在应用程序中按下按钮后,我想打开标准的Google Map应用程序并显示特定位置。我该怎么做?(不使用com.google.android.maps.MapView

Answers:


241

您应该Intent使用geo-URI 创建一个对象:

String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);

如果要指定一个地址,你应该使用地理URI的另一种形式:geo:0,0?q=address

参考:https : //developer.android.com/guide/components/intents-common.html#Maps


1
谢谢@Pixie!纬度和经度的格式是什么?如果我通过,lat: 59.915494, lng: 30.409456它将返回错误的位置。
LA_ 2011年

2
好的,我找到了问题。String.format("geo:%f,%f", latitude, longitude)返回带有逗号的字符串:geo:59,915494,30,409456
LA_ 2011年

20
这将我移到该位置,但没有在此处放气球。我喜欢气球,因此用户可以单击它以获取路线等
Mike

5
请勿将String.format()与简单的String连接串联在一起。该方法仅适用于UI文本,这就是为什么小数点表示法可能会有所不同的原因。只需使用“ +”运算符或StringBuilder:String uri =“ geo:” + lastLocation.getLatitude()+“,” + lastLocation.getLongitude()。
Agustí地区桑切斯

4
对于路线,现在支持google.navigation:q =经纬度:Uri gmmIntentUri = Uri.parse(“ google.navigation:q =” + 12f“ +”,“ + 2f); Intent mapIntent = new Intent(Intent.ACTION_VIEW,gmmIntentUri); mapIntent.setPackage(“ com.google.android.apps.maps”); startActivity(mapIntent);
David Thompson

105

您也可以简单地将http://maps.google.com/maps用作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);

或者您可以确保仅使用Google Maps应用,这可以通过使用来阻止意图过滤器(对话框)的显示

intent.setPackage("com.google.android.apps.maps");

像这样:

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

或者,您可以通过在每组坐标后的括号内添加一个字符串来在位置上添加标签,如下所示:

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

要将用户的当前位置用作起点(不幸的是,我还没有找到标记当前位置的方法),只需saddr按如下所示删除该参数:

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

为了完整起见,如果用户未安装地图应用程序,那么捕获ActivityNotFoundException是一个好主意,如@TonyQ所述,那么我们可以在没有地图应用程序限制的情况下再次启动活动,我们可以确定由于互联网浏览器也是启动此url方案的有效应用程序,因此我们永远也不会结束Toast。

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

编辑:

对于路线,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);

java.util.IllegalFormatConversionException:%f无法格式化java.lang.String参数异常
Amitsharma 2015年

请用[字符串uri = string.format开头的行]替换您已替换的第一行代码的内容,似乎您将字符串作为应该为浮点数的参数之一
David Thompson

嘿,当我通过纬度和经度将标签传递给google地图时,地图应用程序会将标签转换为地址。你能告诉我如何解决这个问题吗?
罗汉·夏尔马

41

使用字符串格式会有所帮助,但是您必须注意语言环境。在德国,浮点数将以逗号分隔,而不是一个点。

使用String.format("geo:%f,%f",5.1,2.1);在英语语言环境的结果将是"geo:5.1,2.1",但与德国的语言环境,你会得到"geo:5,1,2,1"

您应该使用英语语言环境来防止此行为。

String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);

要将标签设置到地理位置,您可以使用以下方法扩展您的地理位置:

!!! 但请注意,geo-uri仍处于开发中 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);

您还可以在卫星或地图图层显示中使用“&t = h”和“&t = m”进行呼叫。
Tony gil 2013年

1
我正在尝试类似的操作,除了添加带有坐标的查询,以便获得提示框。我的代码看起来完全像您的第一个示例。我使用英语语言环境设置URI的格式,但是当我在设置为德语语言环境的设备上使用URI时,Google Maps仍将点替换为逗号,以使查询无法正常工作。当我将设备的语言环境设置为English US fe时,它可以很好地工作。我能做什么?似乎无论什么Google Maps都会再次更改查询字符串。
kaolick


6

有时,如果没有与geo:protocal相关的任何应用程序,则可以使用try-catch来获取ActivityNotFoundException进行处理。

当您使用诸如androVM之类的模拟器(默认情况下未安装google map)时,就会发生这种情况。


6

您还可以使用下面的代码段,以这种方式在启动Intent之前检查google maps的存在。

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

参考:https : //developers.google.com/maps/documentation/android-api/intents


1

要转到上面有PIN的位置,请使用:

String uri = "http://maps.google.com/maps?q=loc:" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);

对于没有别针的,请在uri中使用:

 String uri = "geo:" + destinationLatitude + "," + destinationLongitude;

0

我有一个示例应用程序,可以在其中准备意图,然后将意图中的CITY_NAME传递到地图标记活动,该活动最终由Geocoder使用CITY_NAME计算经度和纬度。

以下是启动地图标记活动和完整的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);
        }
    }
}

链接已过期,因此我在上面粘贴了完整的代码,以防万一,如果您想查看完整的代码,请访问以下网址https : //github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753


0

这是用Kotlin编写的,如果找到它,它将打开maps应用并放置该点,让您开始旅程:

  val gmmIntentUri = Uri.parse("http://maps.google.com/maps?daddr=" + adapter.getItemAt(position).latitud + "," + adapter.getItemAt(position).longitud)
        val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
        mapIntent.setPackage("com.google.android.apps.maps")
        if (mapIntent.resolveActivity(requireActivity().packageManager) != null) {
            startActivity(mapIntent)
        }

更换requireActivity()你的Context

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.