Author Archives: Spencer Smith

Screen shot resized

Android – Running an ArcGIS Map Offline

Many people know how to run ArcGIS on a desktop computer, and ESRI provides many tools to do so.  But what about workers in the field that need to see a map with specific objects?  Running offline maps on an Android device is an extremely useful tool and can help workers do a wide variety of things that before could only be done while sitting in an office.  Creating an offline map app on an Android device is something that is possible with the ESRI mobile API, but it can be tricky. So I will go over how to do two fundamental functions on an Android device: 1) Loading the offline map, and 2) querying at a specific location.

Required:

  • An Android Device (or emulator, I recommend GenyMotion if you go this way)
  • Android Studios (the latest version)
  • A file geodatabase, created using ArcGIS for desktop (with the desired layers that you want in the map loaded into it).
  1. Store the .geodatabase file on the physical device, remembering the folder hierarchy where it is stored.  The .geodatabase file is stored on the physical device in order to make it easier to sync/update the information. If the GIS data was stored inside of the actual application, it would be a much more lengthy process to update and change when your mapping data was changed. (Example path: /sdcard/Geodatabase/basemap.geodatabase)
  2. Create a new Android project in Android Studios, import the ArcGIS libraries and edit the build.gradle file accordingly (See: https://developers.arcgis.com/android/guide/install-and-set-up.htm for more information on how to get your Android app ready for ArcGIS maps).
  3. Place a MapView in your main layout. Match_parent for both width and height (We’ll call it mMapView)
  4. Because loading all of the layers from the .geodatabase file can take a hefty load on the device, it is good practice to run that on a separate background thread. To do this create a private class that extends AsyncTask and create a skeleton doInBackground method within it. (See bottom for full code)
  5. Instantiate an object of that private class in the onCreate method and call .execute() on it.
    
     MapView mMapView;
     Geodatabase geodatabase;
     private GeodatabaseFeatureTable geodatabaseFeatureTable;
     private FeatureLayer featureLayer;
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
    
          mMapView = (MapView) findViewById(R.id.map); //Instantiates the MapView object
          LoadMap mLoadMap = new LoadMap(); //Runs the LoadMap class on another thread
          mLoadMap.execute(); //Calls the background thread
    
     }
    
    

     

  6. Remember where you put the .geodatabasefile on the device? We’re going to use that now.  To add the layers to the MapView, we need to do it one by one. First, we will find the .geodatabasefile and loop through each of the layers that are contained therein, adding them one by one to the MapView. NOTE: the extent of the map will be determined by the first layer that is added on, so keep that in mind when creating your .geodatabase file and adding layers on, due to how our file was constructed, I add them on starting from the back, to get the full extent of the map.
    private class LoadMap extends AsyncTask<Void, Void, Void> {
    
            @Override
            protected Void doInBackground(Void... params) {
    
                try { //Opens up the basemap.geodatabase file from it's location on the physical device
                    geodatabase = new Geodatabase("/sdcard/Geodatabase/basemap.geodatabase");
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } finally { //Takes each layer one by one from the Geodatabase and adds it to the MapView
                    for (int i = (geodatabase.getGeodatabaseTables().size()) - 1; i >= 0; i--) {
                        geodatabaseFeatureTable = geodatabase.getGeodatabaseFeatureTableByLayerId(i);
                        featureLayer = new FeatureLayer(geodatabaseFeatureTable);
                        mMapView.addLayer(featureLayer);
                    }
                }
                return null;
            }
        }
    
  7. Once that is set up, run the app on the device that has the .geodatabase and it will loop through the layers, adding them to the view one by one. Your output should be to this:

Screenshot_2015-02-17-11-03-22

It is a very simple, but necessary, first step to getting a complicated, interactive custom ArcGIS application running on your Android device, free of any WiFi connection!  In my next blog post I will detail how to interact with the map, showing how to query objects at a point tapped on the map. Stay tuned!