افزودن «تکمیل خودکار جا» به فرم نشانی

هنگام تکمیل نشانی تحویل کالا، اطلاعات صورت‌حساب، یا اطلاعات رویداد، فعال کردن فرم‌ها با تکمیل خودکار جا به کاربران کمک می‌کند تا تعداد کلیدهای فشرده‌شده و اشتباهات را هنگام وارد کردن اطلاعات نشانی کاهش دهند. این آموزش مراحل لازم برای فعال کردن فیلد ورودی با «تکمیل خودکار جا» و پر کردن فیلدهای فرم نشانی با مؤلفه‌های نشانی از نشانی انتخاب‌شده توسط کاربر را شرح می‌دهد و نشانی انتخاب‌شده را روی نقشه ارائه می‌دهد تا به تأیید بصری کمک کند.

فرم نشانی که پیش‌بینی‌های «تکمیل خودکار جا» و فیلدهای تکمیل‌شده را نشان می‌دهد

ویدیوها: بهبود فرم‌های نشانی با «تکمیل خودکار جا»

فرم‌های نشانی

Android

iOS

وب

«پلاتفرم Google Maps» ابزاره «تکمیل خودکار جا» را برای پلاتفرم‌های تلفن همراه و وب ارائه می‌دهد. ابزاره، که در شکل‌های قبلی نشان داده شده است، کادر گفتگوی جستجویی با عملکرد تکمیل خودکار داخلی ارائه می‌دهد که حتی می‌توانید آن را برای جستجوی محدود به مکان بهینه‌سازی کنید.

دریافت کد

مخزن Google Places SDK for Android Demos را از GitHub همسان‌سازی یا بارگیری کنید.

مشاهده نسخه Java فعالیت:

    /*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.placesdemo;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static com.google.maps.android.SphericalUtil.computeDistanceBetween;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.example.placesdemo.databinding.AutocompleteAddressActivityBinding;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.AddressComponent;
import com.google.android.libraries.places.api.model.AddressComponents;
import com.google.android.libraries.places.api.model.AutocompletePrediction;
import com.google.android.libraries.places.api.model.AutocompleteSessionToken;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.PlaceTypes;
import com.google.android.libraries.places.api.net.FetchPlaceRequest;
import com.google.android.libraries.places.api.net.PlacesClient;
import com.google.android.libraries.places.widget.PlaceAutocomplete;
import java.util.Arrays;
import java.util.List;

/** Activity for using Place Autocomplete to assist filling out an address form. */
@SuppressWarnings("FieldCanBeLocal")
public class AutocompleteAddressActivity extends AppCompatActivity implements OnMapReadyCallback {

    private static final String TAG = "ADDRESS_AUTOCOMPLETE";
    private static final String MAP_FRAGMENT_TAG = "MAP";
    private LatLng coordinates;
    private boolean checkProximity = false;
    private SupportMapFragment mapFragment;
    private GoogleMap map;
    private Marker marker;
    private PlacesClient placesClient;
    private View mapPanel;
    private LatLng deviceLocation;
    private static final double acceptedProximity = 150;

    private AutocompleteAddressActivityBinding binding;

    View.OnClickListener startAutocompleteIntentListener =
            view -> {
                view.setOnClickListener(null);
                startAutocompleteIntent();
            };

