วิธีเปิดแอปพลิเคชั่น Google แผนที่มาตรฐานจากแอปพลิเคชันของฉัน


140

เมื่อผู้ใช้กดปุ่มในแอปพลิเคชันของฉันฉันต้องการเปิดแอปพลิเคชัน Google แผนที่มาตรฐานและแสดงตำแหน่งเฉพาะ ฉันจะทำมันได้อย่างไร (ไม่ใช้com.google.android.maps.MapView)

คำตอบ:


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_

2
ตกลงฉันพบปัญหาแล้ว กลับสตริงด้วยเครื่องหมายจุลภาค:String.format("geo:%f,%f", latitude, longitude) geo:59,915494,30,409456
LA_

20
นี่ย้ายฉันไปยังที่ตั้ง แต่ไม่ได้วางบอลลูนไว้ที่นั่น ฉันจะรักเอาท์พุตเพื่อให้ผู้ใช้สามารถคลิกเพื่อรับทิศทางอื่น ๆ
ไมค์

5
อย่ายุ่งกับ String.format () สำหรับการเรียงสตริงอย่างง่าย วิธีการนี้มีไว้สำหรับข้อความ UI เท่านั้นนั่นเป็นสาเหตุที่การพิมพ์ซ้ำจุดทศนิยมอาจแตกต่างกันไป เพียงใช้ตัวดำเนินการ "+" หรือ StringBuilder: String uri = "geo:" + lastLocation.getLatitude () + "," + lastLocation.getLongitude ()
AgustíSánchez

4
สำหรับทิศทางตอนนี้รองรับการนำทางด้วย google.navigation: q = ละติจูด, ลองจิจูด: Uri gmmIntentUri = Uri.parse ("google.navigation: q =" + 12f "+", "+ 2f); Intent mapIntent = new เจตนา (Intent.ACTION_VIEW, gmmIntentUri); mapIntent.setPackage ("com.google.android.apps.maps"); startActivity (mapIntent);
David Thompson

106

นอกจากนี้คุณยังสามารถใช้http://maps.google.co.th/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 จากนั้นเราสามารถเริ่มต้นกิจกรรมอีกครั้งโดยไม่มีข้อ จำกัด ของแอป Maps เราค่อนข้างแน่ใจ ที่เราจะไม่ไปถึง Toast ในตอนท้ายเนื่องจากเบราว์เซอร์อินเทอร์เน็ตเป็นแอปพลิเคชั่นที่ถูกต้องในการเปิดใช้รูปแบบ 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();
            }
        }

แก้ไข:

สำหรับทิศทางความตั้งใจในการนำทางได้รับการสนับสนุนด้วย 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

กรุณาโพสต์สิ่งที่คุณได้แทนที่บรรทัดแรกของโค้ดด้วย [บรรทัดที่ขึ้นต้นด้วย String uri = string.format] ดูเหมือนว่าคุณมีสตริงเป็นหนึ่งในพารามิเตอร์ที่ควรเป็นแบบลอยตัว
David Thompson

เฮ้เมื่อฉันส่งเลเบลไปยัง Google Maps ด้วยละติจูดและลองจิจูดแอปพลิเคชั่นแผนที่จะแปลงป้ายชื่อเป็นที่อยู่ คุณช่วยบอกได้ไหมว่าจะแก้ปัญหาอย่างไร
Rohan Sharma

41

การใช้รูปแบบของสตริงจะช่วยได้ แต่คุณต้องระวังให้เต็มที่กับโลแคล ในประเทศเยอรมนีลอยจะถูกคั่นด้วยเครื่องหมายจุลภาคแทนจุด

การใช้String.format("geo:%f,%f",5.1,2.1);locale english ผลลัพธ์จะเป็น"geo:5.1,2.1"แต่ด้วย locale german คุณจะได้รับ"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 นี้ยังอยู่ภายใต้ develoment 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

1
ฉันกำลังลองอะไรที่คล้ายกันยกเว้นว่าฉันเพิ่มแบบสอบถามด้วยพิกัดเพื่อให้ได้บอลลูน รหัสของฉันดูเหมือนกับตัวอย่างแรกของคุณ ฉันจัดรูปแบบ URI ด้วยภาษาอังกฤษ แต่เมื่อฉันใช้บนอุปกรณ์ของฉันที่ตั้งค่าเป็นภาษาเยอรมัน Google แผนที่ยังคงแทนที่จุดด้วยเครื่องหมายจุลภาคเพื่อให้แบบสอบถามของฉันไม่ทำงาน เมื่อฉันตั้งค่าภาษาของอุปกรณ์เป็น English US fe มันทำงานได้อย่างสมบูรณ์แบบ ฉันจะทำอย่างไร ดูเหมือนว่า Google แผนที่จะเปลี่ยนสตริงข้อความค้นหาอีกครั้ง
kaolick


6

บางครั้งหากไม่มีแอปพลิเคชันใด ๆ ที่เกี่ยวข้องกับ geo: protocal คุณสามารถใช้ try-catch เพื่อรับ ActivityNotFoundException เพื่อจัดการ

มันเกิดขึ้นเมื่อคุณใช้อีมูเลเตอร์บางตัวเช่น androVM ซึ่งไม่ได้ติดตั้งแผนที่ google โดยค่าเริ่มต้น


6

คุณยังสามารถใช้ข้อมูลโค้ดด้านล่างด้วยวิธีนี้มีการตรวจสอบการมีอยู่ของ 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 มันจะเปิดแอปแผนที่หากพบและวางจุดและให้คุณเริ่มต้นการเดินทาง:

  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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.