Làm cách nào để mở ứng dụng Google Map tiêu chuẩn từ ứng dụng của tôi?


140

Khi người dùng nhấn nút trong ứng dụng của tôi, tôi muốn mở ứng dụng Google Map tiêu chuẩn và hiển thị vị trí cụ thể. Tôi làm nó như thế nào? (không sử dụng com.google.android.maps.MapView)

Câu trả lời:


241

Bạn nên tạo một Intentđối tượng với URI địa lý:

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

Nếu bạn muốn chỉ định một địa chỉ, bạn nên sử dụng một dạng URI địa lý khác : geo:0,0?q=address.

tham khảo: https://developer.android.com/guide/components/intents-common.html#Maps


1
Cảm ơn, @Pixie! Định dạng của vĩ độ và kinh độ là gì? Nếu tôi vượt qua lat: 59.915494, lng: 30.409456nó trả lại vị trí sai.
LA_

2
Ok, tôi đã tìm thấy vấn đề. String.format("geo:%f,%f", latitude, longitude)trả về chuỗi bằng dấu phẩy : geo:59,915494,30,409456.
LA_

20
Điều này di chuyển tôi đến vị trí nhưng nó không đặt một quả bóng ở đó. Tôi rất thích một chiếc balo để người dùng có thể nhấp vào nó để nhận chỉ đường, v.v.
Mike

5
Đừng lộn xộn với String.format () để nối chuỗi đơn giản. Phương pháp đó chỉ dành cho văn bản UI, đó là lý do tại sao việc bù lại điểm thập phân có thể khác nhau. Chỉ cần sử dụng toán tử "+" hoặc StringBuilder: String uri = "Geo:" + lastLocation.getLatitude () + "," + lastLocation.getLongitude ().
Agustí Sánchez

4
Đối với chỉ đường, mục đích điều hướng hiện được hỗ trợ với google.navulation: q = vĩ độ, kinh độ: Uri gmmIntentUri = Uri.parse ("google.navestion: q =" + 12f "+", "+ 2f); Intent mapIntent = new Ý định (Intent.ACTION_VIEW, gmmIntentUri); mapIntent.setPackage ("com.google.android.apps.maps"); startActivity (mapIntent);
David Thompson

105

Bạn cũng có thể chỉ cần sử dụng http://maps.google.com/maps làm URI của mình

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

hoặc bạn có thể đảm bảo rằng chỉ ứng dụng Google Maps được sử dụng, điều này ngăn bộ lọc ý định (hộp thoại) xuất hiện, bằng cách sử dụng

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

như vậy

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

hoặc bạn có thể thêm nhãn vào các vị trí bằng cách thêm một chuỗi bên trong dấu ngoặc đơn sau mỗi bộ tọa độ như sau:

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

Để sử dụng vị trí hiện tại của người dùng làm điểm bắt đầu (thật không may, tôi chưa tìm được cách gắn nhãn vị trí hiện tại), sau đó chỉ cần bỏ saddrtham số như sau:

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

Để đầy đủ, nếu người dùng không cài đặt ứng dụng bản đồ thì sẽ là một ý tưởng hay để bắt ActivityNotFoundException, như @TonyQ, sau đó chúng tôi có thể bắt đầu lại hoạt động mà không bị hạn chế ứng dụng bản đồ, chúng tôi có thể khá chắc chắn cuối cùng chúng ta sẽ không bao giờ đến Toast vì trình duyệt internet là một ứng dụng hợp lệ để khởi chạy lược đồ url này.

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

BIÊN TẬP:

Đối với chỉ đường, mục đích điều hướng hiện được hỗ trợ với google.navulation

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 không thể định dạng java.lang.String đối số ngoại lệ
Amitsharma

Vui lòng gửi những gì bạn đã thay thế dòng mã đầu tiên bằng [dòng bắt đầu bằng Chuỗi uri = string.format] Có vẻ như bạn có một chuỗi là một trong những tham số nên là một số float
David Thompson

Xin chào khi tôi chuyển nhãn sang bản đồ google với vĩ độ và kinh độ, ứng dụng bản đồ sẽ chuyển đổi nhãn thành địa chỉ. Bạn có thể vui lòng cho biết làm thế nào để giải quyết vấn đề này?
Rohan Sharma

41

Sử dụng định dạng Chuỗi sẽ giúp ích nhưng bạn phải quan tâm đầy đủ với miền địa phương. Trong phao nổi ở Đức sẽ được phân tách bằng dấu phẩy thay vì một điểm.

Sử dụng String.format("geo:%f,%f",5.1,2.1);trên tiếng Anh địa phương kết quả sẽ được "geo:5.1,2.1"nhưng với tiếng Đức địa phương, bạn sẽ nhận được"geo:5,1,2,1"

Bạn nên sử dụng ngôn ngữ tiếng Anh để ngăn chặn hành vi này.

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

Để đặt nhãn thành điểm địa lý, bạn có thể mở rộng uri địa lý của mình bằng cách sử dụng:

!!! nhưng hãy cẩn thận với điều này, ge-uri vẫn còn chưa được phát hiện 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);

bạn cũng có thể sử dụng "& t = h" so với "& t = m" để gọi trong màn hình lớp vệ tinh hoặc bản đồ.
tony gil

1
Tôi đang thử một cái gì đó tương tự ngoại trừ việc tôi thêm một truy vấn với tọa độ để tôi có được một quả bóng. Mã của tôi trông giống hệt ví dụ đầu tiên của bạn. Tôi định dạng URI bằng ngôn ngữ tiếng Anh, nhưng khi tôi sử dụng nó trên thiết bị của mình được đặt thành ngôn ngữ Đức, Google Maps vẫn thay thế dấu chấm bằng dấu phẩy để truy vấn của tôi không hoạt động. Khi tôi đặt ngôn ngữ của thiết bị thành tiếng Anh, nó hoạt động rất tốt. Tôi có thể làm gì? Dường như không có vấn đề gì khi Google Maps thay đổi chuỗi truy vấn một lần nữa.
kaolick


6

Đôi khi, nếu không có bất kỳ ứng dụng nào được liên kết với Geo: protocal, bạn có thể sử dụng tính năng thử bắt để có được ActivityNotFoundException để xử lý nó.

Nó xảy ra khi bạn sử dụng một số trình giả lập như androVM không được cài đặt google map theo mặc định.


6

Bạn cũng có thể sử dụng đoạn mã dưới đây, với cách này, sự tồn tại của google maps được kiểm tra trước khi ý định được bắt đầu.

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

Tham khảo: https://developers.google.com/maps/documentation/android-api/intents


1

Để đi đến vị trí có mã PIN trên đó, hãy sử dụng:

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

cho không có pin, sử dụng này trong uri:

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

0

Tôi có một ứng dụng mẫu nơi tôi chuẩn bị ý định và chỉ cần vượt qua CITY_NAME trong ý định cho hoạt động đánh dấu bản đồ để tính toán kinh độ và vĩ độ theo Geocoder bằng cách sử dụng CITY_NAME.

Dưới đây là đoạn mã bắt đầu hoạt động đánh dấu bản đồ và MapsMarkerActivity hoàn chỉnh.

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

Liên kết hết hạn vì vậy tôi đã dán mã hoàn chỉnh ở trên nhưng chỉ trong trường hợp nếu bạn muốn xem mã hoàn chỉnh thì có sẵn tại: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753


0

Điều này được viết bằng Kotlin, nó sẽ mở ứng dụng bản đồ nếu nó được tìm thấy và đặt điểm và cho phép bạn bắt đầu chuyến đi:

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

Thay thế requireActivity()bằng của bạn Context.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.