Create a basemap from a tiled service (download a basemap) Example

4446
7
Jump to solution
11-13-2013 02:41 PM
by Anonymous User
Not applicable
OK I am trying to use the example to build an offline tpk from a tiled service. 

https://developers.arcgis.com/en/android/guide/create-an-offline-map.htm#ESRI_SECTION1_286D33A9E13C4...

There are not good examples so I am trying to follow the example from ArcGIS Runtime and adjust it to ArcGIS Runtime for Android.

https://developers.arcgis.com/en/java/sample-code/download-tile-cache-beta/

  The problem I appear to be having is on the CallbackListener. 

The line where the issue seems to be happening is  new CallbackListener<TileCacheStatus>() {
where I get the following error....

"java.io.FileNotFoundException: /1029171819/TileCacheStatus:


The code is below....  Any thoughts on what I am doing wrong here.


Envelope extent = new Envelope (-13656926.435,  5702260.809, -13655933.12,  5703167.369);
boolean createAsTilePackage = true;
        // fix this to 5 levels
        double[] levels = {0, 1, 2, 3, 4};
    
     GenerateTileCacheParameters params = new GenerateTileCacheParameters(
             createAsTilePackage,
             levels,
             ExportBy.ID,
             extent,
             mMapView.getSpatialReference());
tileCacheTask = new TileCacheTask("http://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Street_Map/MapServer", null);

tileCacheTask.submitTileCacheJobAndDownload(
               // parameters
               params,
               // status callback
               new CallbackListener<TileCacheStatus>() {
                 private boolean errored = false;
                
                 @Override
                 public void onError(Throwable e) {
                   errored = true;
                   //updateProgressBarUI(null, false);
                   e.printStackTrace();
                 }
                
                 @Override
                 public void onCallback(TileCacheStatus status) {
                   if (!errored) {
                    // updateProgressBarUI("Latest status: "+status.getStatus(), true);
                   }
                 }
               },
               // callback when download complete
               new CallbackListener<String>() {
                 private boolean errored = false;
          
                 @Override
                 public void onError(Throwable e) {
                   errored = true;
                  // updateProgressBarUI(null, false);
                   e.printStackTrace();
                 }
          
                 @Override
                 public void onCallback(String path) {
                   if (!errored) {
                    // updateProgressBarUI("Tile cache download complete. Switching to local layer...", true);
                    // switchToLocalLayer(path);
                    // updateProgressBarUI(null, false);
                     //tpkButton.setEnabled(true); // re-enable button for another job
                   }
                 }
               },
               // path for downloaded tile cache
               "file:///storage/extSdCard/Reference_Data/TPK/Test.tpk");
0 Kudos
1 Solution

Accepted Solutions
DanO_Neill
Occasional Contributor III
No. I´m just testing a code. This feature only works after the app was licenced ?


You do not need to license your app to use API in developer mode. 

I try to run this code with runtime 10.2.3 (using the new ExportTileCacheTask class instead TileCacheTask) but I got the error below

com.esri.core.io.EsriSecurityException: Unauthorized access to a secure service - http://tiledbasemaps.arcgis.com/arcg...iles/submitJob


You need to generate a token to use this service.

View solution in original post

0 Kudos
7 Replies
DanO_Neill
Occasional Contributor III
We are working currently working on a sample for Android and will make it available on ArcGIS Online when it is complete.  Below is some working code for creating the tiles locally by calling submitTileCacheJobAndDownload.

 
/**
* Creates tile Cache locally by calling submitTileCacheJobAndDownload
*
* @param params
* @param tileCacheTask
* @param tileCachePath
*/
private void createTileCache(GenerateTileCacheParameters params,
final TileCacheTask tileCacheTask, final String tileCachePath) {

  // Set the recovery directory for incomplete tasks
  tileCacheTask.setRecoveryDir(recoveryDir);

  // estimate tile cache size

  tileCacheTask.estimateTileCacheSize(params,
  new CallbackListener<Long>() {

  @Override
  public void onError(Throwable e) {
    Log.d("*** tilecachesize error: ", "" + e);
  }

  @Override
  public void onCallback(Long objs) {
    Log.d("*** tilecachesize: ", "" + objs);

  }
});

// Submit tile cache job and download

tileCacheTask.submitTileCacheJobAndDownload(params, null,
  new CallbackListener<String>() {
    private boolean errored = false;

    @Override
    public void onError(Throwable e) {
      errored = true;
      // print out the error message and disable the progress bar
      Log.d("*** submitTileCacheJobAndDownload error: ", "" + e);
      mProgress.setVisibility(View.GONE);
    }

    @Override
    public void onCallback(String path) {
      if (!errored) {
        Log.d("the Download Path = ", "" + path);
        // Disable the progress bar and switch to the
        // successfully downloaded local layer
        mProgress.setVisibility(View.GONE);
        switchToLocalLayer(path);
     }
    }
}, tileCachePath);

// recover all incomplete jobs contained in the recovery directory
tileCacheTask.recoverAllJobs(new CallbackListener<TileCacheStatus>() {

@Override
public void onError(Throwable e) {
  Log.d("*** recoverAllJobs error: ", "" + e);
  mProgress.setVisibility(View.GONE);
}

@Override
public void onCallback(TileCacheStatus objs) {
  Log.d("***", " start recovery" + objs);
  }
}, new CallbackListener<String>() {

@Override
public void onError(Throwable e) {
  mProgress.setVisibility(View.GONE);
}

@Override
public void onCallback(String objs) {
  Log.d("***", " end recovery" + objs);
  mProgress.setVisibility(View.GONE);
  }
});

}
0 Kudos
by Anonymous User
Not applicable
Dan, Thanks for the assistance.  I was able to get my code to successfully cache.  For anyone interested here is the code that worked for me.  Will definitely need to add a progress bar as the download itself can take awhile.  Will probably need to restrict this tool based on the estimated cache size.

Aaron Dick
Service First Mobile GIS Program Lead
Oregon Washington BLM
USFS Pacific NW Lead


buttonCacheTiles.setOnClickListener(new View.OnClickListener() {
    
     @Override
     public void onClick(View v) {
      // TODO Auto-generated method stub
     
     
      Geometry extent = new Envelope (-13656747.243,  5702686.121, -13656740.229,  5702696.346);
     
      tileCacheTask = new TileCacheTask("http://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Street_Map/MapServer", null);
    
      GenerateTileCacheParameters params = createParameters(extent);
 
     final String tileCachePath = "/storage/extSdCard/Reference_Data/TPK/Test2.tpk";
       createTileCache(params, tileCacheTask, tileCachePath);
     
     }
    });

private GenerateTileCacheParameters createParameters(Geometry extent) {

    boolean createAsTilePackage = true;
     // fix this to 5 levels
    // double[] levels = {0, 1, 2, 3, 4};
    double[] levels = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
     // set up parameters
     GenerateTileCacheParameters params = new GenerateTileCacheParameters(
       createAsTilePackage,
         levels,
         ExportBy.ID,
         extent,
         mMapView.getSpatialReference());

     return params;
   }




private void createTileCache(GenerateTileCacheParameters params,
   final TileCacheTask tileCacheTask, final String tileCachePath) {

  String recoveryDir = "/storage/extSdCard/Reference_Data/Temp";
     // Set the recovery directory for incomplete tasks
     tileCacheTask.setRecoveryDir(recoveryDir);

     // estimate tile cache size

     tileCacheTask.estimateTileCacheSize(params,
     new CallbackListener<Long>() {
   
     @Override
     public void onError(Throwable e) {
       Log.d("*** tilecachesize error: ", "" + e);
     }

     @Override
     public void onCallback(Long objs) {
       Log.d("*** tilecachesize: ", "" + objs);
     
     }
   });

   // Submit tile cache job and download

   tileCacheTask.submitTileCacheJobAndDownload(params, null,
     new CallbackListener<String>() {
       private boolean errored = false;

       @Override
       public void onError(Throwable e) {
         errored = true;
         // print out the error message and disable the progress bar
         Log.d("*** submitTileCacheJobAndDownload error: ", "" + e);
        // mProgress.setVisibility(View.GONE);
       }

       @Override
       public void onCallback(String path) {
         if (!errored) {
           Log.d("the Download Path = ", "" + path);
           // Disable the progress bar and switch to the
           // successfully downloaded local layer
           //mProgress.setVisibility(View.GONE);
          switchToLocalLayer(path);
        }
       }
   }, tileCachePath);

  
   
   // recover all incomplete jobs contained in the recovery directory
   tileCacheTask.recoverAllJobs(new CallbackListener<TileCacheStatus>() {

   @Override
   public void onError(Throwable e) {
     Log.d("*** recoverAllJobs error: ", "" + e);
    // mProgress.setVisibility(View.GONE);
   }

   @Override
   public void onCallback(TileCacheStatus objs) {
     Log.d("***", " start recovery" + objs);
     }
   }, new CallbackListener<String>() {

   @Override
   public void onError(Throwable e) {
    // mProgress.setVisibility(View.GONE);
   }

   @Override
   public void onCallback(String objs) {
     Log.d("***", " end recovery" + objs);
    // mProgress.setVisibility(View.GONE);
     }
   });




}


  private void switchToLocalLayer(final String path) {
    //  SwingUtilities.invokeLater(new Runnable() {

       // @Override
        //public void run() {
       
 
       mMapView.removeAll();

     
        mMapView.addLayer(new ArcGISLocalTiledLayer("file:///storage/extSdCard/Reference_Data/TPK/Test2.tpk"));
   
    
    }
0 Kudos
LisandroRueckert
New Contributor II
Hello,

I try to run this code with runtime 10.2.3 (using the new ExportTileCacheTask class instead TileCacheTask) but I got the error below

com.esri.core.io.EsriSecurityException: Unauthorized access to a secure service - http://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Street_Map/MapServer/exportTiles/submitJo...

The same error has ocurred when I try to run the OfflineTiledLayer example from Java SDK.

Anyone knows what is wrong ?


Thank´s

Lisandro
0 Kudos
EdwardLin
New Contributor II
Do you License your app at the Basic level?
0 Kudos
LisandroRueckert
New Contributor II
Do you License your app at the Basic level?


No. I´m just testing a code. This feature only works after the app was licenced ?
0 Kudos
DanO_Neill
Occasional Contributor III
No. I´m just testing a code. This feature only works after the app was licenced ?


You do not need to license your app to use API in developer mode. 

I try to run this code with runtime 10.2.3 (using the new ExportTileCacheTask class instead TileCacheTask) but I got the error below

com.esri.core.io.EsriSecurityException: Unauthorized access to a secure service - http://tiledbasemaps.arcgis.com/arcg...iles/submitJob


You need to generate a token to use this service.
0 Kudos
by Anonymous User
Not applicable
When I wrote the code above it did not require credentials.  However that changed, so now you must have the code as follows...

UserCredentials credentials;
    credentials = new UserCredentials();
      credentials.setUserAccount(username, password);
  
    tileCacheTask = new ExportTileCacheTask("http://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Street_Map/MapServer", credentials);
0 Kudos