AddLayer after OnCreate NOT working. BUG?

1142
10
05-13-2013 01:42 AM
JessicaSena
New Contributor
Hi,

I'm experimenting a weird behaviour with map.addLayer() method and I'm not sure if it's a bug or I'm missing something.

The thing is that in some Android devices (i.e. Samsung Galaxy Ace) when I add layers to the map after the OnCreate method these layers are not showing in the map, but if I add the layers during the onCreate method, these layers are showing correctly.

I could guess that you can only use the addLayer method on the OnCreate process, but it has no sense because as I say, this only happens in some Android devices... and that's why I'm not getting which is the exact problem.

These are two examples about 2different ways of how I add the layers:

map.removeAll();
WMSLayer wms = new WMSLayer("http://mapcache.icc.cat/map/bases/service?",SpatialReference.create(23031));
map.addLayer(wms);


or

baseLayer.setVisible(false);//I set to not visible the current layer added to the map
WMSLayer wms = new WMSLayer("http://mapcache.icc.catmapbasesservice?",SpatialReference.create(23031));
map.addLayer(wms);


Anyone has noticed the same? Anyone from ESRI could try to reproduce the problem?

Thanks in advanced,
0 Kudos
10 Replies
JessicaSena
New Contributor
Hi again,

then, nobody else has experimented the same issue? I've been doing some more research with no luck.

Actually, I download de BaseMaps example, given by ESRI, where they only add 4base layers to the mapn in the onCreate, and then they only change the visibility of each depending on which one you choose. I've modified this to use the "add" and "remove" map operations, instead of addind all layers in the on Create and going on changing the visibility, and indeed, it doesn't work neither in my samsung galaxy ace:

//In the original code:
case R.id.World_Topo:
 
   basemapStreet.setVisible(false);
   basemapNatGeo.setVisible(false);
   basemapOcean.setVisible(false);
   basemapTopo.setVisible(true);

//In my code
case R.id.World_Topo:
   mMapView.removeAll();
   mMapView.addLayer(basemapTopo);  

And, misteriously (at least for me) the second snippet doesn't work in some devices.

Please, could anyone give me some advice of how to solve it? Is it normal? Is it impossible to add/remove layers dynamically? or I have to assume that you have to manage the layers of the map in a kinf od "static way" knowing from the begining all the layers you're going to use?

Thanks,
0 Kudos
KevinGebhardt
New Contributor III
Hello,
Can you please post how your MapView was created. Did you added it to your layout.xml?
Normally a layer is shown after it has been added to a mapview.
Have you also set the extent of your map view.
I think, it would be a good idea to post your complete code so I could check it myself.

Greetings
0 Kudos
JessicaSena
New Contributor
Yes, of course! Here's the code of the example "Basemaps" provided for ESRI:



[INDENT]public class BasemapsActivity extends Activity {

[INDENT] MapView mMapView = null;
ArcGISTiledMapServiceLayer basemapStreet;
ArcGISTiledMapServiceLayer basemapTopo;
ArcGISTiledMapServiceLayer basemapNatGeo;
ArcGISTiledMapServiceLayer basemapOcean;[/INDENT]

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
[INDENT]  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  // Retrieve the map and initial extent from XML layout
  mMapView = (MapView) findViewById(R.id.map);
  /* create an initial basemap */
  basemapStreet = new ArcGISTiledMapServiceLayer(this.getResources()
    .getString(R.string.WORLD_STREET_MAP));
  basemapTopo = new ArcGISTiledMapServiceLayer(this.getResources()
    .getString(R.string.WORLD_TOPO_MAP));
  basemapNatGeo = new ArcGISTiledMapServiceLayer(this.getResources()
    .getString(R.string.WORLD_NATGEO_MAP));
  basemapOcean = new ArcGISTiledMapServiceLayer(this.getResources()
    .getString(R.string.OCEAN_BASEMAP));
  // set visibility
  basemapTopo.setVisible(false);
  basemapNatGeo.setVisible(false);
  basemapOcean.setVisible(false);

  // attribute ESRI logo to map 
                mMapView.setEsriLogoVisible(true); [/INDENT]
 
[INDENT]  // Add basemap to MapView
  mMapView.addLayer(basemapStreet);
  mMapView.addLayer(basemapTopo);
  mMapView.addLayer(basemapNatGeo);
  mMapView.addLayer(basemapOcean);[/INDENT]

  // enable map to wrap around date line
  mMapView.enableWrapAround(true);
}

