Khi điền địa chỉ giao hàng, thông tin thanh toán hoặc thông tin sự kiện, việc bật biểu mẫu bằng tính năng Place Autocomplete sẽ giúp người dùng giảm số lần nhấn phím và lỗi khi nhập thông tin địa chỉ. Hướng dẫn này trình bày các bước cần thiết để bật trường nhập dữ liệu bằng tính năng Place Autocomplete và điền các trường biểu mẫu địa chỉ bằng các thành phần địa chỉ từ địa chỉ do người dùng chọn, đồng thời trình bày địa chỉ đã chọn trên bản đồ để hỗ trợ xác nhận bằng hình ảnh.

Video: Cải thiện biểu mẫu địa chỉ bằng tính năng Tự động hoàn thành địa điểm
Biểu mẫu địa chỉ
Android
iOS
Web
Google Maps Platform cung cấp tiện ích Place Autocomplete cho các nền tảng di động và web. Tiện ích (như trong các hình trước) cung cấp một hộp thoại tìm kiếm có chức năng tự động hoàn thành tích hợp sẵn mà bạn thậm chí có thể tối ưu hoá cho tính năng tìm kiếm theo phạm vi vị trí.
Lấy mã
Sao chép hoặc tải kho lưu trữ Bản minh hoạ SDK Địa điểm của Google cho Android xuống từ GitHub.
Xem phiên bản Java của hoạt động:
/* * 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 } }); } }
Đang bật API
Để triển khai các đề xuất này, bạn phải bật các API sau trong Google Cloud Console:
- Maps SDK cho Android (hoặc API cho nền tảng bạn chọn)
- Places API
Để biết thêm thông tin về cách thiết lập, hãy xem bài viết Thiết lập dự án trên Google Cloud.
Thêm tính năng tự động hoàn thành vào các trường nhập dữ liệu
Phần này mô tả cách thêm tính năng Place Autocomplete vào biểu mẫu địa chỉ.
Thêm tiện ích Place Autocomplete
Trong Android, bạn có thể thêm tiện ích tự động hoàn thành bằng cách sử dụng một Ý định tự động hoàn thành để khởi chạy Place Autocomplete từ trường nhập dữ liệu Dòng địa chỉ 1, nơi người dùng sẽ bắt đầu nhập địa chỉ của họ. Khi bắt đầu nhập, họ sẽ có thể chọn địa chỉ của mình trong danh sách cụm từ gợi ý của tính năng tự động hoàn thành.
Trước tiên, hãy chuẩn bị một trình chạy hoạt động bằng cách sử dụng ActivityResultLauncher. Trình chạy này sẽ lắng nghe kết quả từ hoạt động được chạy. Lệnh gọi lại kết quả sẽ chứa một đối tượng Địa điểm tương ứng với địa chỉ mà người dùng chọn trong cụm từ gợi ý của tính năng Tự động hoàn thành.
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"); } });
Tiếp theo, hãy xác định các trường, vị trí và thuộc tính loại của ý định Place Autocomplete rồi tạo ý định đó bằng Autocomplete.IntentBuilder.
Cuối cùng, hãy chạy ý định bằng cách sử dụng ActivityResultLauncher được xác định trong mã mẫu trước đó.
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); }
Xử lý địa chỉ do Place Autocomplete trả về
Việc xác định ActivityResultLauncher trước đó cũng xác định những việc cần làm khi kết quả hoạt động được trả về trong lệnh gọi lại. Nếu người dùng chọn một cụm từ gợi ý, thì cụm từ đó sẽ được phân phối theo ý định có trong đối tượng kết quả. Vì ý định được tạo bởi Autocomplete.IntentBuilder,
nên phương thức Autocomplete.getPlaceFromIntent() có thể trích xuất đối tượng Địa điểm
từ ý định đó.
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"); } });
Từ đó, hãy gọi Place.getAddressComponents() và so khớp từng thành phần địa chỉ với trường nhập dữ liệu tương ứng trong biểu mẫu địa chỉ, điền giá trị từ Địa điểm mà người dùng đã chọn vào trường đó.
Ví dụ về cách triển khai để điền sẵn các trường trong biểu mẫu địa chỉ được chia sẻ trong phương thức fillInAddress của mã mẫu được cung cấp trong phần Lấy mã của trang này.
Việc thu thập dữ liệu địa chỉ từ thông tin dự đoán thay vì địa chỉ được nhập thủ công giúp đảm bảo độ chính xác của địa chỉ, đảm bảo rằng địa chỉ đó đã được biết đến và có thể giao hàng đến, đồng thời giảm số lần nhấn phím của người dùng.
Những điều cần cân nhắc khi triển khai tính năng Place Autocomplete
Place Autocomplete có một số lựa chọn cho phép triển khai linh hoạt nếu bạn muốn sử dụng nhiều hơn chỉ tiện ích. Bạn có thể kết hợp nhiều dịch vụ để nhận được chính xác thông tin cần thiết nhằm so khớp vị trí theo cách chính xác.
Đối với biểu mẫu ĐỊA CHỈ, hãy đặt tham số types thành
addressđể chỉ cho phép kết quả khớp là địa chỉ đường phố đầy đủ. Tìm hiểu thêm về các loại được hỗ trợ trong yêu cầu của tính năng Place Autocomplete.Đặt các quy tắc hạn chế và thiên vị phù hợp nếu bạn không cần tìm kiếm trên toàn thế giới. Có một số tham số có thể dùng để thiên vị hoặc hạn chế kết quả phù hợp chỉ cho một số khu vực cụ thể.
Sử dụng
RectangularBoundsđể đặt ranh giới hình chữ nhật nhằm ràng buộc cho một khu vực, sử dụngsetLocationRestriction()để đảm bảo chỉ trả về các địa chỉ trong những khu vực đó.Sử dụng
setCountries()để hạn chế phản hồi ở một số quốc gia nhất định.
Cho phép chỉnh sửa các trường trong trường hợp một số trường không khớp, và cho phép khách hàng cập nhật địa chỉ nếu cần. Vì hầu hết địa chỉ do Place Autocomplete trả về đều không chứa số phụ như số căn hộ, số phòng hoặc số đơn vị, nên bạn có thể di chuyển tiêu điểm đến Dòng địa chỉ 2 để khuyến khích người dùng điền thông tin đó nếu cần.
Cung cấp hình ảnh xác nhận địa chỉ
Trong quá trình nhập địa chỉ, hãy cung cấp cho người dùng thông tin xác nhận trực quan về địa chỉ trên bản đồ. Điều này giúp người dùng yên tâm hơn rằng địa chỉ đó là chính xác.
Hình ảnh sau đây cho thấy một bản đồ bên dưới địa chỉ, có một biểu tượng chiếc ghim tại địa chỉ đã nhập.

Ví dụ sau đây tuân theo các bước cơ bản để thêm bản đồ trong Android. Hãy tham khảo tài liệu để biết thêm chi tiết.
- Thêm
SupportMapFragment(trong trường hợp này là thêm một mảnh theo cách linh động) - Lấy một handle cho mảnh và đăng ký lệnh gọi lại
- Tạo kiểu và thêm điểm đánh dấu vào bản đồ
- Tắt các chế độ điều khiển bản đồ
Đang thêm SupportMapFragment
Trước tiên, hãy thêm một mảnh SupportMapFragment vào tệp XML bố cục.
<fragment
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/confirmation_map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>Sau đó, hãy thêm mảnh theo phương thức lập trình nếu mảnh đó chưa tồn tại.
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);
}
}Lấy tên người dùng cho mảnh và đăng ký lệnh gọi lại
Để lấy một handle cho mảnh, hãy gọi phương thức
FragmentManager.findFragmentByIdvà truyền mã tài nguyên của mảnh vào tệp bố cục. Nếu bạn thêm mảnh một cách linh động, hãy bỏ qua bước này vì bạn đã truy xuất được tay điều khiển.Gọi phương thức
getMapAsyncđể đặt lệnh gọi lại trên mảnh.
Ví dụ: nếu bạn thêm mảnh theo cách tĩnh:
Kotlin
val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this)
Java
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this);
Tạo kiểu và thêm điểm đánh dấu vào bản đồ
Khi bản đồ đã sẵn sàng, hãy đặt kiểu, căn giữa camera và thêm điểm đánh dấu tại toạ độ của địa chỉ đã nhập. Đoạn mã sau đây sử dụng kiểu được xác định trong một đối tượng JSON hoặc bạn có thể tải một mã bản đồ đã được xác định bằng tính năng Định kiểu bản đồ dựa trên đám mây.
@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)); }
Tắt các nút điều khiển bản đồ
Để giữ cho bản đồ đơn giản bằng cách hiển thị vị trí mà không có các chế độ điều khiển bản đồ bổ sung (chẳng hạn như la bàn, thanh công cụ hoặc các tính năng tích hợp khác), hãy cân nhắc tắt các chế độ điều khiển mà bạn thấy không cần thiết. Trên Android, một lựa chọn khác là bật chế độ thu gọn để cung cấp khả năng tương tác hạn chế.