    private final ActivityResultLauncher<Intent> startAutocomplete =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == Activity.RESULT_OK) {
                            Intent intent = result.getData();
                            if (intent != null) {
                                AutocompletePrediction prediction =
                                        PlaceAutocomplete.getPredictionFromIntent(intent);
                                AutocompleteSessionToken sessionToken =
                                        PlaceAutocomplete.getSessionTokenFromIntent(intent);
                                if (prediction != null) {
                                    List<Place.Field> fields =
                                            Arrays.asList(
                                                    Place.Field.ADDRESS_COMPONENTS,
                                                    Place.Field.LOCATION,
                                                    Place.Field.VIEWPORT);
                                    FetchPlaceRequest request =
                                            FetchPlaceRequest.builder(
                                                            prediction.getPlaceId(), fields)
                                                    .setSessionToken(sessionToken)
                                                    .build();
                                    placesClient
                                            .fetchPlace(request)
                                            .addOnSuccessListener(
                                                    response -> {
                                                        Place place = response.getPlace();
                                                        // Write a method to read the address
                                                        // components from the Place
                                                        // and populate the form with the address
                                                        // components
                                                        Log.d(
                                                                TAG,
                                                                "Place: "
                                                                        + place
                                                                                .getAddressComponents());
                                                        fillInAddress(place);
                                                    })
                                            .addOnFailureListener(
                                                    exception -> {
                                                        Log.e(
                                                                TAG,
                                                                "Place not found: "
                                                                        + exception.getMessage());
                                                    });
                                }
                            }
                        } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                            // The user canceled the operation.
                            Log.i(TAG, "User canceled autocomplete");
                        }
                    });


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        binding.autocompleteAddress1.setOnClickListener(startAutocompleteIntentListener);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Enable edge-to-edge display. This must be called before calling super.onCreate().
        EdgeToEdge.enable(this);
        super.onCreate(savedInstanceState);

        binding = AutocompleteAddressActivityBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Retrieve a PlacesClient (previously initialized - see MainActivity)
        placesClient = Places.createClient(this);

        // Attach an Autocomplete intent to the Address 1 EditText field
        binding.autocompleteAddress1.setOnClickListener(startAutocompleteIntentListener);

        // Update checkProximity when user checks the checkbox
        CheckBox checkProximityBox = findViewById(R.id.checkbox_proximity);
        checkProximityBox.setOnCheckedChangeListener(
                (view, isChecked) -> {
                    // Set the boolean to match user preference for when the Submit button is
                    // clicked
                    checkProximity = isChecked;
                });

        // Submit and optionally check proximity
        Button saveButton = findViewById(R.id.autocomplete_save_button);
        saveButton.setOnClickListener(v -> saveForm());

        // Reset the form
        Button resetButton = findViewById(R.id.autocomplete_reset_button);
        resetButton.setOnClickListener(v -> clearForm());
    }

    private void startAutocompleteIntent() {
        // Build the autocomplete intent with country and type filters applied
        Intent intent =
                new PlaceAutocomplete.IntentBuilder()
                        .setCountries(List.of("US"))
                        .setTypesFilter(List.of(PlaceTypes.ADDRESS))
                        .build(this);
        startAutocomplete.launch(intent);
    }


    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        map = googleMap;
        try {
            // Customise the styling of the base map using a JSON object defined
            // in a string resource.
            boolean success =
                    map.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.style_json));

            if (!success) {
                Log.e(TAG, "Style parsing failed.");
            }
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, "Can't find style. Error: ", e);
        }
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15f));
        marker = map.addMarker(new MarkerOptions().position(coordinates));
    }


    private void fillInAddress(Place place) {
        AddressComponents components = place.getAddressComponents();
        StringBuilder address1 = new StringBuilder();
        StringBuilder postcode = new StringBuilder();

        // Get each component of the address from the place details,
        // and then fill-in the corresponding field on the form.
        // Possible AddressComponent types are documented at https://goo.gle/32SJPM1
        if (components != null) {
            for (AddressComponent component : components.asList()) {
                String type = component.getTypes().get(0);
                switch (type) {
                    case "street_number":
                        {
                            address1.insert(0, component.getName());
                            break;
                        }

                    case "route":
                        {
                            address1.append(" ");
                            address1.append(component.getShortName());
                            break;
                        }

                    case "postal_code":
                        {
                            postcode.insert(0, component.getName());
                            break;
                        }

                    case "postal_code_suffix":
                        {
                            postcode.append("-").append(component.getName());
                            break;
                        }

                    case "locality":
                        binding.autocompleteCity.setText(component.getName());
                        break;

                    case "administrative_area_level_1":
                        {
                            binding.autocompleteState.setText(component.getShortName());
                            break;
                        }

                    case "country":
                        binding.autocompleteCountry.setText(component.getName());
                        break;
                }
            }
        }

        binding.autocompleteAddress1.setText(address1.toString());
        binding.autocompletePostal.setText(postcode.toString());

        // After filling the form with address components from the Autocomplete
        // prediction, set cursor focus on the second address line to encourage
        // entry of sub-premise information such as apartment, unit, or floor number.
        binding.autocompleteAddress2.requestFocus();

        // Add a map for visual confirmation of the address
        showMap(place);
    }

    private void showMap(Place place) {
        coordinates = place.getLocation();

        // It isn't possible to set a fragment's id programmatically so we set a tag instead and
        // search for it using that.
        mapFragment =
                (SupportMapFragment)
                        getSupportFragmentManager().findFragmentByTag(MAP_FRAGMENT_TAG);

        // We only create a fragment if it doesn't already exist.
        if (mapFragment == null) {
            mapPanel = ((ViewStub) findViewById(R.id.stub_map)).inflate();
            GoogleMapOptions mapOptions = new GoogleMapOptions();
            mapOptions.mapToolbarEnabled(false);

            // To programmatically add the map, we first create a SupportMapFragment.
            mapFragment = SupportMapFragment.newInstance(mapOptions);

            // Then we add it using a FragmentTransaction.
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.confirmation_map, mapFragment, MAP_FRAGMENT_TAG)
                    .commit();
            mapFragment.getMapAsync(this);
        } else {
            updateMap(coordinates);
        }
    }


    private void updateMap(LatLng latLng) {
        marker.setPosition(latLng);
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f));
        if (mapPanel.getVisibility() == View.GONE) {
            mapPanel.setVisibility(View.VISIBLE);
        }
    }

    private void saveForm() {
        Log.d(TAG, "checkProximity = " + checkProximity);
        if (checkProximity) {
            checkLocationPermissions();
        } else {
            Toast.makeText(this, R.string.autocomplete_skipped_message, Toast.LENGTH_SHORT).show();
        }
    }

    private void clearForm() {
        binding.autocompleteAddress1.setText("");
        binding.autocompleteAddress2.getText().clear();
        binding.autocompleteCity.getText().clear();
        binding.autocompleteState.getText().clear();
        binding.autocompletePostal.getText().clear();
        binding.autocompleteCountry.getText().clear();
        if (mapPanel != null) {
            mapPanel.setVisibility(View.GONE);
        }
        binding.autocompleteAddress1.requestFocus();
    }

    // Register the permissions callback, which handles the user's response to the
    // system permissions dialog. Save the return value, an instance of
    // ActivityResultLauncher, as an instance variable.
    private final ActivityResultLauncher<String> requestPermissionLauncher =
            registerForActivityResult(
                    new ActivityResultContracts.RequestPermission(),
                    isGranted -> {
                        if (isGranted) {
                            // Since ACCESS_FINE_LOCATION is the only permission in this sample,
                            // run the location comparison task once permission is granted.
                            // Otherwise, check which permission is granted.
                            getAndCompareLocations();
                        } else {
                            // Fallback behavior if user denies permission
                            Log.d(TAG, "User denied permission");
                        }
                    });


    private void checkLocationPermissions() {
        if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            getAndCompareLocations();
        } else {
            requestPermissionLauncher.launch(ACCESS_FINE_LOCATION);
        }
    }


    @SuppressLint("MissingPermission")
    private void getAndCompareLocations() {
        // TODO: Detect and handle if user has entered or modified the address manually and update
        // the coordinates variable to the Lat/Lng of the manually entered address. May use
        // Geocoding API to convert the manually entered address to a Lat/Lng.
        LatLng enteredLocation = coordinates;
        map.setMyLocationEnabled(true);

        FusedLocationProviderClient fusedLocationClient =
                LocationServices.getFusedLocationProviderClient(this);

        fusedLocationClient
                .getLastLocation()
                .addOnSuccessListener(
                        this,
                        location -> {
                            // Got last known location. In some rare situations this can be null.
                            if (location == null) {
                                return;
                            }

                            deviceLocation =
                                    new LatLng(location.getLatitude(), location.getLongitude());
                            Log.d(TAG, "device location = " + deviceLocation);
                            Log.d(TAG, "entered location = " + enteredLocation.toString());

                            // Use the computeDistanceBetween function in the Maps SDK for Android
                            // Utility Library
                            // to use spherical geometry to compute the distance between two Lat/Lng
                            // points.
                            double distanceInMeters =
                                    computeDistanceBetween(deviceLocation, enteredLocation);
                            if (distanceInMeters <= acceptedProximity) {
                                Log.d(TAG, "location matched");
                                // TODO: Display UI based on the locations matching
                            } else {
                                Log.d(TAG, "location not matched");
                                // TODO: Display UI based on the locations not matching
                            }
                        });
    }
}

    