public boolean onCreateOptionsMenu(Menu menu) {
[INDENT]  MenuInflater inflater = getMenuInflater();
  inflater.inflate(R.menu.basemap_menu, menu);
  return true;[/INDENT]
}

public boolean onOptionsItemSelected(MenuItem item) {
[INDENT]  // handle item selection
 
  switch (item.getItemId()) {
  case R.id.World_Street_Map:
   [INDENT]basemapStreet.setVisible(true);
   basemapTopo.setVisible(false);
   basemapNatGeo.setVisible(false);
   basemapOcean.setVisible(false);
   return true;[/INDENT]
  case R.id.World_Topo: 
   [INDENT]basemapStreet.setVisible(false);
   basemapNatGeo.setVisible(false);
   basemapOcean.setVisible(false);
   basemapTopo.setVisible(true);
   return true;[/INDENT]
  case R.id.NatGeo:  
   [INDENT]basemapStreet.setVisible(false);
   basemapTopo.setVisible(false);
   basemapOcean.setVisible(false);
   basemapNatGeo.setVisible(true);
   return true;[/INDENT]
  case R.id.Ocean_Basemap:  
   [INDENT]basemapStreet.setVisible(false);
   basemapTopo.setVisible(false);
   basemapNatGeo.setVisible(false);
   basemapOcean.setVisible(true);[/INDENT]
  default:
   [INDENT]return super.onOptionsItemSelected(item);[/INDENT][/INDENT]
  }
}

@Override
protected void onPause() {
[INDENT]  super.onPause();
  mMapView.pause();[/INDENT]
}

@Override
protected void onResume() {
[INDENT]  super.onResume();
  mMapView.unpause();[/INDENT]
}

}

[/INDENT]
So, the point is, if I comment the "map.addLayer(X)" lines, in the onCreate (setting layers visibility to true), and in every case of the switch, instead of setting the visibility, I do:

[INDENT]  case R.id.World_Topo:
   [INDENT]mMapView.removeAll();
   mMapView.addLayer(basemapTopo);  
//   basemapStreet.setVisible(false);
//   basemapNatGeo.setVisible(false);
//   basemapOcean.setVisible(false);
//   basemapTopo.setVisible(true);[/INDENT][/INDENT]


that means, I remove all the possible layers in the map and I add a new one, for some devices the new layer is not showing. I've tested with diffetent combinations of adding and removing layers and the problem persists. I've tested not doing a "remove" or removeAll", only the "add", and it doesn't work neither (with this I mean, that I guess that the remove is not the problem) I've only solved the issue adding all the layers in the onCreate... but that would mean that you can't add layers dynamically to your map...

Any idea what's going on?

The same code is working for the following devices:
Samsung galaxy s3
Sony ericsson st18i
LG e610
Samsung galaxy TAB

and not working for:
Samsung Galaxy ACE
Samsung tab 10.1

Thanks, hope somebody can help me
0 Kudos
KevinGebhardt
New Contributor III
I tried your code on my Medion tablet with Android 4.0.3 and it works.
What are the android-versions of your tablets / smartphones?
Is the min- and the max-SDK property in the AndroidManifest.xml set correctly?
Can you see nothing at all or the empty grid of the tiled layers? Maybe it could help to zoom to a known location with
mMapView.zoomToScale(yourCenter, yourScale);
0 Kudos
JessicaSena
New Contributor
Hi, thanks for trying!

The models and the android version they have are:


[INDENT]Devices where the code works:

Sony Ericsson st18i / 2.3.4
Sony Ericsson Xpersia P / 4.0.x
Samsung Galaxy s3 / 4.1.x �?? 4.2.x
LG e610 / 4.1.x
Samsung Galaxay Tab / 2.3.6

Devices where DOESN'T work

Samsung galaxy note II / 3.0
Samsun galaxy Ace 2.3.6[/INDENT]



As you see, it makes no sense neither... why the code is working in some devices and the others not?

I've checked the min amb max version and it's ok:


[INDENT]    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />[/INDENT]


About your question, I can see the grid, but not the layer... it seems that the "map" object is ok, but I don't understand why, th e layer is not being "painted"... I've tried to zoomtoscale in the map, changing map extent, and some other combinations with no luck 😞

I'm really lost about it... any help will be grateful!

