Android
Google Maps API v2 voor Android
Zoeken…
parameters
Parameter | Details |
---|---|
GoogleMap | de GoogleMap is een object dat wordt ontvangen bij een gebeurtenis onMapReady() |
MarkerOptions | MarkerOptions is de MarkerOptions van een Marker en wordt gebruikt om één marker aan een kaart toe te voegen. |
Opmerkingen
Voorwaarden
- Google Play Services SDK geïnstalleerd.
- Een Google Console-account.
- Een Google Maps API-sleutel verkregen in Google Console.
Standaard Google Map-activiteit
Deze activiteitscode biedt basisfunctionaliteit voor het opnemen van een Google Map met behulp van een SupportMapFragment.
De Google Maps V2 API bevat een geheel nieuwe manier om kaarten te laden.
Activiteiten moeten nu de OnMapReadyCallBack- interface implementeren, die wordt geleverd met een onMapReady () methode-overschrijving die wordt uitgevoerd telkens we SupportMapFragment uitvoeren . getMapAsync (OnMapReadyCallback) ; en de oproep is succesvol afgerond.
Maps gebruiken Markers , polygonen en polylijnen om interactieve informatie aan de gebruiker te tonen.
MapsActivity.java:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
Merk op dat de bovenstaande code een lay-out opblaast, met een SupportMapFragment genest in de lay-out van de container, gedefinieerd met een ID van R.id.map
. Het lay-outbestand wordt hieronder weergegeven:
activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context="com.example.app.MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>
Aangepaste Google-kaartstijlen
Kaartstijl
Google Maps wordt geleverd met een aantal verschillende stijlen die kunnen worden toegepast, met behulp van deze code:
// Sets the map type to be "hybrid"
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
De verschillende kaartstijlen zijn:
normaal
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
Typische wegenkaart. Wegen, sommige door de mens gemaakte kenmerken en belangrijke natuurlijke kenmerken zoals rivieren worden getoond. Weg- en kenmerklabels zijn ook zichtbaar.
Hybride
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
Satellietfotogegevens met wegenkaarten toegevoegd. Weg- en kenmerklabels zijn ook zichtbaar.
Satelliet
map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
Satellietfotogegevens. Weg- en kenmerklabels zijn niet zichtbaar.
Terrein
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
Topografische gegevens. De kaart bevat kleuren, contourlijnen en labels en perspectiefschaduw. Sommige wegen en labels zijn ook zichtbaar.
Geen
map.setMapType(GoogleMap.MAP_TYPE_NONE);
Geen tegels. De kaart wordt weergegeven als een leeg raster zonder geladen tegels.
ANDERE STIJLOPTIES
Indoor kaarten
Bij hoge zoomniveaus toont de kaart plattegronden voor binnenruimtes. Dit worden binnenkaarten genoemd en worden alleen weergegeven voor de 'normale' en 'satelliet' kaarttypen.
om plattegronden in of uit te schakelen, gaat dit als volgt:
GoogleMap.setIndoorEnabled(true).
GoogleMap.setIndoorEnabled(false).
We kunnen aangepaste stijlen aan kaarten toevoegen.
Voeg in de onMapReady-methode het volgende codefragment toe
mMap = googleMap;
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = mMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
MapsActivity.this, R.raw.style_json));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style.", e);
}
maak onder de map res een mapnaam raw aan en voeg het stijlen json-bestand toe. Voorbeeld style.json-bestand
[
{
"featureType": "all",
"elementType": "geometry",
"stylers": [
{
"color": "#242f3e"
}
]
},
{
"featureType": "all",
"elementType": "labels.text.stroke",
"stylers": [
{
"lightness": -80
}
]
},
{
"featureType": "administrative",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#746855"
}
]
},
{
"featureType": "administrative.locality",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "poi",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [
{
"color": "#263c3f"
}
]
},
{
"featureType": "poi.park",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#6b9a76"
}
]
},
{
"featureType": "road",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#2b3544"
}
]
},
{
"featureType": "road",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#9ca5b3"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#38414e"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#212a37"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#746855"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#1f2835"
}
]
},
{
"featureType": "road.highway",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#f3d19c"
}
]
},
{
"featureType": "road.local",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#38414e"
}
]
},
{
"featureType": "road.local",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#212a37"
}
]
},
{
"featureType": "transit",
"elementType": "geometry",
"stylers": [
{
"color": "#2f3948"
}
]
},
{
"featureType": "transit.station",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "#17263c"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#515c6d"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.stroke",
"stylers": [
{
"lightness": -20
}
]
}
]
Klik op deze link om stijlen json-bestand te genereren
Markeringen toevoegen aan een kaart
Om markeringen aan een Google Map toe te voegen, bijvoorbeeld vanuit een ArrayList
van MyLocation
Objects, kunnen we dit op deze manier doen.
De MyLocation
:
public class MyLocation {
LatLng latLng;
String title;
String snippet;
}
Hier is een methode die een lijst met MyLocation
objecten zou nemen en voor elk een markering zou plaatsen:
private void LocationsLoaded(List<MyLocation> locations){
for (MyLocation myLoc : locations){
mMap.addMarker(new MarkerOptions()
.position(myLoc.latLng)
.title(myLoc.title)
.snippet(myLoc.snippet)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
}
}
Opmerking: voor dit voorbeeld is mMap
een variabele van een lid van de klasse van de activiteit, waar we deze hebben toegewezen aan de onMapReady()
ontvangen in de onMapReady()
.
MapView: een GoogleMap in een bestaande lay-out insluiten
Het is mogelijk om een GoogleMap als een Android-weergave te behandelen als we gebruik maken van de meegeleverde MapView-klasse. Het gebruik ervan lijkt sterk op MapFragment.
Gebruik MapView in uw lay-out als volgt:
<com.google.android.gms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!--
map:mapType="0" Specifies a change to the initial map type
map:zOrderOnTop="true" Control whether the map view's surface is placed on top of its window
map:useVieLifecycle="true" When using a MapFragment, this flag specifies whether the lifecycle of the map should be tied to the fragment's view or the fragment itself
map:uiCompass="true" Enables or disables the compass
map:uiRotateGestures="true" Sets the preference for whether rotate gestures should be enabled or disabled
map:uiScrollGestures="true" Sets the preference for whether scroll gestures should be enabled or disabled
map:uiTiltGestures="true" Sets the preference for whether tilt gestures should be enabled or disabled
map:uiZoomGestures="true" Sets the preference for whether zoom gestures should be enabled or disabled
map:uiZoomControls="true" Enables or disables the zoom controls
map:liteMode="true" Specifies whether the map should be created in lite mode
map:uiMapToolbar="true" Specifies whether the mapToolbar should be enabled
map:ambientEnabled="true" Specifies whether ambient-mode styling should be enabled
map:cameraMinZoomPreference="0.0" Specifies a preferred lower bound for camera zoom
map:cameraMaxZoomPreference="1.0" Specifies a preferred upper bound for camera zoom -->
/>
Uw activiteit moet de OnMapReadyCallback-interface implementeren om te werken:
/**
* This shows how to create a simple activity with a raw MapView and add a marker to it. This
* requires forwarding all the important lifecycle methods onto MapView.
*/
public class RawMapViewDemoActivity extends AppCompatActivity implements OnMapReadyCallback {
private MapView mMapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.raw_mapview_demo);
mMapView = (MapView) findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
}
Huidige locatie weergeven in een Google Map
Hier is een volledige activiteitsklasse die een markering op de huidige locatie plaatst en de camera ook naar de huidige positie verplaatst.
Er zijn hier een paar dingen aan de hand:
- Controleer locatietoestemming
- Zodra de
setMyLocationEnabled()
is verleend, roept usetMyLocationEnabled()
, bouwt u de GoogleApiClient en verbindt u deze - Zodra de GoogleApiClient is verbonden, kunt u locatie-updates aanvragen
public class MapLocationActivity extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("Map Location Activity");
mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
@Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
@Override
public void onMapReady(GoogleMap googleMap)
{
mGoogleMap=googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {}
@Override
public void onLocationChanged(Location location)
{
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MapLocationActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context="com.example.app.MapLocationActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>
Resultaat:
Geef uitleg indien nodig op Marshmallow en Nougat met behulp van een AlertDialog (dit geval gebeurt wanneer de gebruiker eerder een toestemmingsverzoek had geweigerd of de toestemming had verleend en dit later in de instellingen had ingetrokken):
Vraag de gebruiker om locatietoestemming voor Marshmallow en Nougat door ActivityCompat.requestPermissions()
bellen:
Verplaats de camera naar de huidige locatie en plaats de markering wanneer de locatietoestemming wordt verleend:
De SH1-vingerafdruk van uw certificaatsleutelarchiefbestand verkrijgen
Om een Google Maps API-sleutel voor uw certificaat te verkrijgen, moet u de API-console voorzien van de SH1-vingerafdruk van uw debug / release-sleutelarchief.
U kunt de keystore verkrijgen door het keytool- programma van JDK te gebruiken , zoals hier in de documentatie wordt beschreven.
Een andere benadering is om de vingerafdruk programmatisch te verkrijgen door dit fragment uit te voeren met uw app ondertekend met het debug / release-certificaat en de hash naar het logboek af te drukken.
PackageInfo info;
try {
info = getPackageManager().getPackageInfo("com.package.name", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String hash= new String(Base64.encode(md.digest(), 0));
Log.e("hash", hash);
}
} catch (NameNotFoundException e1) {
Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
Log.e("exception", e.toString());
}
Start Google Maps niet wanneer op de kaart wordt geklikt (lite-modus)
Wanneer een Google Map in lite-modus wordt weergegeven, wordt door klikken op een kaart de applicatie Google Maps geopend. Om deze functionaliteit uit te schakelen, moet u setClickable(false)
in de MapView
, bijvoorbeeld :
final MapView mapView = (MapView)view.findViewById(R.id.map);
mapView.setClickable(false);
UISettings
Met behulp van UISettings
kan het uiterlijk van Google Map worden gewijzigd.
Hier is een voorbeeld van enkele algemene instellingen:
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mGoogleMap.getUiSettings().setMapToolbarEnabled(true);
mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
mGoogleMap.getUiSettings().setCompassEnabled(true);
Resultaat:
Krijg foutopsporende SHA1-vingerafdruk
- Open Android Studio
- Open uw project
- Klik op Gradle (vanuit het rechter zijpaneel ziet u Gradle Bar )
- Klik op Vernieuwen (Klik op Vernieuwen vanuit Gradle Bar , u ziet List Gradle-scripts van uw project)
- Klik op Uw Project (Uw Naam van het project vorm List (root))
- Klik op Taken
- Klik op Android
- Dubbelklik op signingReport (u krijgt SHA1 en MD5 in Run Bar )
InfoWindow Klik op Listener
Hier is een voorbeeld van het definiëren van een andere actie voor elke Markering InfoWindow-klikgebeurtenis.
Gebruik een HashMap waarin de marker-ID de sleutel is en de waarde de overeenkomstige actie is die moet worden uitgevoerd wanneer op InfoWindow wordt geklikt.
Gebruik vervolgens een OnInfoWindowClickListener
om de gebeurtenis OnInfoWindowClickListener
te handelen dat een gebruiker op InfoWindow klikt en gebruik de HashMap om te bepalen welke actie moet worden ondernomen.
In dit eenvoudige voorbeeld zullen we een andere activiteit openen op basis van waarop Marker InfoWindow is geklikt.
Verklaar de HashMap als een instantievariabele van de activiteit of het fragment:
//Declare HashMap to store mapping of marker to Activity
HashMap<String, String> markerMap = new HashMap<String, String>();
Voer vervolgens elke keer dat u een marker toevoegt, een vermelding in de HashMap in met de marker-ID en de actie die moet worden uitgevoerd wanneer op InfoWindow wordt geklikt.
Bijvoorbeeld door twee markeringen toe te voegen en voor elk een actie te definiëren:
Marker markerOne = googleMap.addMarker(new MarkerOptions().position(latLng1)
.title("Marker One")
.snippet("This is Marker One");
String idOne = markerOne.getId();
markerMap.put(idOne, "action_one");
Marker markerTwo = googleMap.addMarker(new MarkerOptions().position(latLng2)
.title("Marker Two")
.snippet("This is Marker Two");
String idTwo = markerTwo.getId();
markerMap.put(idTwo, "action_two");
Klik in InfoWindow op luisteraar, haal de actie uit de HashMap en open de bijbehorende activiteit op basis van de actie van de marker:
mGoogleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
String actionId = markerMap.get(marker.getId());
if (actionId.equals("action_one")) {
Intent i = new Intent(MainActivity.this, ActivityOne.class);
startActivity(i);
} else if (actionId.equals("action_two")) {
Intent i = new Intent(MainActivity.this, ActivityTwo.class);
startActivity(i);
}
}
});
Opmerking Als de code een fragment is, vervangt u MainActivity.this door getActivity ().
Wijzig offset
Door de waarden voor mappoint x en y naar behoefte te wijzigen, kunt u de offset-positie van google map wijzigen. Standaard bevindt deze zich in het midden van de kaartweergave. Roep de onderstaande methode aan waar u deze wilt wijzigen! Beter om het te gebruiken in uw onLocationChanged
zoals changeOffsetCenter(location.getLatitude(),location.getLongitude());
public void changeOffsetCenter(double latitude,double longitude) {
Point mappoint = mGoogleMap.getProjection().toScreenLocation(new LatLng(latitude, longitude));
mappoint.set(mappoint.x, mappoint.y-100); // change these values as you need , just hard coded a value if you want you can give it based on a ratio like using DisplayMetrics as well
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(mGoogleMap.getProjection().fromScreenLocation(mappoint)));
}