درحال فعال کردن میاناهای برنامه‌سازی کاربردی

برای پیاده‌سازی این توصیه‌ها، باید میاناهای برنامه‌سازی کاربردی زیر را در کنسول Google Cloud فعال کنید:

برای اطلاعات بیشتر درباره راه‌اندازی، به راه‌اندازی پروژه Google Cloud مراجعه کنید.

افزودن تکمیل خودکار به فیلدهای ورودی

این بخش نحوه افزودن «تکمیل خودکار جا» به فرم نشانی را شرح می‌دهد.

افزودن ابزارک «تکمیل خودکار جا»

در Android، می‌توانید بااستفاده از هدف تکمیل خودکار که «تکمیل خودکار جا» را از فیلد ورودی «خط نشانی ۱» راه‌اندازی می‌کند، ابزاره تکمیل خودکار را اضافه کنید. کاربر در این فیلد شروع به وارد کردن نشانی خود می‌کند. وقتی شروع به تایپ کردن می‌کند، می‌تواند نشانی‌اش را از فهرست پیش‌بینی‌های «تکمیل خودکار» انتخاب کند.

ابتدا، بااستفاده از ActivityResultLauncher، راه‌انداز فعالیتی آماده کنید که منتظر نتیجه‌ای از فعالیت راه‌اندازی‌شده باشد. فراخوانی نتیجه حاوی شیء «مکان» خواهد بود که با نشانی‌ای که کاربر از پیش‌بینی‌های «تکمیل خودکار» انتخاب می‌کند مطابقت دارد.

    private final ActivityResultLauncher<Intent> startAutocomplete =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == Activity.RESULT_OK) {
                            Intent intent = result.getData();
                            if (intent != null) {
                                AutocompletePrediction prediction =
                                        PlaceAutocomplete.getPredictionFromIntent(intent);
                                AutocompleteSessionToken sessionToken =
                                        PlaceAutocomplete.getSessionTokenFromIntent(intent);
                                if (prediction != null) {
                                    List<Place.Field> fields =
                                            Arrays.asList(
                                                    Place.Field.ADDRESS_COMPONENTS,
                                                    Place.Field.LOCATION,
                                                    Place.Field.VIEWPORT);
                                    FetchPlaceRequest request =
                                            FetchPlaceRequest.builder(
                                                            prediction.getPlaceId(), fields)
                                                    .setSessionToken(sessionToken)
                                                    .build();
                                    placesClient
                                            .fetchPlace(request)
                                            .addOnSuccessListener(
                                                    response -> {
                                                        Place place = response.getPlace();
                                                        // Write a method to read the address
                                                        // components from the Place
                                                        // and populate the form with the address
                                                        // components
                                                        Log.d(
                                                                TAG,
                                                                "Place: "
                                                                        + place
                                                                                .getAddressComponents());
                                                        fillInAddress(place);
                                                    })
                                            .addOnFailureListener(
                                                    exception -> {
                                                        Log.e(
                                                                TAG,
                                                                "Place not found: "
                                                                        + exception.getMessage());
                                                    });
                                }
                            }
                        } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                            // The user canceled the operation.
                            Log.i(TAG, "User canceled autocomplete");
                        }
                    });