Thanks,
0 Kudos
KevinGebhardt
New Contributor III
It sounds like the layer could be initialized, otherwise you would not get the empty grid. Did you tried to display the scale and the center of the map in a textview. Can you get Attributes from the layers like getVisibility(), getExtent() or getLayers(). Check if you get any exceptions then you try to fetch these attributes.
0 Kudos
JessicaSena
New Contributor
Hi,

Actually, yes, I'm pretty sure the layer is indeed initialized. After the:


[INDENT]   mMapView.removeAll();
   mMapView.addLayer(basemapTopo);[/INDENT]

If I get the layers added to the map:


[INDENT]Layer[] list = mMapView.getLayers();[/INDENT]


And I check all the properties, I'm getting the following log with my samsung galaxy ace (the one which is not working)


[INDENT]05-28 14:38:06.210: I/BASEMAP(9888): l.getHeight():430
05-28 14:38:06.210: I/BASEMAP(9888): l.getID():2236624
05-28 14:38:06.210: I/BASEMAP(9888): l.getMaxScale():0.0
05-28 14:38:06.242: I/BASEMAP(9888): l.getMinScale():0.0
05-28 14:38:06.242: I/BASEMAP(9888): l.getName():Layers
05-28 14:38:06.242: I/BASEMAP(9888): l.getOpacity():1.0
05-28 14:38:06.273: I/BASEMAP(9888): l.getResolution():125234.41916976124
05-28 14:38:06.273: I/BASEMAP(9888): l.getTitle():null
05-28 14:38:06.273: I/BASEMAP(9888): l.getUrl():http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer
05-28 14:38:06.273: I/BASEMAP(9888): l.getWebMapLayerID():null
05-28 14:38:06.273: I/BASEMAP(9888): l.getWidth():320
05-28 14:38:06.273: I/BASEMAP(9888): l.getDefaultSpatialReference()com.esri.core.geometry.SpatialReference@4057f900
05-28 14:38:06.273: I/BASEMAP(9888): l.isInitialized():true
05-28 14:38:06.273: I/BASEMAP(9888): l.isVisible():true
05-28 14:38:06.273: I/BASEMAP(9888): l.getHeight()false
[/INDENT]


And the same values (except the ones relative to the screen resolution, etc) for my samsung galaxy s3, where the code works.


The map getVisibility is the correct one too (value 0 = VISIBLE).


I mean, everything looks like it has to work. The map is initialized, the layer too, and it seems that is properly added to the map... but, for some reason, is not being rendered in the device...

Anyone from ESRI could confirm that this should work, and try to check it by himself?


Thanks
0 Kudos
DanO_Neill
Occasional Contributor III
I edited the Basemaps sample as you suggested in the post and cannot reproduce on a Galaxy Nexus or a Nexus 7 with Android 4.2.2 .  I am looking to see if I can find the specific devices you are referencing.

Concerning your question about adding/removing layers ...
Adding all the layers and setting the visibility of the layer with Layer.setVisible() is the preferred approach as layers will be initialized once.  That is the reason the Basemaps samples uses that pattern.  However, if all of your layers share the same spatial reference you can instantiate the MapView with the Spatial Reference and Extent then add/remove any layers.  Is there a reason you prefer to add/remove layers over setting the visibility?
0 Kudos
JessicaSena
New Contributor
Hey Dan,

First of all, thanks for answering and trying the code.

About your question, there are some reasons for which I prefer the add/remove behaviour:

- The less important, because I have many layers, and I was not sure about how many layers you could add to the map object without a loss of eficiency. Do you have any specific data about it?

Anyway, the two more importants reasons are the following:

- In my app I want to offer the user the option to add "manually" layers to the map, that means, the user will be capable to write the URL, and the app will create the new layer with this URL, and then will add it to the map. And in the same way, after that, the user will be able to remove it.

- I'm working with tpk's, and depending on the tpk's available in the device I will choose ones or anothers, that is, I don't know from the beginning which ones or how many I'll have.

To sum up, I need a dynamic behaviour about the layers in the map... I'm already using the "visibility pattern" for my base layers that always will be in the map, but I cannot do that for the others.

The worst thing is that I don't understand why the add/remove code does not work in some devices. And although you say that the preferred approach is setting the visibility, I assume that the add/remove should work too, otherwise which would be the point of add/remove operations?

Thanks in advanced, and looking forward the results of your tests

Jessica
0 Kudos