12/08/2018, 15:23

Làm Việc Với Google Map Trên Android

Trong dự án tôi đang làm có một chức năng khá hay. Chức năng đó có yêu cầu hiển thị Google Map, lấy vị trí hiện tại của người dùng, hiển thị marker khi người dùng click vào một vị trí trên bản đồ, tìm kiếm dữ liệu trong những khoảng bán kính nhất định. Vì lý do bảo mật nên tôi không thể cho các ...

Trong dự án tôi đang làm có một chức năng khá hay. Chức năng đó có yêu cầu hiển thị Google Map, lấy vị trí hiện tại của người dùng, hiển thị marker khi người dùng click vào một vị trí trên bản đồ, tìm kiếm dữ liệu trong những khoảng bán kính nhất định. Vì lý do bảo mật nên tôi không thể cho các bạn xem về design của dự án. Nhưng trong bài viết này tôi sẽ hướng dẫn các bạn làm việc với google map cũng như thực hiện một số chức năng với google map. Để các bạn dễ hình dung, tôi có làm một video demo Như trong video các bạn có thể thấy trong project sample của tôi gồm có những chức năng sau:

  • Hiển Thị bản dồ sử dụng google map
  • Hiển thị Current Location của người dùng
  • Hiển Thị marker khi người dùng click trên bản đồ
  • Hiển thị vòng tròn quanh một vị trí trên bản đồ cũng như độ zoom của bản đồ Sau đây tôi sẽ hướng dẫn các bạn thực hiện lần lượt những chức năng trên. Để sử dụng google map API bạn phải đăng ký ứng dụng của bạn trên Google Developer Console và enable API. Đi tới Google Developer Console. Nếu bạn đã có 1 project thì bạn có thể bỏ qua bước này, nếu không thì bạn theo sau những hướng dẫn cụ thể bên dưới:

Tạo một project

Tạo một project mới bằng cách click vào button màu xanh **Create Project ** rồi sau đó bạn nhập tên ứng dụng bạn muốn tạo như hình bên dưới:

Enabling Maps API

Khi project đã được tạo, bạn lựa chọn project và enable Maps API như bên dưới

Tạo Android API Key

Sau khi bạn đã Enable Maps API bạn click trên item Credentials bên dưới APIs & auth để có được key access APIs & auth cho ứng dụng của bạn. Khi bạn nhìn thấy Credentials dialog, ban click trên Add Credentials và lực chọn API Key

Bạn cần lựa chọn Android key trong dialog tiếp theo, nếu bạn muốn tạo cùng một ứng dụng sử dụng maps cho nhiều nền tảng khác nhau bạn có thể tạo một key cho mỗi nên tảng.

Set up Android Project

Sau khi bạn đã tạo một project cho Android, bạn mở file build.gradle bạn cần import library Play Services cho maps ngoài ra trong sample này bạn cũng cần import library locations Play Services theo thứ tự để thiêt lập vị trí ban đầu cho maps của bạn. Trong file build.gradle:

   compile 'com.google.android.gms:play-services-maps:10.2.4'
  compile 'com.google.android.gms:play-services:10.2.4'`

Sau đó bạn mởi file AndroidManifest.xml bạn cần khai báo các permission bạn sử dụng trong app

<uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

Ngoài ra bên trong node application bạn cũng cần add đoạn code bên dưới:

Tiếp theo bạn tạo 1 file layout như trong ví dụ này tôi gọi là activity_main.xlm và thêm đoạn code bên dưới:

<RelativeLayout
        android:layout_awidth="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        >

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

Tiếp theo bạn tao một class , ở đây tôi đặt tên là MainActivity.class như bên dưới:

public class MainActivity extends AppCompatActivity
        implements OnMapReadyCallback, GoogleMap.OnMapClickListener,
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
        View.OnClickListener {

    private GoogleMap mGoogleMap;

    private GoogleApiClient mGoogleApiClient;

    private LatLng mCurrentLocation;

    private LatLng mLatLngSearchPosition;

    private ActivityMainBinding mActivityMainBinding;

    private LinearLayout radius15, radius3, radius5, radius10, radius30, radiusall;

    private ObservableFloat mRadiusSearch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        initViews();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    private void initViews() {
        mActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        FragmentManager fragmentManager = getSupportFragmentManager();
        SupportMapFragment mapFragment =
                (SupportMapFragment) fragmentManager.findFragmentById(R.id.map);

        mapFragment.getMapAsync(this);
        radius15 = (LinearLayout) mActivityMainBinding.radiusSearch15km;
        radius3 = (LinearLayout) mActivityMainBinding.radiusSearch3km;
        radius5 = (LinearLayout) mActivityMainBinding.radiusSearch5km;
        radius10 = (LinearLayout) mActivityMainBinding.radiusSearch10km;
        radius30 = (LinearLayout) mActivityMainBinding.radiusSearch30km;
        radiusall = (LinearLayout) mActivityMainBinding.radiusSearchAll;

        radius15.setOnClickListener(this);
        radius3.setOnClickListener(this);
        radius5.setOnClickListener(this);
        radius10.setOnClickListener(this);
        radius30.setOnClickListener(this);
        radiusall.setOnClickListener(this);

        mRadiusSearch = new ObservableFloat(Constant.RADIUS_1_5KM);
        mActivityMainBinding.setRadiusSearch(mRadiusSearch.get());
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            final Location lastLocation =
                    LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (lastLocation == null) {
                return;
            }
            mCurrentLocation = new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude());
            if (mLatLngSearchPosition == null) {
                showCameraToPosition(mCurrentLocation, Constant.LEVEL_ZOOM_DEFAULT);
            }
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onMapClick(LatLng latLng) {
        mLatLngSearchPosition = latLng;
        showMarkerToGoogleMap(mLatLngSearchPosition);

        if (mRadiusSearch.get() <= Constant.RADIUS_DEFAULT
                || mRadiusSearch.get() >= Constant.RADIUS_ALL) {
            showCameraToPosition(mLatLngSearchPosition, Constant.LEVEL_ZOOM_DEFAULT);
        } else {
            final LatLngBounds circleBounds = new LatLngBounds(
                    locationMinMax(false, mLatLngSearchPosition, mRadiusSearch.get()),
                    locationMinMax(true, mLatLngSearchPosition, mRadiusSearch.get()));
            showCameraToPosition(circleBounds, 200);
        }

        showCircleToGoogleMap(mLatLngSearchPosition, mRadiusSearch.get());
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.setOnMapClickListener(this);
        mGoogleMap.getUiSettings().setCompassEnabled(true);
        mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
        mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
        mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
        mGoogleMap.setTrafficEnabled(true);
        mGoogleMap.setBuildingsEnabled(true);

        if (ActivityCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_COARSE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            mGoogleMap.setMyLocationEnabled(true);
        } else {
            //            Common.checkAndRequestPermissionsGPS(getActivity());
        }
    }
    
. . .
  • ConnectionCallbacks và OnConnectionFailedListener là những callback được dùng để giám sát trạng thái của GoogleApiClient, được sử dụng trong sample của chúng ta để lấy vị trí của người dùng
  • GoogleMap.OnMapClickListener được gọi khi người dùng click vào 1 vị trí trên google map
  • OnMapReadyCallback được gọi khi google map là đã được load

Bây giờ bạn chạy ứng dụng bạn sẽ nhìn thấy google map xuất hiện trên device

Thao tác với Google Map

Tạo GoogleApiClient Bạn cần tạo GoogleApiClient và bắt đầu LocationServices để lấy về current Location.

mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

Và trong ...

   @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

Setting Google Map

Để hiển thị ZoomControl, Compass, MyLocationButton ... Bạn cần setting UI cho Google Map:

@Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.setOnMapClickListener(this);
        mGoogleMap.getUiSettings().setCompassEnabled(true);
        mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
        mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
        mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
        mGoogleMap.setTrafficEnabled(true);
        mGoogleMap.setBuildingsEnabled(true);

        if (ActivityCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_COARSE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            mGoogleMap.setMyLocationEnabled(true);
        } else {
            //            Common.checkAndRequestPermissionsGPS(getActivity());
        }
    }

Move Camera tới một vị trí trên Bản đồ Để di chuyển Camera tới một vị trí nào đó trên bản đồ khi người dùng click hay khi đến vị hiện tại của người

public void showCameraToPosition(LatLng position, float zoomLevel) {
        CameraPosition cameraPosition = CameraPosition.builder()
                .target(position)
                .zoom(zoomLevel)
                .bearing(0.0f)
                .tilt(0.0f)
                .build();

        if (mGoogleMap != null) {
            mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), null);
        }
    }

Hiển thị marker trên Google Map Khi người dùng click vào một vị trí trên bản đồ, bạn muốn hiển thị một marker trên bản đồ:

 public void showMarkerToGoogleMap(LatLng position) {
        mGoogleMap.clear();
        MarkerOptions markerOptions = new MarkerOptions().position(position);
        markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_active));
        mGoogleMap.addMarker(markerOptions);
    }

Draw trên Google Map GoogleMap Object có hỗ trợ một bộ những phương thức cho phép bạn vẽ những hình học hoặc là image . Như trong ví dụ này tôi vẽ một hình tròn khi người dùng chọn bán kính tìm kiếm:

public void showCircleToGoogleMap(LatLng position, float radius) {
        if (position == null) {
            return;
        }
        CircleOptions circleOptions = new CircleOptions();
        circleOptions.center(position);
        //Radius in meters
        circleOptions.radius(radius * 1000);
        circleOptions.fillColor(getResources().getColor(R.color.circle_on_map));
        circleOptions.strokeColor(getResources().getColor(R.color.circle_on_map));
        circleOptions.strokeWidth(0);
        if (mGoogleMap != null) {
            mGoogleMap.addCircle(circleOptions);
        }
    }

Khi bạn chạy app bạn sẽ thấy:

Hiểu được chi tiết hơn các bạn có thể tham khảo source code đầy đủ tại đây

0