سپس، فیلدها، مکان، و ویژگی‌های نوع قصد «تکمیل خودکار جا» را تعریف کنید و آن را با Autocomplete.IntentBuilder بسازید. درنهایت، قصد را بااستفاده از ActivityResultLauncher تعریف‌شده در نمونه کد قبلی راه‌اندازی کنید.

    private void startAutocompleteIntent() {
        // Build the autocomplete intent with country and type filters applied
        Intent intent =
                new PlaceAutocomplete.IntentBuilder()
                        .setCountries(List.of("US"))
                        .setTypesFilter(List.of(PlaceTypes.ADDRESS))
                        .build(this);
        startAutocomplete.launch(intent);
    }

مدیریت نشانی برگردانده‌شده توسط «تکمیل خودکار جا»

تعریف کردن ActivityResultLauncher در مراحل قبل همچنین مشخص می‌کند که وقتی نتیجه فعالیت در فراخوانی برگشتی برگردانده می‌شود چه کاری باید انجام شود. اگر کاربر پیش‌بینی‌ای را انتخاب کرده باشد، این پیش‌بینی در هدف موجود در شیء نتیجه ارائه خواهد شد. ازآنجایی‌که هدف توسط Autocomplete.IntentBuilder ساخته شده است، روش Autocomplete.getPlaceFromIntent() می‌تواند شیء Place را از آن استخراج کند.

    private final ActivityResultLauncher<Intent> startAutocomplete =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == Activity.RESULT_OK) {
                            Intent intent = result.getData();
                            if (intent != null) {
                                AutocompletePrediction prediction =
                                        PlaceAutocomplete.getPredictionFromIntent(intent);
                                AutocompleteSessionToken sessionToken =
                                        PlaceAutocomplete.getSessionTokenFromIntent(intent);
                                if (prediction != null) {
                                    List<Place.Field> fields =
                                            Arrays.asList(
                                                    Place.Field.ADDRESS_COMPONENTS,
                                                    Place.Field.LOCATION,
                                                    Place.Field.VIEWPORT);
                                    FetchPlaceRequest request =
                                            FetchPlaceRequest.builder(
                                                            prediction.getPlaceId(), fields)
                                                    .setSessionToken(sessionToken)
                                                    .build();
                                    placesClient
                                            .fetchPlace(request)
                                            .addOnSuccessListener(
                                                    response -> {
                                                        Place place = response.getPlace();
                                                        // Write a method to read the address
                                                        // components from the Place
                                                        // and populate the form with the address
                                                        // components
                                                        Log.d(
                                                                TAG,
                                                                "Place: "
                                                                        + place
                                                                                .getAddressComponents());
                                                        fillInAddress(place);
                                                    })
                                            .addOnFailureListener(
                                                    exception -> {
                                                        Log.e(
                                                                TAG,
                                                                "Place not found: "
                                                                        + exception.getMessage());
                                                    });
                                }
                            }
                        } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                            // The user canceled the operation.
                            Log.i(TAG, "User canceled autocomplete");
                        }
                    });

