Ngày nay gần hết các ứng dụng đều lớn đều tích hợp dịch vụ GoolgeMap và location trong ứng dụng của họ để nhận biết được vị trí khách hàng hay thiết bị của người dùng . Điển hình như Grab , Uber , now ... sử dụng GoogleMap và location để giúp cho người dùng dễ dàng di chuyển cũng như xác định vị trí khách hàng .Ở bài này mình giới thiệu về cách tích hợp GoogleMap và định vị thiết bị android thông trên GoogleMap
Cấu hình và thiết lập tệp Manifiest
Mở tệp build.gradle của bạn và thêm phụ thuộc này vào dự án android
implementation 'com.google.android.gms:play-services:12.0.1'
Mở tệp Manifiest để thêm một số quyền
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Thêm khai báo sau vào tệp manifying của bạn bên trong phần tử gốc của tệp manifiest.
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
Thêm khai báo sau vào tệp manifying của bạn, Bạn cần đặt bên trong thẻ Application
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Thêm khóa API trong project manifest và khai báo key API trong values/string
<meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" />
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_awidth="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:name="com.google.android.gms.maps.MapFragment" android:layout_awidth="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback { private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; LatLng latLng = new LatLng(16.080141, 108.219977); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 10); mMap.animateCamera(cameraUpdate); } }
Chạy ứng dụng và xem kết quả
Hãy bắt đầu viết code
Thêm một số quyền xác định vị trí
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Ở MainActivity.java các bạn implement các đối tượng sau :onnectionCallbacks , OnConnectionFailedListener và LocationListener
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; 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) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then over riding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } mMap.setMyLocationEnabled(true); } @Override public void onConnected(@Nullable Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onLocationChanged(Location location) { } }
Viết một số phương thức xác định vị trí
- setupLocationManager () - Sử dụng để tạo LocationManager trước khi yêu cầu vị trí điểm cuối
- createdLocationRequest () - Xử lý tham số yêu cầu để nhận vị trí điểm cuối
- setInitialLocation () - Phương pháp này sẽ hiển thị Vị trí được biết đến cuối cùng của thiết bị trên GoogleMap
private void setupLocationManager() { if (mGoogleApiClient == null) { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .addApi(Places.GEO_DATA_API) .addApi(Places.PLACE_DETECTION_API) .build(); } mGoogleApiClient.connect(); }
protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setSmallestDisplacement(10); mLocationRequest.setFastestInterval(50000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setNumUpdates(3); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest); builder.setAlwaysShow(true); PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build()); result.setResultCallback(new ResultCallback<LocationSettingsResult>() { @Override public void onResult(@NonNull LocationSettingsResult result) { final Status status = result.getStatus(); final LocationSettingsStates states = result.getLocationSettingsStates(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: setInitialLocation(); break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: try { status.startResolutionForResult(MainActivity.this, 1); } catch (IntentSender.SendIntentException e) { } break; case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: break; } } }); }
Bạn cần xử lý kết quả thông qua OnActivityResult
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { switch (requestCode) { case 1: switch (resultCode) { case Activity.RESULT_OK: { setInitialLocation(); mRequestingLocationUpdates = true; break; } case Activity.RESULT_CANCELED: { mRequestingLocationUpdates = false; break; } default: { break; } } break; } }
private void setInitialLocation() { if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationListener() { @Override public void onLocationChanged(Location location) { mLastLocation = location; try { LatLng positionUpdate = new LatLng(location.getLatitude(), location.getLongitude()); CameraUpdate update = CameraUpdateFactory.newLatLngZoom(positionUpdate, 15); mMap.animateCamera(update); } catch (Exception ex) { ex.printStackTrace(); Log.e("MapException", ex.getMessage()); } } }); }
Xử lý địa điểm
Kiểm tra phiên bản ứng dụng và yêu cầu người dùng cấp quyền đối với nhưng ứng dụng phiên bản dưỡi 6.0
private void CheckMapPermission() { if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1002); }else { setupLocationManager(); } } else { setupLocationManager(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case 1002: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { setupLocationManager(); } } else { Toast.makeText(MainActivity.this,"Permission Denied",Toast.LENGTH_SHORT).show(); //finish(); } } break; } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); CheckMapPermission(); createLocationRequest(); }
Chạy ưng dụng và xem kết quả: