<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Offline database backed tile layer in ArcGIS Runtime SDK for Android Questions</title>
    <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605292#M4184</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE class="jive-quote"&gt;Is the script actually importing the Compact Cache Bundle Files into an SQLite DB or is it extracting the images (essentially the exploded format) in the bundle and putting those files in the DB.&amp;nbsp; That is, would I need to create the cache in exploded format in order to import the files with your script. Can you provide some timing info?&amp;nbsp; How long does it take to import for a particular size cache?&amp;nbsp; Is viewing the tiles as fast and smooth as it is with the ArcGISLocalTiledLayer class?&lt;/BLOCKQUOTE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;It uses an exploded cache since there wouldn't be any benefit of creating the compact cache only to rip it back apart. It takes a few minutes, probably less than 20 to build the entire sqlite db. I have noticed no difference at all in speed versus a local tiled layer.&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Fri, 20 Apr 2012 12:20:44 GMT</pubDate>
    <dc:creator>JozefKaslikowski</dc:creator>
    <dc:date>2012-04-20T12:20:44Z</dc:date>
    <item>
      <title>Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605286#M4178</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;SPAN&gt;The offline abilities of the android runtime are limited to using compact caches. Even those are pretty much unusable when tiling large areas. My maps for example end up as 800+MB with thousands of files. Half the tiles are blank and completely unneeded. So I now import them into a sqlite database and throwaway all of the blank tiles, cutting my download size in half and making my file count one. As a result, the transfers of the map caches are much faster for offline use.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I can post the tile importer script also if anyone else is interested.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;PRE class="plain" name="code"&gt;
package com.main.utilinspect;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;

import android.content.Context;
import android.util.Log;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.esri.core.internal.c.d;
import com.esri.core.internal.c.h;
import com.esri.core.internal.c.l;

import com.esri.android.map.TiledServiceLayer;

public class OfflineDbTiledLayer extends TiledServiceLayer {
 
 File workingDirectory;
 String mapDefinition;
 String databaseName;
 private SQLiteDatabase database;
 File blankImage;
 
 byte[] blankImageBytes;
 
 private final Object lock = new Object();
 
 
 private static final String TAG = "OfflineTiledLayer"; 
 

 public OfflineDbTiledLayer(Context paramContext, File workingDirectory, String mapDefinition, String databaseName)&amp;nbsp; {
&amp;nbsp; super("required");
&amp;nbsp; this.workingDirectory = workingDirectory;
&amp;nbsp; this.mapDefinition = mapDefinition;
&amp;nbsp; this.databaseName = databaseName;
&amp;nbsp; 
&amp;nbsp; String databasePath = workingDirectory.getAbsolutePath() + File.separator + databaseName;
&amp;nbsp; 
&amp;nbsp; this.database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
&amp;nbsp; 
&amp;nbsp; this.blankImage = new File(workingDirectory.getAbsolutePath() + File.separator + "blank.png");
&amp;nbsp; 
&amp;nbsp; RandomAccessFile raFile = null;
&amp;nbsp; 
&amp;nbsp; try {
&amp;nbsp;&amp;nbsp; raFile = new RandomAccessFile(this.blankImage, "r");
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; blankImageBytes = new byte[(int) raFile.length()];
&amp;nbsp;&amp;nbsp; raFile.readFully(blankImageBytes);
&amp;nbsp;&amp;nbsp; 
&amp;nbsp; } catch (FileNotFoundException e) {
&amp;nbsp;&amp;nbsp; // TODO Auto-generated catch block
&amp;nbsp;&amp;nbsp; e.printStackTrace();
&amp;nbsp; } catch (IOException e) {
&amp;nbsp;&amp;nbsp; // TODO Auto-generated catch block
&amp;nbsp;&amp;nbsp; e.printStackTrace();
&amp;nbsp; }&amp;nbsp; 
&amp;nbsp; finally {
&amp;nbsp;&amp;nbsp; if(raFile != null) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raFile.close();
&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (IOException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO Auto-generated catch block
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp; }
&amp;nbsp; } 
&amp;nbsp; 
&amp;nbsp; h h1 = null;
&amp;nbsp; 
&amp;nbsp; try
&amp;nbsp; {
&amp;nbsp; 
&amp;nbsp; JsonParser paramJsonParser = new JsonFactory()
&amp;nbsp; .createJsonParser(new File(workingDirectory.getAbsolutePath() + File.separator + mapDefinition));
&amp;nbsp; paramJsonParser.nextToken(); 
&amp;nbsp; 
&amp;nbsp; h1 = h.a(paramJsonParser, "test");
&amp;nbsp; }
&amp;nbsp; catch(Exception ex){
&amp;nbsp;&amp;nbsp; 
&amp;nbsp; }&amp;nbsp; 
&amp;nbsp; 
&amp;nbsp; 
&amp;nbsp; setFullExtent(h1.f());&amp;nbsp; 
&amp;nbsp; setDefaultSpatialReference(h1.c());
&amp;nbsp; setInitialExtent(h1.e());
&amp;nbsp; 
&amp;nbsp; l l1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List list;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double ad[] = new double[i = (list = (l1 = h1.d()).h).size()];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double ad1[] = new double&lt;I&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int j = 0; j &amp;lt; list.size(); j++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ad&lt;J&gt; = ((d)list.get(j)).b();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ad1&lt;J&gt; = ((d)list.get(j)).a();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp; 
&amp;nbsp; setTileInfo(new com.esri.android.map.TiledServiceLayer.TileInfo(l1.f, ad, ad1, i, l1.c, l1.b, l1.a));
&amp;nbsp; 
&amp;nbsp; super.initLayer();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&amp;nbsp; 
 } 
 
 private void openDatabase(){
&amp;nbsp; if(!database.isOpen()){
&amp;nbsp;&amp;nbsp; String databasePath = workingDirectory.getAbsolutePath() + File.separator + databaseName;
&amp;nbsp;&amp;nbsp; this.database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
&amp;nbsp; }
 }
 
 private void closeDatabase(){
&amp;nbsp; if(database.isOpen()){
&amp;nbsp;&amp;nbsp; this.database.close();
&amp;nbsp; }
 }

 @Override
 protected byte[] getTile(int level, int column, int row) throws Exception {
&amp;nbsp; byte[] tileImage;&amp;nbsp; 
&amp;nbsp; 
&amp;nbsp; Log.i(TAG, "getTile");
&amp;nbsp; 
&amp;nbsp; Log.i(TAG, "getTile - retrieving tile"); 
&amp;nbsp; 
&amp;nbsp; 
&amp;nbsp; synchronized(lock) {
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - entered synchronized block");
&amp;nbsp; 
&amp;nbsp;&amp;nbsp; openDatabase();&amp;nbsp; 
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; // First check to see if the tile exists in the database
&amp;nbsp;&amp;nbsp; Cursor tileCursor = database.rawQuery("SELECT image FROM tiles WHERE level = " + Integer.toString(level) + " AND row = " + Integer.toString(row) + " AND column = " + Integer.toString(column), null);
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; if(tileCursor != null &amp;amp;&amp;amp; tileCursor.getCount() &amp;gt; 0) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; tileCursor.moveToFirst();
&amp;nbsp;&amp;nbsp;&amp;nbsp; tileImage = tileCursor.getBlob(0);
&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - tile found, returning image");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp; else {
&amp;nbsp;&amp;nbsp;&amp;nbsp; // The tile does not exist in the database, read the blank placeholder tile and serve it
&amp;nbsp;&amp;nbsp;&amp;nbsp; tileImage = blankImageBytes;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - tile not found returning blank");
&amp;nbsp;&amp;nbsp; } 
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; tileCursor.close();&amp;nbsp; 
&amp;nbsp;&amp;nbsp; this.database.close();
&amp;nbsp; }
&amp;nbsp; 
&amp;nbsp; Log.i(TAG, "getTile - exited synchronized block");
&amp;nbsp; 
&amp;nbsp; return tileImage; 
 }

 

}

&lt;/J&gt;&lt;/J&gt;&lt;/I&gt;&lt;/PRE&gt;&lt;DIV style="display:none;"&gt; &lt;/DIV&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Feb 2012 12:57:01 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605286#M4178</guid>
      <dc:creator>JozefKaslikowski</dc:creator>
      <dc:date>2012-02-22T12:57:01Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605287#M4179</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE class="jive-quote"&gt;The offline abilities of the android runtime are limited to using compact caches. Even those are pretty much unusable when tiling large areas. My maps for example end up as 800+MB with thousands of files. Half the tiles are blank and completely unneeded. So I now import them into a sqlite database and throwaway all of the blank tiles, cutting my download size in half and making my file count one. As a result, the transfers of the map caches are much faster for offline use.&lt;BR /&gt;&lt;BR /&gt;I can post the tile importer script also if anyone else is interested.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;