از آنجا، Place.getAddressComponents() را فراخوانی کنید و هر مؤلفه نشانی را با فیلد ورودی مربوطه در فرم نشانی مطابقت دهید و فیلد را با مقدار «مکان» انتخاب‌شده کاربر پر کنید.

یک نمونه پیاده‌سازی برای پر کردن فیلدهای فرم نشانی در روش fillInAddress کد نمونه ارائه‌شده در بخش دریافت کد این صفحه هم‌رسانی شده است.

ضبط داده‌های نشانی از پیش‌بینی به‌جای نشانی واردشده به‌صورت دستی به اطمینان از دقت نشانی کمک می‌کند، اطمینان می‌دهد که نشانی شناخته‌شده است و می‌توان به آن تحویل داد، و تعداد کلیدهای فشرده‌شده توسط کاربر را کاهش می‌دهد.

ملاحظات هنگام پیاده‌سازی «تکمیل خودکار جا»

«تکمیل خودکار جا» گزینه‌هایی دارد که به آن اجازه می‌دهد در پیاده‌سازی‌اش انعطاف‌پذیر باشد، اگر بخواهید از چیزی بیشتر از ابزاره استفاده کنید. می‌توانید از ترکیبی از سرویس‌ها استفاده کنید تا دقیقاً آنچه را نیاز دارید برای مطابقت دادن مکان به روش صحیح دریافت کنید.

  • برای فرم ADDRESS، پارامتر types را روی address تنظیم کنید تا مطابقت‌ها به نشانی‌های کامل خیابان محدود شود. درباره انواع پشتیبانی‌شده در درخواست‌های «تکمیل خودکار جا» بیشتر بدانید.

  • اگر نیازی به جستجوی سراسری ندارید، محدودیت‌ها و سوگیری‌های مناسب را تنظیم کنید. پارامترهای متعددی وجود دارد که می‌توان از آن‌ها برای سوگیری یا محدود کردن هرگونه مطابقت فقط به مناطق خاص استفاده کرد.

    • از RectangularBounds برای تنظیم مرزهای مستطیلی برای محدود کردن یک منطقه استفاده کنید، از setLocationRestriction() استفاده کنید تا مطمئن شوید فقط نشانی‌های موجود در آن مناطق برگردانده می‌شوند.

    • از setCountries() برای محدود کردن پاسخ‌ها به مجموعه خاصی از کشورها استفاده کنید.

  • فیلدها را قابل‌ویرایش بگذارید تا اگر فیلدهای خاصی در تطابق ازقلم افتاده بود، مشتریان بتوانند درصورت نیاز نشانی را به‌روز کنند. ازآنجایی‌که اکثر نشانی‌های برگردانده‌شده توسط «تکمیل خودکار جا» حاوی شماره‌های فرعی مانند شماره آپارتمان، سوئیت، یا واحد نیستند، می‌توانید تمرکز را به «خط نشانی ۲» منتقل کنید تا کاربر را تشویق کنید درصورت لزوم آن اطلاعات را تکمیل کند.

ارائه تأیید تصویری نشانی

به‌عنوان بخشی از ورودی نشانی، تأیید دیداری نشانی را در نقشه به کاربران ارائه دهید. این کار به کاربران اطمینان بیشتری می‌دهد که نشانی درست است.

شکل زیر نقشه‌ای را در زیر نشانی نشان می‌دهد که سنجاقی روی نشانی واردشده قرار دارد.

فرم نشانی با نشانگر نقشه که مکان انتخاب‌شده را تأیید می‌کند

مثال زیر از مراحل اصلی افزودن نقشه در Android پیروی می‌کند. برای جزئیات بیشتر به اسناد مراجعه کنید.

درحال افزودن SupportMapFragment…

ابتدا، قطعه SupportMapFragment را به فایل XML چیدمان اضافه کنید.

    <fragment
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:id="@+id/confirmation_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

سپس، اگر قطعه هنوز وجود ندارد، آن را به‌صورت برنامه‌نویسی‌شده اضافه کنید.

    private void showMap(Place place) {
        coordinates = place.getLocation();

        // It isn't possible to set a fragment's id programmatically so we set a tag instead and
        // search for it using that.
        mapFragment =
                (SupportMapFragment)
                        getSupportFragmentManager().findFragmentByTag(MAP_FRAGMENT_TAG);

        // We only create a fragment if it doesn't already exist.
        if (mapFragment == null) {
            mapPanel = ((ViewStub) findViewById(R.id.stub_map)).inflate();
            GoogleMapOptions mapOptions = new GoogleMapOptions();
            mapOptions.mapToolbarEnabled(false);

            // To programmatically add the map, we first create a SupportMapFragment.
            mapFragment = SupportMapFragment.newInstance(mapOptions);

            // Then we add it using a FragmentTransaction.
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.confirmation_map, mapFragment, MAP_FRAGMENT_TAG)
                    .commit();
            mapFragment.getMapAsync(this);
        } else {
            updateMap(coordinates);
        }
    }

دریافت نام کاربری برای قطعه و ثبت تماس برگشتی

  1. برای دریافت دستگیره قطعه، روش FragmentManager.findFragmentById را فراخوانی کنید و شناسه منبع قطعه را در فایل چیدمان به آن ارسال کنید. اگر قطعه را به‌صورت پویا اضافه کرده‌اید، این مرحله را رد کنید زیرا قبلاً دسته را بازیابی کرده‌اید.

  2. برای تنظیم کردن فراخوانی برگشتی در قطعه، روش getMapAsync را فراخوانی کنید.

برای مثال، اگر قطعه را به‌صورت ایستا اضافه کرده‌اید:

Kotlin

val mapFragment = supportFragmentManager
    .findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)

      

جاوا

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

      

سبک‌بندی و افزودن نشانگر به نقشه

وقتی نقشه آماده شد، سبک را تنظیم کنید، دوربین را در مرکز قرار دهید، و نشانگری در مختصات نشانی واردشده اضافه کنید. کد زیر از سبک‌پردازی تعریف‌شده در شیء JSON استفاده می‌کند یا می‌توانید شناسه نقشه‌ای را که با سبک‌پردازی نقشه بااستفاده از فضای ابری تعریف شده است بار کنید.

    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        map = googleMap;
        try {
            // Customise the styling of the base map using a JSON object defined
            // in a string resource.
            boolean success =
                    map.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.style_json));

            if (!success) {
                Log.e(TAG, "Style parsing failed.");
            }
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, "Can't find style. Error: ", e);
        }
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15f));
        marker = map.addMarker(new MarkerOptions().position(coordinates));
    }

(مشاهده نمونه کد کامل)

غیرفعال کردن کنترل‌های نقشه

برای ساده نگه داشتن نقشه با نشان دادن مکان بدون کنترل‌های اضافی نقشه (مانند قطب‌نما، نوار ابزار، یا سایر ویژگی‌های داخلی)، کنترل‌هایی را که ضروری نمی‌دانید غیرفعال کنید. در Android، گزینه دیگر فعال کردن حالت ساده برای ارائه تعامل محدود است.