I'm facing an issue when using Google Maps v2 in Android. I want to have a MapView as part of a layout. I'm able to ge the MapView along with a marker, however the tiles themselves don't load UNLESS I click on the map. For each click I do, an additional tile will be painted (so it takes like 4 or 5 clicks to get the whole map).
I'm using Maps V2 but in this particular case, not in a fragment. As a note, the map works ok in another place in which I'm using a MapFragment.
The following are the important snippets of code:
Snippet of the activity:
public class ViewNodeDetailsGame extends MapActivity implements View.OnClickListener, OnMapReadyCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = savedInstanceState;
setContentView(R.layout.activity_view_node_details_game);
// Maps related
MapsInitializer.initialize(this);
// ... the data is fetched asynchronously here. Then, getLocation() is called
}
private void getLocation(final LinearLayout llLocation) {
mMapView = (MapView)llLocation.findViewById(R.id.map);
mMapView.onCreate(mBundle);
mMapView.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap map) {
LatLng sydney = new LatLng(-34, 151);
map.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
map.animateCamera(CameraUpdateFactory.newLatLng(sydney));
map.getUiSettings().setMyLocationButtonEnabled(true);
map.getUiSettings().setZoomControlsEnabled(true);
map.getUiSettings().setCompassEnabled(true);
map.getUiSettings().setAllGesturesEnabled(true);
}
#Override
public void onResume() {
super.onResume();
if (mMapView != null) {
mMapView.onResume();
}
}
#Override
public void onPause() {
super.onPause();
if (mMapView != null) {
mMapView.onPause();
}
}
#Override
public void onLowMemory() {
super.onLowMemory();
if (mMapView != null) {
mMapView.onLowMemory();
}
}
#Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
if (mMapView != null) {
mMapView.onSaveInstanceState(outState);
}
}
#Override
public void onDestroy() {
super.onDestoy();
if (mMapView != null) {
mMapView.onDestroy();
}
}
Snippet of the layout. This layout is added programmatically:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:padding="5dp"
android:orientation="vertical">
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:clickable="true"
android:enabled="true"
android:layout_width="match_parent"
android:layout_height="250dp" />
<!-- More stuff below -->
I am including my API_KEY in the AndroidManifest.xml file:
<!-- lots of stuff above this... -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIza --rest of my key here--"
/>
</application>
The following images show the progression of tile painting I get with each click. Any tips are appreciated.
It's because you don't call
mMapView.onResume() in Activity's onResume() callback.
Started working with Android Studio, trying to display a Google Map in a fragment. The maps displays fine and I'm able to zoom/move the map around, but my markers will not display.
Here is my MapsActivity (HomePageMapsActivity.java):
public class HomePageMapsActivity extends FragmentActivity {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page_maps);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
/**
* Sets up the map if it is possible to do so, and the map has not already been instantiated.
* If not installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will prompt user to
* install/update the Google Play services APK on their device.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
/**
* This is where we can add markers, lines, listeners, or move the camera.
* Only call once and when sure {#link #mMap} is not null.
*/
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(33, -84)).title("Atlanta"));
}
}
The xml (activity_home_page_maps.xml):
<?xml version="1.0" encoding="utf-8"?>
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
tools:context="net.datanetics.campusresponseapp.HomePageMapsActivity" />
The home page xml (activity_home_page):
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/HomePageMap"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"
tools:context=".HomePageMapsActivity"
class="com.google.android.gms.maps.SupportMapFragment" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:weightSum="1" >
<Button
android:id="#+id/MenuButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:background="#3498DB"
android:text="Menu"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/EmergencyButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:background="#C1392B"
android:text="Emergency"
android:textColor="#FFFFFF" />
</LinearLayout>
Are you sure, your GoogleMap is not null? Try to get map asynchronously:
public class YourActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
SupportMapFragment fragMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page_maps);
fragMap = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
fragMap.getMapAsync(this);
}
#Override
public void onMapReady(final GoogleMap map) {
if (map != null) {
mMap = map;
setUpMap();
}
}
}
Two things:
1) You are trying to use the map too early. You need to have the view
first, so your code should be in onCreateView() not onCreate().
Correction: onCreateView() applies to fragments, not activities.
The app I used to test this used a Fragment to hold the map, not a
FragmentActivity.
2) I found I needed to prod the initialization of the map layers by
calling mMapView.onCreate() and mMapView.onResume() explicitly. See
also JoelLipman.com.
public class HomePageMaps extends SupportMapFragment {
private View mView;
private View mMapView;
private GoogleMap mMap;
#Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle state) {
super.onCreateView(inflater, group, state);
mView = inflater.inflate(R.layout.activity_home_page_maps, group, false);
mMapView= (MapView)mView.findViewById(R.id.map);
mMapView.onCreate(state);
mMapView.onResume();
mMap= mMapView.getMap();
mapUpdate();
return (mView);
}
private void mapUpdate() {
LatLng myLoc= new LatLng(33,-84);
MarkerOptions opt = new MarkerOptions();
mMap.clear();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLoc, 15));
mMap.addMarker(opt.position(myLoc).title("Me"));
}
}
I got your issue change this line
mMap.addMarker(new MarkerOptions().position(new LatLng(33, -84)).title("Atlanta"));
to
mMap.addMarker(new MarkerOptions().position(new LatLng(33.7550,84.3900)).title("Atlanta"));
you have to pass the double value in lat and lng.
I found my "FirstMap" project, hope it helps. You will want to
move your map into a fragment sooner rather than later.
MapsActivity.java
public class MapsActivity extends FragmentActivity {
private PageMap mPageMap;
public interface IAction {
boolean onClick(int BtnID);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageMap= new PageMap();
setContentView(R.layout.activity_main);
}
public void onClick(View Ctrl) {
int BtnID= Ctrl.getId();
switch(BtnID) {
case R.id.MainBtn_Map: ShowMap(); break;
default: mPageMap.onClick(BtnID);
}
}
private void ShowMap() {
LoadPage(mPageMap);
}
public void LoadPage(Fragment NewPage) {
FragmentManager Mgr= getSupportFragmentManager();
FragmentTransaction Action= Mgr.beginTransaction();
Action.replace(R.id.Main_FragmentContainer,NewPage);
Action.show(NewPage);
Action.commit();
}
}
res/layout/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"
>
<Button
android:id="#+id/MainBtn_Map"
android:onClick="onClick"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Load Map"
/>
<LinearLayout
android:id="#+id/Main_FragmentContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/material_blue_grey_800"
>
</LinearLayout>
</LinearLayout>
PageMap.java
public class PageMap extends SupportMapFragment implements MapsActivity.IAction {
private FragmentActivity mActivity;
private MapView mMapView;
private GoogleMap mMap;
#Override public void onAttach(Activity parent) {
mActivity= (FragmentActivity)parent;
super.onAttach(parent);
}
#Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle instance) {
super.onCreateView(inflater,group,instance);
View view= inflater.inflate(R.layout.page_map,group,false);
mMapView= (MapView)view.findViewById(R.id.map);
mMapView.onCreate(instance);
mMapView.onResume();
mMap= mMapView.getMap();
return(view);
}
public boolean onClick(int BtnID) {
switch(BtnID) {
case R.id.PageMap_BtnUpdate: return (Update());
}
return (false);
}
private boolean Update() {
setUpMap();
return(true);
}
private void setUpMap() {
if(mMap!=null) {
LatLng loc = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(loc).title("Marker"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(loc, 15));
}
}
}
//EOF: PAGEMAP.JAVA
res/layout/page_map.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<Button
android:id="#+id/PageMap_BtnUpdate"
android:onClick="onClick"
android:text="Update"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<com.google.android.gms.maps.MapView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
/>
</LinearLayout>
I have an Activity (which inflates a map fragment) which implements the GoogleMap.onCameraChangedListener, and I have overriden the onCameraChange method.
The problem is that whenever I move across the map, i.e. the camera position changes, the onCameraChange method is never called.
What could be causing this?
Try this :
public class MapActivity extends AppCompatActivity implements
GoogleMap.OnCameraChangeListener{
private GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.googlemap_layout);
setUpMapIfNeeded();
}
#Override
public void onCameraChange(CameraPosition cameraPosition) {
double latitude = cameraPosition.target.latitude;
double longitude = cameraPosition.target.longitude;
}
private void setUpMapIfNeeded() {
if (googleMap == null) {
// Try to obtain the map from the SupportMapFragment.
googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
if (googleMap != null) {
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(false);
googleMap.getUiSettings().setZoomControlsEnabled(false);
googleMap.setOnCameraChangeListener(this);
}
}
}
}
Layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>
I'm trying to initialize a GoogleMap instance, but SupportMapFragment returns null.
Here is my MainActivity Class:
public class MainActivity extends FragmentActivity
{
GoogleMap gMap;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
initMap(); //here is the NullPointerExeption
setContentView(R.layout.activity_map);
}
public boolean initMap()
{
if (gMap == null) {
SupportMapFragment mapFrag =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.fragMap);
gMap = mapFrag.getMap();
}
return (gMap != null);
}
}
And this is my activity_map.xml:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/fragMap"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
what is the problem? if I comment out the initMap() function, it works fine and displays the map.
I think you should change the order like
setContentView(R.layout.activity_map);
initMap();
First you should setContentView(R.layout.activity_map); and then reference Map from SupportMapFragment.
I want to add one Marker in Google map. I successfully loaded map in my app but when I tried to add a Marker, the app got crashed. I don't know why. Please some one help me!
My code:
public class BasicMapActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_demo);
setUpMap();
}
#Override
protected void onResume() {
super.onResume();
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
Layout.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/map2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>
Create a method setUpMapIfNeeded() and called on onResume() and onCreate()
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
First you need to obtain the map from the SupportMapFragment and then you add Marker into map using
mMap.addMarker(new MarkerOptions().position(new LatLng(Your_lat, Your_long)).title("Marker"));
Try This
private void setUpMap() {
Marker pos_Marker = googleMap.addMarker(new MarkerOptions().position(starting).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_laumcher)).title("Starting Location").draggable(false));
pos_Marker.showInfoWindow();
}