package com.main.utilinspect;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;

import android.content.Context;
import android.util.Log;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.esri.core.internal.c.d;
import com.esri.core.internal.c.h;
import com.esri.core.internal.c.l;

import com.esri.android.map.TiledServiceLayer;

public class OfflineDbTiledLayer extends TiledServiceLayer {
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; File workingDirectory;
&amp;nbsp;&amp;nbsp;&amp;nbsp; String mapDefinition;
&amp;nbsp;&amp;nbsp;&amp;nbsp; String databaseName;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private SQLiteDatabase database;
&amp;nbsp;&amp;nbsp;&amp;nbsp; File blankImage;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] blankImageBytes;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; private final Object lock = new Object();
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; private static final String TAG = "OfflineTiledLayer";&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; 

&amp;nbsp;&amp;nbsp;&amp;nbsp; public OfflineDbTiledLayer(Context paramContext, File workingDirectory, String mapDefinition, String databaseName)&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super("required");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.workingDirectory = workingDirectory;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.mapDefinition = mapDefinition;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.databaseName = databaseName;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String databasePath = workingDirectory.getAbsolutePath() + File.separator + databaseName;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.blankImage = new File(workingDirectory.getAbsolutePath() + File.separator + "blank.png");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RandomAccessFile raFile = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raFile = new RandomAccessFile(this.blankImage, "r");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blankImageBytes = new byte[(int) raFile.length()];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raFile.readFully(blankImageBytes);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (FileNotFoundException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO Auto-generated catch block
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (IOException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO Auto-generated catch block
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(raFile != null) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raFile.close();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (IOException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO Auto-generated catch block
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h h1 = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JsonParser paramJsonParser = new JsonFactory()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .createJsonParser(new File(workingDirectory.getAbsolutePath() + File.separator + mapDefinition));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; paramJsonParser.nextToken();&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h1 = h.a(paramJsonParser, "test");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch(Exception ex){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setFullExtent(h1.f());&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setDefaultSpatialReference(h1.c());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setInitialExtent(h1.e());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l l1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List list;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double ad[] = new double[i = (list = (l1 = h1.d()).h).size()];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double ad1[] = new double&lt;I&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int j = 0; j &amp;lt; list.size(); j++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ad&lt;J&gt; = ((d)list.get(j)).b();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ad1&lt;J&gt; = ((d)list.get(j)).a();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setTileInfo(new com.esri.android.map.TiledServiceLayer.TileInfo(l1.f, ad, ad1, i, l1.c, l1.b, l1.a));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super.initLayer();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; private void openDatabase(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(!database.isOpen()){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String databasePath = workingDirectory.getAbsolutePath() + File.separator + databaseName;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; private void closeDatabase(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(database.isOpen()){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.database.close();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override
&amp;nbsp;&amp;nbsp;&amp;nbsp; protected byte[] getTile(int level, int column, int row) throws Exception {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] tileImage;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - retrieving tile");&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; synchronized(lock) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - entered synchronized block");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; openDatabase();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // First check to see if the tile exists in the database
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cursor tileCursor = database.rawQuery("SELECT image FROM tiles WHERE level = " + Integer.toString(level) + " AND row = " + Integer.toString(row) + " AND column = " + Integer.toString(column), null);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(tileCursor != null &amp;amp;&amp;amp; tileCursor.getCount() &amp;gt; 0) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tileCursor.moveToFirst();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tileImage = tileCursor.getBlob(0);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - tile found, returning image");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // The tile does not exist in the database, read the blank placeholder tile and serve it
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tileImage = blankImageBytes;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - tile not found returning blank");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tileCursor.close();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.database.close();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Log.i(TAG, "getTile - exited synchronized block");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return tileImage;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; 

}

&lt;/J&gt;&lt;/J&gt;&lt;/I&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Hi Jeff&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;can i have a look at the importer script please.&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sun, 12 Dec 2021 01:57:16 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605287#M4179</guid>
      <dc:creator>hermancheah</dc:creator>
      <dc:date>2021-12-12T01:57:16Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605288#M4180</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE class="jive-quote"&gt;Hi Jeff&lt;BR /&gt;can i have a look at the importer script please.&lt;/BLOCKQUOTE&gt;&lt;BR /&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;This is the python script that does &lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;
#This script updates all tiles in an ArcGIS Server 10 map cache

import datetime
import os
import sqlite3
import shutil

# Access the geoprocessing tools
import arcgisscripting

root = "\\\\server\drive$\\arcgisserver\\arcgiscache\\inspections\\Layers\\_alllayers"

web_path = "\\\\server\\drive$\\inetpub\\wwwroot\\download\\"

print "Started Cache Regeneration - " + str(datetime.datetime.now())


gp = arcgisscripting.create()

# Set up all of the variables for the update tool
server_name = "server"
object_name = "inspections"
data_frame = "Layers"
layers = ""
constraining_extent = ""
scales = "1000;2000;4000;8000;16000;32000;64000;128000;256000"
update_mode = "Recreate All Tiles"
thread_count = "7"
antialiasing = "NONE"

# Run the Update Map Server Cache tool
try:
&amp;nbsp;&amp;nbsp;&amp;nbsp; #print 'Starting Cache Update'
&amp;nbsp;&amp;nbsp;&amp;nbsp; gp.UpdateMapServerCache(server_name, object_name, data_frame, layers, constraining_extent, scales, update_mode, thread_count, antialiasing)
&amp;nbsp;&amp;nbsp;&amp;nbsp; #print 'Finished Cache Update'

# Get the error messages if the tool fails
except:
&amp;nbsp;&amp;nbsp;&amp;nbsp; gp.AddMessage(gp.GetMessages(2))
&amp;nbsp;&amp;nbsp;&amp;nbsp; print gp.GetMessages(2)

print "Completed Cache Regeneration - " + str(datetime.datetime.now())

levels = os.listdir(root)

files_deleted = 0

for level in levels:
&amp;nbsp;&amp;nbsp;&amp;nbsp; rows = os.listdir(root + "\\" + level)

&amp;nbsp;&amp;nbsp;&amp;nbsp; for row in rows:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; images = os.listdir(root + "\\" + level + "\\" + row)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for image in images:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; image_path = root + "\\" + level + "\\" + row + "\\" + image
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; image_stats = os.stat(image_path)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print image + " - " + str(image_stats.st_size) + " bytes"

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if image_stats.st_size &amp;lt;= 1146: #638
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; os.remove(image_path)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; files_deleted += 1

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (files_deleted % 1000) == 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print "deleted " + str(files_deleted)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
print "deleted " + str(files_deleted) + " files, " + str((files_deleted * 1146.0) / 1048576) + " MB"

print "Completed Empty File Pruning - " + str(datetime.datetime.now())

connection = sqlite3.connect("tilestore.sqlite")

cursor = connection.cursor()

cursor.execute("DROP TABLE IF EXISTS \"tiles\"")
connection.commit()
cursor.execute("CREATE TABLE \"tiles\" (\"level\" INTEGER NOT NULL , \"row\" INTEGER NOT NULL , \"column\" INTEGER NOT NULL , \"image\" BLOB, PRIMARY KEY (\"level\", \"row\", \"column\"))")
connection.commit();

levels = os.listdir(root)

for level in levels:
&amp;nbsp;&amp;nbsp;&amp;nbsp; level_number = int(level[1:], 16)
&amp;nbsp;&amp;nbsp;&amp;nbsp; rows = os.listdir(root + "\\" + level)
&amp;nbsp;&amp;nbsp;&amp;nbsp; #print("level - " + level)

&amp;nbsp;&amp;nbsp;&amp;nbsp; for row in rows:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; row_number = int(row[1:], 16)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print row_number
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; images = os.listdir(root + "\\" + level + "\\" + row)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for image in images:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; column_number = int(image[1:-4], 16)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print "\t" + str(column_number) + " - " + image
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; image_path = root + "\\" + level + "\\" + row + "\\" + image&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; image_file = open(image_path, "rb")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binary = sqlite3.Binary(image_file.read())&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cursor.execute("INSERT INTO tiles (level, row, [column], image) VALUES (?, ?, ?, ?)", (level_number, row_number, column_number, binary))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 

connection.commit()
cursor.close()
print "Completed Building Tile Cache - " + str(datetime.datetime.now())

print "Starting File Transfer - " + str(datetime.datetime.now())
shutil.copy("tilestore.sqlite", web_path + "tilestore.sqlite.zip")
print "Completed File Transfer - " + str(datetime.datetime.now())
&lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sun, 12 Dec 2021 01:57:19 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605288#M4180</guid>
      <dc:creator>JozefKaslikowski</dc:creator>
      <dc:date>2021-12-12T01:57:19Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605289#M4181</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;SPAN&gt;Hi,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;I'm new to Android. I rewrote your class a little, because I need to use tile files directly.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;Though I can't get it to work. When debugging program inserts to "public OfflineDbTiledLayer()" function. It doesn't insert to "protected byte[] getTile()". Should it?&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;Is it possible you could send some sample project. I would immensely appreciate.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Regards,&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;Markus&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 30 Mar 2012 08:32:52 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605289#M4181</guid>
      <dc:creator>MarkusUntera</dc:creator>
      <dc:date>2012-03-30T08:32:52Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605290#M4182</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE class="jive-quote"&gt;Hi,&lt;BR /&gt;&lt;BR /&gt;I'm new to Android. I rewrote your class a little, because I need to use tile files directly.&lt;BR /&gt;Though I can't get it to work. When debugging program inserts to "public OfflineDbTiledLayer()" function. It doesn't insert to "protected byte[] getTile()". Should it?&lt;BR /&gt;Is it possible you could send some sample project. I would immensely appreciate.&lt;BR /&gt;&lt;BR /&gt;Regards,&lt;BR /&gt;&lt;BR /&gt;Markus&lt;/BLOCKQUOTE&gt;&lt;BR /&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;I don't think you can see it break into that code since that is called by the ESRI internal classes.&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 05 Apr 2012 19:29:44 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605290#M4182</guid>
      <dc:creator>JozefKaslikowski</dc:creator>
      <dc:date>2012-04-05T19:29:44Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605291#M4183</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;SPAN&gt;Is the script actually importing the Compact Cache Bundle Files into an SQLite DB or is it extracting the images (essentially the exploded format) in the bundle and putting those files in the DB.&amp;nbsp; That is, would I need to create the cache in exploded format in order to import the files with your script. Can you provide some timing info?&amp;nbsp; How long does it take to import for a particular size cache?&amp;nbsp; Is viewing the tiles as fast and smooth as it is with the ArcGISLocalTiledLayer class?&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 12 Apr 2012 12:49:47 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605291#M4183</guid>
      <dc:creator>LukeCatania</dc:creator>
      <dc:date>2012-04-12T12:49:47Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605292#M4184</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE class="jive-quote"&gt;Is the script actually importing the Compact Cache Bundle Files into an SQLite DB or is it extracting the images (essentially the exploded format) in the bundle and putting those files in the DB.&amp;nbsp; That is, would I need to create the cache in exploded format in order to import the files with your script. Can you provide some timing info?&amp;nbsp; How long does it take to import for a particular size cache?&amp;nbsp; Is viewing the tiles as fast and smooth as it is with the ArcGISLocalTiledLayer class?&lt;/BLOCKQUOTE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;It uses an exploded cache since there wouldn't be any benefit of creating the compact cache only to rip it back apart. It takes a few minutes, probably less than 20 to build the entire sqlite db. I have noticed no difference at all in speed versus a local tiled layer.&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 20 Apr 2012 12:20:44 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605292#M4184</guid>
      <dc:creator>JozefKaslikowski</dc:creator>
      <dc:date>2012-04-20T12:20:44Z</dc:date>
    </item>
    <item>
      <title>Re: Offline database backed tile layer</title>
      <link>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605293#M4185</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;BLOCKQUOTE class="jive-quote"&gt;It uses an exploded cache since there wouldn't be any benefit of creating the compact cache only to rip it back apart. It takes a few minutes, probably less than 20 to build the entire sqlite db. I have noticed no difference at all in speed versus a local tiled layer.&lt;/BLOCKQUOTE&gt;&lt;BR /&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;Have you updated the code to the latest release 1.1?&amp;nbsp; I get an error that cannot resolve com.esri.core.internal.c.l&lt;/SPAN&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 09 May 2012 14:30:36 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-runtime-sdk-for-android-questions/offline-database-backed-tile-layer/m-p/605293#M4185</guid>
      <dc:creator>LukeCatania</dc:creator>
      <dc:date>2012-05-09T14:30:36Z</dc:date>
    </item>
  </channel>
</rss>

