Android SQLite ErrorCopyingDataBase Error












0















I'm need help. I have an existing database and I want to copy that from assets to my device, but I only end up getting this error:



java.lang.Error: ErrorCopyingDataBase
at com.example.maas.databaseapplication.DatabaseHelper.createDataBase(DatabaseHelper.java:66)


Where line 66 is the throw clause in code below which is linked with copyDataBase().



public class DatabaseHelper extends SQLiteAssetHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "";
private static String DB_NAME ="NewDatabase1.db";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public Cursor data1;


public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);// 1? Its database Version
this.mContext = context;
if(android.os.Build.VERSION.SDK_INT >= 17){
DB_PATH = Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/";
}
else
{
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}


}


public void createDataBase() throws IOException
{
//If the database does not exist, copy it from the assets.

boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}

//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{

File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}

//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}



//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}

@Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}


I have the



    <uses-permission android:name="androidx.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="androidx.permission.READ_EXTERNAL_STORAGE" />


permissions in my manifest. Can someone please help me? I have tried different database-adapters, but none seem to be working.
I have applied the methods presented in Android : Error Copying database (Sqliite) From Asset Folder . It did NOT solve my problem, if it solved my problem I would not have made a new thread.










share|improve this question

























  • Possible duplicate of Android : Error Copying database (Sqliite) From Asset Folder

    – Lekr0
    Nov 21 '18 at 15:11











  • It is not a duplicate since the presented soulutions in that topic already is in my code. Please see my first post.

    – Ulrich_Peters
    Nov 21 '18 at 15:20
















0















I'm need help. I have an existing database and I want to copy that from assets to my device, but I only end up getting this error:



java.lang.Error: ErrorCopyingDataBase
at com.example.maas.databaseapplication.DatabaseHelper.createDataBase(DatabaseHelper.java:66)


Where line 66 is the throw clause in code below which is linked with copyDataBase().



public class DatabaseHelper extends SQLiteAssetHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "";
private static String DB_NAME ="NewDatabase1.db";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public Cursor data1;


public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);// 1? Its database Version
this.mContext = context;
if(android.os.Build.VERSION.SDK_INT >= 17){
DB_PATH = Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/";
}
else
{
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}


}


public void createDataBase() throws IOException
{
//If the database does not exist, copy it from the assets.

boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}

//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{

File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}

//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}



//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}

@Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}


I have the



    <uses-permission android:name="androidx.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="androidx.permission.READ_EXTERNAL_STORAGE" />


permissions in my manifest. Can someone please help me? I have tried different database-adapters, but none seem to be working.
I have applied the methods presented in Android : Error Copying database (Sqliite) From Asset Folder . It did NOT solve my problem, if it solved my problem I would not have made a new thread.










share|improve this question

























  • Possible duplicate of Android : Error Copying database (Sqliite) From Asset Folder

    – Lekr0
    Nov 21 '18 at 15:11











  • It is not a duplicate since the presented soulutions in that topic already is in my code. Please see my first post.

    – Ulrich_Peters
    Nov 21 '18 at 15:20














0












0








0








I'm need help. I have an existing database and I want to copy that from assets to my device, but I only end up getting this error:



java.lang.Error: ErrorCopyingDataBase
at com.example.maas.databaseapplication.DatabaseHelper.createDataBase(DatabaseHelper.java:66)


Where line 66 is the throw clause in code below which is linked with copyDataBase().



public class DatabaseHelper extends SQLiteAssetHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "";
private static String DB_NAME ="NewDatabase1.db";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public Cursor data1;


public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);// 1? Its database Version
this.mContext = context;
if(android.os.Build.VERSION.SDK_INT >= 17){
DB_PATH = Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/";
}
else
{
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}


}


public void createDataBase() throws IOException
{
//If the database does not exist, copy it from the assets.

boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}

//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{

File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}

//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}



//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}

@Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}


I have the



    <uses-permission android:name="androidx.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="androidx.permission.READ_EXTERNAL_STORAGE" />


permissions in my manifest. Can someone please help me? I have tried different database-adapters, but none seem to be working.
I have applied the methods presented in Android : Error Copying database (Sqliite) From Asset Folder . It did NOT solve my problem, if it solved my problem I would not have made a new thread.










share|improve this question
















I'm need help. I have an existing database and I want to copy that from assets to my device, but I only end up getting this error:



java.lang.Error: ErrorCopyingDataBase
at com.example.maas.databaseapplication.DatabaseHelper.createDataBase(DatabaseHelper.java:66)


Where line 66 is the throw clause in code below which is linked with copyDataBase().



public class DatabaseHelper extends SQLiteAssetHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "";
private static String DB_NAME ="NewDatabase1.db";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public Cursor data1;


public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);// 1? Its database Version
this.mContext = context;
if(android.os.Build.VERSION.SDK_INT >= 17){
DB_PATH = Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/";
}
else
{
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}


}


public void createDataBase() throws IOException
{
//If the database does not exist, copy it from the assets.

boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}

//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{

File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}

//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}



//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}

@Override
public synchronized void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}


I have the



    <uses-permission android:name="androidx.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="androidx.permission.READ_EXTERNAL_STORAGE" />


permissions in my manifest. Can someone please help me? I have tried different database-adapters, but none seem to be working.
I have applied the methods presented in Android : Error Copying database (Sqliite) From Asset Folder . It did NOT solve my problem, if it solved my problem I would not have made a new thread.







java android database sqlite






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 15:25







Ulrich_Peters

















asked Nov 21 '18 at 14:57









Ulrich_PetersUlrich_Peters

52




52













  • Possible duplicate of Android : Error Copying database (Sqliite) From Asset Folder

    – Lekr0
    Nov 21 '18 at 15:11











  • It is not a duplicate since the presented soulutions in that topic already is in my code. Please see my first post.

    – Ulrich_Peters
    Nov 21 '18 at 15:20



















  • Possible duplicate of Android : Error Copying database (Sqliite) From Asset Folder

    – Lekr0
    Nov 21 '18 at 15:11











  • It is not a duplicate since the presented soulutions in that topic already is in my code. Please see my first post.

    – Ulrich_Peters
    Nov 21 '18 at 15:20

















Possible duplicate of Android : Error Copying database (Sqliite) From Asset Folder

– Lekr0
Nov 21 '18 at 15:11





Possible duplicate of Android : Error Copying database (Sqliite) From Asset Folder

– Lekr0
Nov 21 '18 at 15:11













It is not a duplicate since the presented soulutions in that topic already is in my code. Please see my first post.

– Ulrich_Peters
Nov 21 '18 at 15:20





It is not a duplicate since the presented soulutions in that topic already is in my code. Please see my first post.

– Ulrich_Peters
Nov 21 '18 at 15:20












2 Answers
2






active

oldest

votes


















0














The problem with the code you have is that numerous exceptions are caught by using throws IOException and then you just issue a generic exception.



Whilst there could be a number of underlying causes.



It could be that asset itself doesn't exist where it's expected (in the assets folder (e.g. not in the databases directory (SQLiteAssetHelper uses this directory))).



It could be that the databases folder, within the package doesn't exist (use mkdirs on the DB_PATH). e.g. have something like :-



private boolean checkDatabase {
File db = new File(mContext.getDatabasePath(DB_NAME).getPath());
if(db.exists()) return true;
File dir = new File(db.getParent());
if (!dir.exists()) {
dir.mkdirs();
}
return false;
}



  • Note the use of the Context's getDatabasePath


The following is code that is very long but provides very comprehensive logging (it also caters for multiple databases (up to 10 by default) and is also caters for directories in the assets folder).



/**
* Database Helper that includes ability to open database from assets
* if the database doesn't exist.
* (i.e. a pre-defined database)
*
*/

public class OpenAssetDBHelper extends SQLiteOpenHelper {

private static final String LOGTAG = "OADB-HLPR";
public static final int MAXIMUM_HELPERS = 10;
private String mDBPath, mAssetPath;
private static OpenAssetDBHelper mInstance = new OpenAssetDBHelper[MAXIMUM_HELPERS];
private SQLiteDatabase mDB;

/**
* OpenAssetDBHelper Class that will copy a predefined database
* from the assets folder and then open it is the database;
*
* The copy will only be done if the database does not exist.
*
* Note this code is intended to be used for development and/or
* experimentation, hence the extensive logging.
*/

/**
* get an OpenAssetDBHelper instance as a singleton;
* Note! caters for up to 10 OpenAssetDBHelpers for up to 10 databases
* as specified by the helper_index
*
* @param helper_index Index to this instance/database
* (0-MAXIMUM_HELPERS less 1)
* @param context Context for the database
* @param database Database name (i.e. file name)
* @param dbversion Database version (user_version)
* @param assetfile Name of the asset file to be copied to the database
* @param asset_sub_directories String Array of the sub-directories where
* the asset file is located;
* MUST be in order
* @return The resultant OpenAssetDBHelper
*/
public static synchronized OpenAssetDBHelper getInstance(
int helper_index,
Context context,
String database,
int dbversion,
String assetfile,
String asset_sub_directories) {
// Checck that helper_index is within bounds
if (helper_index > (MAXIMUM_HELPERS -1)) {
throw new RuntimeException(
"Helper Index greater than " +
MAXIMUM_HELPERS
);
}
if (helper_index < 0) {
throw new RuntimeException(
"Helper Index cannot be negative, must be 0-" +
MAXIMUM_HELPERS
);
}
// Create the respective OpenAssetDBHelper instance
if(mInstance[helper_index] == null) {
mInstance[helper_index] = new OpenAssetDBHelper(context,
database,
dbversion,
assetfile,
asset_sub_directories);
}
return mInstance[helper_index];
}

/**
* Construct an OpenAssetDBHelper instance;
* Note! can only be called within class
*
* @param context the context to be used
* @param database the database name (equates to filename)
* @param dbversion the databaae version (user_version)
* @param assetfile The name of the asset file i.e. the pre-defined db
* @param directories The hierarchy of directories within the assets folder
* where the asset file is located
* (null or zero elements = in the assets folder)
*/
private OpenAssetDBHelper(Context context,
String database,
int dbversion,
String assetfile,
String directories) {
super(context, database, null, dbversion);
Log.d(LOGTAG,"OpenAssetDBHelper being constructed.");

mDBPath = context.getDatabasePath(database).getPath();
if (assetfile == null || assetfile.length() < 1) {
assetfile = database;
}
mAssetPath = buildAssetPath(directories,assetfile);

if (!ifDatabaseExists(mDBPath)) {
Log.d(LOGTAG,"Database " + database + " not found at " + mDBPath + " so attempting to copy from assets.");
if (copyDatabaseFromAssets(context,mDBPath, database, mAssetPath)) {
Log.d(LOGTAG, "Successfully Copied Database from Assets.");
} else {
throw new RuntimeException("No Database Available.");
}
}
// Force Database open and store it
this.mDB = this.getWritableDatabase();
logDatabaseTableInformation(mDB);
Log.d(LOGTAG,"OpenAssetDBHelper constructed.");
}


/**
* onCreate - This is where you would create tables;
* Typically this is where you would alter the structure of the database;
* Note that this is called once for the lifetime of the database.
* @param db The SQLitedatabase
*/
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
// As Database is copied from assets nothing to do in onCreate!
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
// Nothing to do as it's early days in the Database's lifetime.
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
}

/**
* Check to see if the Database exists,
* if it doesn't exists then check to see if
* the database directory exists,
* if the directory(ies) does(do) not exist then make the directory(ies);
*
*
* @param dbpath The path to the database
* @return true if the database exists, else false
*/
private boolean ifDatabaseExists(String dbpath) {
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
File db = new File(dbpath);
if(db.exists()) return true;
File dir = new File(db.getParent());
if (!dir.exists()) {
dir.mkdirs();
}
return false;
}

/**
* Copy the Database from the assets folder
* @param context
* @param dbpath
* @return
*/
private boolean copyDatabaseFromAssets(Context context,String dbpath, String dbname, String asset) {
String thisclass = new Object(){}.getClass().getEnclosingMethod().getName();
Log.d(LOGTAG,thisclass + " initiated");
InputStream assetsdb;
OutputStream database;
File db = new File(dbpath);
int filesize;
// Get the asset file
try {
Log.d(LOGTAG,thisclass + " attempting to find asset " + asset);
assetsdb = context.getAssets().open(asset);
filesize = assetsdb.available();
Log.d(LOGTAG,thisclass + " asset " + asset +
" located successfully with a size of " +
Integer.toString(filesize)
);
} catch (IOException e) {
Log.d(LOGTAG,thisclass + " Did not locate asset " + asset);
e.printStackTrace();
return false;
}

// Read the first 16 bytes from the asset file
byte dbcheck = new byte[16];
try {
assetsdb.read(dbcheck,0,16);
} catch (IOException e) {
Log.d(LOGTAG, thisclass + " failed trying to read 16 bytes to check for a valid database. ");
e.printStackTrace();
return false;
}

// Check that the asset file is an SQLite database
String chkdb = new String(dbcheck);
if(!chkdb.equals("SQLite format 3u0000")) {
Log.d(LOGTAG,thisclass + " asset " +
asset +
" is not a valid SQLite Database File (found " +
chkdb +
" at bytes 1-16 instead of SQLite format 3)");
try {
assetsdb.close();
} catch (IOException e) {
// Not worth doing anything
}
return false;
}
// Close the asset file
try {
assetsdb.close();
} catch (IOException e) {
Log.d(LOGTAG,thisclass +
" failed to close assets file after checking for a valid database."
);
return false;
}
// Re-open the asset file
try {
assetsdb = context.getAssets().open(asset);
filesize = assetsdb.available();
} catch (IOException e) {
Log.d(LOGTAG, thisclass +
" failed trying to re-open asset " +
asset +
" after checking for a valid database."
);
e.printStackTrace();
return false;
}

// Read the entire asset file into a buffer
Log.d(LOGTAG, thisclass +
" copying asset database " +
dbname +
" into buffer of size " +
filesize
);
byte buffer = new byte[filesize];
// Close the asset file
try {
assetsdb.read(buffer);
Log.d(LOGTAG,thisclass +
" closing asset database " + dbname
);
assetsdb.close();
} catch (IOException e) {
Log.d(LOGTAG, thisclass +
" failed while copying asset database " +
dbname +
" (or closing asset database)."
);
e.printStackTrace();
return false;
}
// Open the new database file
try {
Log.d(LOGTAG,thisclass + " attempting to open new database file " + dbpath);
database = new FileOutputStream(dbpath);
} catch (IOException e) {
Log.d(LOGTAG, thisclass + " failed to open new database file.");
e.printStackTrace();
return false;
}
// Write the new database file
try {
Log.d(LOGTAG, thisclass + " writing new database file " + dbpath);
database.write(buffer);
} catch (IOException e) {
Log.d(LOGTAG, thisclass + " failed while writing new database file " + dbpath);
e.printStackTrace();
return false;
}
// Flush the new database file
try {
Log.d(LOGTAG, thisclass + " flushing new database file " + dbpath);
database.flush();
} catch (IOException e) {
Log.d(LOGTAG, thisclass + " failed while flushing new database file " + dbpath);
e.printStackTrace();
return false;
}
// Close the new database file
try {
Log.d(LOGTAG, thisclass + " closing new database file " + dbpath);
database.close();
} catch (IOException e) {
Log.d(LOGTAG, thisclass + " failed while closing new database file " + dbpath);
e.printStackTrace();
return false;
}
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
return true;
}

/**
* Log Database table Information
*/
private void logDatabaseTableInformation(SQLiteDatabase db) {
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
String mastertable = "sqlite_master";
String typecolumn = "type";
String namecolumn = "name";
String sqlcolumn = "sql";
String args = new String{"table","android_metadata"};
Cursor csr = db.query(mastertable,
null,
typecolumn + "=? AND " + namecolumn + "!=?",
args,
null,null,null
);
while (csr.moveToNext()) {
Log.d(LOGTAG,"Database contains Table " +
csr.getString(csr.getColumnIndex(namecolumn)) +
" created by SQL " +
csr.getString(csr.getColumnIndex(sqlcolumn))
);
logTableInformation(db, csr.getString(csr.getColumnIndex(namecolumn)));
}
csr.close();
Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
}

/**
* Write Table information, Table name, Column Count,
* Row Count and Column Names to the Log
* @param table Name of the table to be reported on
*/
private void logTableInformation(SQLiteDatabase db, String table) {
Cursor csr = db.query(table,
null,
null,
null,
null,
null,
null
);
Log.d(LOGTAG,"Table is " +
table +
" Column Count = " +
Integer.toString(csr.getColumnCount()) +
" Row Count = " +
Long.toString(DatabaseUtils.queryNumEntries(mDB,table))
);
StringBuilder columns_as_string = new StringBuilder();
for (String s: csr.getColumnNames()) {
columns_as_string.append(s).append(" ");
}
Log.d(LOGTAG, "tColumns are :- " + columns_as_string);
csr.close();
}

/**
* Build the sub-path to the asset, according to the directories specified
*
* @param directories directories underneath the assets folder where
* the asset files is located, null or empty
* array if file is located directly in the
* assets folder;
* directories must be specified in the order
* in which they appear in the path.
* @param filename The filename of the asset
* @return The fill sub-path to the asset
*/
private String buildAssetPath(String directories, String filename) {
StringBuilder sb = new StringBuilder();
final String SEPERATOR = "/";
if (directories != null && directories.length > 0) {
for (String s: directories) {
sb.append(s);
if (!s.substring(s.length()-1,s.length()).equals(SEPERATOR)) {
sb.append(SEPERATOR);
}
}
sb.append(filename);
return sb.toString();
} else {
return filename;
}
}
}


Example Usage



public class MainActivity extends AppCompatActivity {

public static final int DBVERSION = 1;
public static final String DBNAME1 = "openassetdb.db";
public static final int DB1_INDEX = 0;
public static final String DBNAME2 = "myshopping";
public static final int DB2_INDEX = 1;

OpenAssetDBHelper mOADBHlpr;
OpenAssetDBHelper mShoppingHelper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Example 1 - Database file located in the assets folder and
// database name same as file name
mOADBHlpr = OpenAssetDBHelper.getInstance(DB1_INDEX,
this,
DBNAME1,
DBVERSION,
DBNAME1,
null
);
// Example 2 - Database file in databases directory of the assets folder
// database name different to the asset filename
mShoppingHelper = OpenAssetDBHelper.getInstance(DB2_INDEX,
this,
DBNAME2,
DBVERSION,
"shopper",
new String{"databases"}
);
}
}


Result (when no databases exist) :-



2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: Database openassetdb.db not found at /data/user/0/mjt.openassetdb/databases/openassetdb.db so attempting to copy from assets.
2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset openassetdb.db
2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset openassetdb.db located successfully with a size of 12288
2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database openassetdb.db into buffer of size 12288
2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database openassetdb.db
2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate initiated.
2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate completed.
2018-11-22 07:06:01.425 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table testtable created by SQL CREATE TABLE `testtable` (
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT,
`timestamp` INTEGER
)
2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Table is testtable Column Count = 3 Row Count = 2
2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Columns are :- _id name timestamp
2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table sqlite_sequence created by SQL CREATE TABLE sqlite_sequence(name,seq)
2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Table is sqlite_sequence Column Count = 2 Row Count = 1
2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Columns are :- name seq
2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.


(2nd)



2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.
2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: Database myshopping not found at /data/user/0/mjt.openassetdb/databases/myshopping so attempting to copy from assets.
2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/shopper
2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset databases/shopper located successfully with a size of 262144
2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database myshopping into buffer of size 262144
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database myshopping
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/myshopping
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/myshopping
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/myshopping
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/myshopping
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate initiated.
2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate completed.
2018-11-22 07:06:01.443 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
2018-11-22 07:06:01.444 1993-1993/? D/OADB-HLPR: Database contains Table shops created by SQL CREATE TABLE shops (_id INTEGER PRIMARY KEY , shopname TEXT , shoporder INTEGER DEFAULT 100 , shopstreet TEXT , shopcity TEXT , shopstate TEXT , shopphone TEXT , shopnotes TEXT )
2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Table is shops Column Count = 8 Row Count = 4
2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Columns are :- _id shopname shoporder shopstreet shopcity shopstate shopphone shopnotes
2018-11-22 07:06:01.446 1993-1993/? D/OADB-HLPR: Database contains Table aisles created by SQL CREATE TABLE aisles (_id INTEGER PRIMARY KEY , aislename TEXT , aisleorder INTEGER DEFAULT 100 , aisleshopref INTEGER )
2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Table is aisles Column Count = 4 Row Count = 20
2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Columns are :- _id aislename aisleorder aisleshopref
2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Database contains Table products created by SQL CREATE TABLE products (_id INTEGER PRIMARY KEY , productname TEXT , productorder INTEGER DEFAULT 100 , productaisleref INTEGER , productuses INTEGER DEFAULT 0 , productnotes TEXT )
2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Table is products Column Count = 6 Row Count = 10
2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Columns are :- _id productname productorder productaisleref productuses productnotes
2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Database contains Table productusage created by SQL CREATE TABLE productusage (productailseref INTEGER , productproductref INTEGER , productcost REAL DEFAULT 1.00 , productbuycount INTEGER DEFAULT 0 , productfirstbuydate INTEGER DEFAULT 0 , productlatestbuydate INTEGER DEFAULT 0 , mincost REAL , PRIMARY KEY (productailseref, productproductref))
2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Table is productusage Column Count = 7 Row Count = 20
2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Columns are :- productailseref productproductref productcost productbuycount productfirstbuydate productlatestbuydate mincost
2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Database contains Table rules created by SQL CREATE TABLE rules (ruleid INTEGER PRIMARY KEY , rulename TEXT , ruletype INTEGER , rulepromptflag INTEGER , ruleperiod INTEGER , rulemultiplier INTEGER , ruleactiveon INTEGER , ruleproductref INTEGER , ruleaisleref INTEGER )
2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Table is rules Column Count = 9 Row Count = 0
2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Columns are :- ruleid rulename ruletype rulepromptflag ruleperiod rulemultiplier ruleactiveon ruleproductref ruleaisleref
2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Database contains Table shoplist created by SQL CREATE TABLE "shoplist" ("_id" INTEGER PRIMARY KEY NOT NULL , "productref" INTEGER, "dateadded" INTEGER, "numbertoget" INTEGER, "done" BOOL, "dategot" INTEGER, "cost" REAL, "productusageref" INTEGER, "aisleref" INTEGER)
2018-11-22 07:06:01.453 1993-1993/? D/OADB-HLPR: Table is shoplist Column Count = 9 Row Count = 4
2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: Columns are :- _id productref dateadded numbertoget done dategot cost productusageref aisleref
2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.
2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.





share|improve this answer
























  • I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

    – Ulrich_Peters
    Nov 26 '18 at 15:54











  • Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

    – Ulrich_Peters
    Nov 29 '18 at 5:58











  • @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

    – MikeT
    Nov 29 '18 at 8:22











  • @Ulrich_Peters also note that file and directory names are case dependant.

    – MikeT
    Nov 29 '18 at 8:59



















0














Additional - Asset not found example



using



    mShopper = OpenAssetDBHelper.getInstance(DB3_INDEX,
this,
DBNAME3,
DBVERSION,
"Shopper.lite", // not the asset name
new String{"databases"}
);


Where
- DBNAME3 resolves to rumplestiltskin (the final database name)
- DBVERSION is 1
- and the asset filename is Shopper.lite which should be in the databases folder (doesn't exist though).



The resultant log is :-



11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper constructed.
11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: ifDatabaseExists initiated.
11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: Database rumplestilskin not found at /data/data/mjt.openassetdb/databases/rumplestilskin so attempting to copy from assets.
11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets initiated
11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite
11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite
11-29 07:46:22.603 4816-4816/? W/System.err: java.io.FileNotFoundException: databases/Shopper.lite
11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.openAsset(Native Method)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:315)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:289)
11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.copyDatabaseFromAssets(OpenAssetDBHelper.java:187)
11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:117)
11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Activity.performCreate(Activity.java:5008)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Looper.loop(Looper.java:137)
11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:4745)
11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-29 07:46:22.603 4816-4816/? W/System.err: at dalvik.system.NativeStart.main(Native Method)
11-29 07:46:22.603 4816-4816/? D/AndroidRuntime: Shutting down VM
11-29 07:46:22.603 4816-4816/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6265288)
11-29 07:46:22.603 4816-4816/? E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: No Database Available.
at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:120)
at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
at android.app.ActivityThread.access$600(ActivityThread.java:130) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:137) 
at android.app.ActivityThread.main(ActivityThread.java:4745) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
at dalvik.system.NativeStart.main(Native Method) 


The first pertinent line is D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite



This provides the path within the assets folder where the asset is expected to be found (in this example the filename is expected to be Shopper.lite in the databases subfolder/directory)



The line D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite reports that the asset file was not found.



This is followed by the trapped exception (not the actual crash)



Processing continues until the final crash as reported by :-



E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414789%2fandroid-sqlite-errorcopyingdatabase-error%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    The problem with the code you have is that numerous exceptions are caught by using throws IOException and then you just issue a generic exception.



    Whilst there could be a number of underlying causes.



    It could be that asset itself doesn't exist where it's expected (in the assets folder (e.g. not in the databases directory (SQLiteAssetHelper uses this directory))).



    It could be that the databases folder, within the package doesn't exist (use mkdirs on the DB_PATH). e.g. have something like :-



    private boolean checkDatabase {
    File db = new File(mContext.getDatabasePath(DB_NAME).getPath());
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }



    • Note the use of the Context's getDatabasePath


    The following is code that is very long but provides very comprehensive logging (it also caters for multiple databases (up to 10 by default) and is also caters for directories in the assets folder).



    /**
    * Database Helper that includes ability to open database from assets
    * if the database doesn't exist.
    * (i.e. a pre-defined database)
    *
    */

    public class OpenAssetDBHelper extends SQLiteOpenHelper {

    private static final String LOGTAG = "OADB-HLPR";
    public static final int MAXIMUM_HELPERS = 10;
    private String mDBPath, mAssetPath;
    private static OpenAssetDBHelper mInstance = new OpenAssetDBHelper[MAXIMUM_HELPERS];
    private SQLiteDatabase mDB;

    /**
    * OpenAssetDBHelper Class that will copy a predefined database
    * from the assets folder and then open it is the database;
    *
    * The copy will only be done if the database does not exist.
    *
    * Note this code is intended to be used for development and/or
    * experimentation, hence the extensive logging.
    */

    /**
    * get an OpenAssetDBHelper instance as a singleton;
    * Note! caters for up to 10 OpenAssetDBHelpers for up to 10 databases
    * as specified by the helper_index
    *
    * @param helper_index Index to this instance/database
    * (0-MAXIMUM_HELPERS less 1)
    * @param context Context for the database
    * @param database Database name (i.e. file name)
    * @param dbversion Database version (user_version)
    * @param assetfile Name of the asset file to be copied to the database
    * @param asset_sub_directories String Array of the sub-directories where
    * the asset file is located;
    * MUST be in order
    * @return The resultant OpenAssetDBHelper
    */
    public static synchronized OpenAssetDBHelper getInstance(
    int helper_index,
    Context context,
    String database,
    int dbversion,
    String assetfile,
    String asset_sub_directories) {
    // Checck that helper_index is within bounds
    if (helper_index > (MAXIMUM_HELPERS -1)) {
    throw new RuntimeException(
    "Helper Index greater than " +
    MAXIMUM_HELPERS
    );
    }
    if (helper_index < 0) {
    throw new RuntimeException(
    "Helper Index cannot be negative, must be 0-" +
    MAXIMUM_HELPERS
    );
    }
    // Create the respective OpenAssetDBHelper instance
    if(mInstance[helper_index] == null) {
    mInstance[helper_index] = new OpenAssetDBHelper(context,
    database,
    dbversion,
    assetfile,
    asset_sub_directories);
    }
    return mInstance[helper_index];
    }

    /**
    * Construct an OpenAssetDBHelper instance;
    * Note! can only be called within class
    *
    * @param context the context to be used
    * @param database the database name (equates to filename)
    * @param dbversion the databaae version (user_version)
    * @param assetfile The name of the asset file i.e. the pre-defined db
    * @param directories The hierarchy of directories within the assets folder
    * where the asset file is located
    * (null or zero elements = in the assets folder)
    */
    private OpenAssetDBHelper(Context context,
    String database,
    int dbversion,
    String assetfile,
    String directories) {
    super(context, database, null, dbversion);
    Log.d(LOGTAG,"OpenAssetDBHelper being constructed.");

    mDBPath = context.getDatabasePath(database).getPath();
    if (assetfile == null || assetfile.length() < 1) {
    assetfile = database;
    }
    mAssetPath = buildAssetPath(directories,assetfile);

    if (!ifDatabaseExists(mDBPath)) {
    Log.d(LOGTAG,"Database " + database + " not found at " + mDBPath + " so attempting to copy from assets.");
    if (copyDatabaseFromAssets(context,mDBPath, database, mAssetPath)) {
    Log.d(LOGTAG, "Successfully Copied Database from Assets.");
    } else {
    throw new RuntimeException("No Database Available.");
    }
    }
    // Force Database open and store it
    this.mDB = this.getWritableDatabase();
    logDatabaseTableInformation(mDB);
    Log.d(LOGTAG,"OpenAssetDBHelper constructed.");
    }


    /**
    * onCreate - This is where you would create tables;
    * Typically this is where you would alter the structure of the database;
    * Note that this is called once for the lifetime of the database.
    * @param db The SQLitedatabase
    */
    @Override
    public void onCreate(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // As Database is copied from assets nothing to do in onCreate!
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // Nothing to do as it's early days in the Database's lifetime.
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Check to see if the Database exists,
    * if it doesn't exists then check to see if
    * the database directory exists,
    * if the directory(ies) does(do) not exist then make the directory(ies);
    *
    *
    * @param dbpath The path to the database
    * @return true if the database exists, else false
    */
    private boolean ifDatabaseExists(String dbpath) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    File db = new File(dbpath);
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }

    /**
    * Copy the Database from the assets folder
    * @param context
    * @param dbpath
    * @return
    */
    private boolean copyDatabaseFromAssets(Context context,String dbpath, String dbname, String asset) {
    String thisclass = new Object(){}.getClass().getEnclosingMethod().getName();
    Log.d(LOGTAG,thisclass + " initiated");
    InputStream assetsdb;
    OutputStream database;
    File db = new File(dbpath);
    int filesize;
    // Get the asset file
    try {
    Log.d(LOGTAG,thisclass + " attempting to find asset " + asset);
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    Log.d(LOGTAG,thisclass + " asset " + asset +
    " located successfully with a size of " +
    Integer.toString(filesize)
    );
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass + " Did not locate asset " + asset);
    e.printStackTrace();
    return false;
    }

    // Read the first 16 bytes from the asset file
    byte dbcheck = new byte[16];
    try {
    assetsdb.read(dbcheck,0,16);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed trying to read 16 bytes to check for a valid database. ");
    e.printStackTrace();
    return false;
    }

    // Check that the asset file is an SQLite database
    String chkdb = new String(dbcheck);
    if(!chkdb.equals("SQLite format 3u0000")) {
    Log.d(LOGTAG,thisclass + " asset " +
    asset +
    " is not a valid SQLite Database File (found " +
    chkdb +
    " at bytes 1-16 instead of SQLite format 3)");
    try {
    assetsdb.close();
    } catch (IOException e) {
    // Not worth doing anything
    }
    return false;
    }
    // Close the asset file
    try {
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass +
    " failed to close assets file after checking for a valid database."
    );
    return false;
    }
    // Re-open the asset file
    try {
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed trying to re-open asset " +
    asset +
    " after checking for a valid database."
    );
    e.printStackTrace();
    return false;
    }

    // Read the entire asset file into a buffer
    Log.d(LOGTAG, thisclass +
    " copying asset database " +
    dbname +
    " into buffer of size " +
    filesize
    );
    byte buffer = new byte[filesize];
    // Close the asset file
    try {
    assetsdb.read(buffer);
    Log.d(LOGTAG,thisclass +
    " closing asset database " + dbname
    );
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed while copying asset database " +
    dbname +
    " (or closing asset database)."
    );
    e.printStackTrace();
    return false;
    }
    // Open the new database file
    try {
    Log.d(LOGTAG,thisclass + " attempting to open new database file " + dbpath);
    database = new FileOutputStream(dbpath);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed to open new database file.");
    e.printStackTrace();
    return false;
    }
    // Write the new database file
    try {
    Log.d(LOGTAG, thisclass + " writing new database file " + dbpath);
    database.write(buffer);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while writing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Flush the new database file
    try {
    Log.d(LOGTAG, thisclass + " flushing new database file " + dbpath);
    database.flush();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while flushing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Close the new database file
    try {
    Log.d(LOGTAG, thisclass + " closing new database file " + dbpath);
    database.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while closing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    return true;
    }

    /**
    * Log Database table Information
    */
    private void logDatabaseTableInformation(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    String mastertable = "sqlite_master";
    String typecolumn = "type";
    String namecolumn = "name";
    String sqlcolumn = "sql";
    String args = new String{"table","android_metadata"};
    Cursor csr = db.query(mastertable,
    null,
    typecolumn + "=? AND " + namecolumn + "!=?",
    args,
    null,null,null
    );
    while (csr.moveToNext()) {
    Log.d(LOGTAG,"Database contains Table " +
    csr.getString(csr.getColumnIndex(namecolumn)) +
    " created by SQL " +
    csr.getString(csr.getColumnIndex(sqlcolumn))
    );
    logTableInformation(db, csr.getString(csr.getColumnIndex(namecolumn)));
    }
    csr.close();
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Write Table information, Table name, Column Count,
    * Row Count and Column Names to the Log
    * @param table Name of the table to be reported on
    */
    private void logTableInformation(SQLiteDatabase db, String table) {
    Cursor csr = db.query(table,
    null,
    null,
    null,
    null,
    null,
    null
    );
    Log.d(LOGTAG,"Table is " +
    table +
    " Column Count = " +
    Integer.toString(csr.getColumnCount()) +
    " Row Count = " +
    Long.toString(DatabaseUtils.queryNumEntries(mDB,table))
    );
    StringBuilder columns_as_string = new StringBuilder();
    for (String s: csr.getColumnNames()) {
    columns_as_string.append(s).append(" ");
    }
    Log.d(LOGTAG, "tColumns are :- " + columns_as_string);
    csr.close();
    }

    /**
    * Build the sub-path to the asset, according to the directories specified
    *
    * @param directories directories underneath the assets folder where
    * the asset files is located, null or empty
    * array if file is located directly in the
    * assets folder;
    * directories must be specified in the order
    * in which they appear in the path.
    * @param filename The filename of the asset
    * @return The fill sub-path to the asset
    */
    private String buildAssetPath(String directories, String filename) {
    StringBuilder sb = new StringBuilder();
    final String SEPERATOR = "/";
    if (directories != null && directories.length > 0) {
    for (String s: directories) {
    sb.append(s);
    if (!s.substring(s.length()-1,s.length()).equals(SEPERATOR)) {
    sb.append(SEPERATOR);
    }
    }
    sb.append(filename);
    return sb.toString();
    } else {
    return filename;
    }
    }
    }


    Example Usage



    public class MainActivity extends AppCompatActivity {

    public static final int DBVERSION = 1;
    public static final String DBNAME1 = "openassetdb.db";
    public static final int DB1_INDEX = 0;
    public static final String DBNAME2 = "myshopping";
    public static final int DB2_INDEX = 1;

    OpenAssetDBHelper mOADBHlpr;
    OpenAssetDBHelper mShoppingHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example 1 - Database file located in the assets folder and
    // database name same as file name
    mOADBHlpr = OpenAssetDBHelper.getInstance(DB1_INDEX,
    this,
    DBNAME1,
    DBVERSION,
    DBNAME1,
    null
    );
    // Example 2 - Database file in databases directory of the assets folder
    // database name different to the asset filename
    mShoppingHelper = OpenAssetDBHelper.getInstance(DB2_INDEX,
    this,
    DBNAME2,
    DBVERSION,
    "shopper",
    new String{"databases"}
    );
    }
    }


    Result (when no databases exist) :-



    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: Database openassetdb.db not found at /data/user/0/mjt.openassetdb/databases/openassetdb.db so attempting to copy from assets.
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset openassetdb.db located successfully with a size of 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database openassetdb.db into buffer of size 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.425 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table testtable created by SQL CREATE TABLE `testtable` (
    `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
    `name` TEXT,
    `timestamp` INTEGER
    )
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Table is testtable Column Count = 3 Row Count = 2
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Columns are :- _id name timestamp
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table sqlite_sequence created by SQL CREATE TABLE sqlite_sequence(name,seq)
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Table is sqlite_sequence Column Count = 2 Row Count = 1
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Columns are :- name seq
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.


    (2nd)



    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: Database myshopping not found at /data/user/0/mjt.openassetdb/databases/myshopping so attempting to copy from assets.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/shopper
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset databases/shopper located successfully with a size of 262144
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database myshopping into buffer of size 262144
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.443 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.444 1993-1993/? D/OADB-HLPR: Database contains Table shops created by SQL CREATE TABLE shops (_id INTEGER PRIMARY KEY , shopname TEXT , shoporder INTEGER DEFAULT 100 , shopstreet TEXT , shopcity TEXT , shopstate TEXT , shopphone TEXT , shopnotes TEXT )
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Table is shops Column Count = 8 Row Count = 4
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Columns are :- _id shopname shoporder shopstreet shopcity shopstate shopphone shopnotes
    2018-11-22 07:06:01.446 1993-1993/? D/OADB-HLPR: Database contains Table aisles created by SQL CREATE TABLE aisles (_id INTEGER PRIMARY KEY , aislename TEXT , aisleorder INTEGER DEFAULT 100 , aisleshopref INTEGER )
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Table is aisles Column Count = 4 Row Count = 20
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Columns are :- _id aislename aisleorder aisleshopref
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Database contains Table products created by SQL CREATE TABLE products (_id INTEGER PRIMARY KEY , productname TEXT , productorder INTEGER DEFAULT 100 , productaisleref INTEGER , productuses INTEGER DEFAULT 0 , productnotes TEXT )
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Table is products Column Count = 6 Row Count = 10
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Columns are :- _id productname productorder productaisleref productuses productnotes
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Database contains Table productusage created by SQL CREATE TABLE productusage (productailseref INTEGER , productproductref INTEGER , productcost REAL DEFAULT 1.00 , productbuycount INTEGER DEFAULT 0 , productfirstbuydate INTEGER DEFAULT 0 , productlatestbuydate INTEGER DEFAULT 0 , mincost REAL , PRIMARY KEY (productailseref, productproductref))
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Table is productusage Column Count = 7 Row Count = 20
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Columns are :- productailseref productproductref productcost productbuycount productfirstbuydate productlatestbuydate mincost
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Database contains Table rules created by SQL CREATE TABLE rules (ruleid INTEGER PRIMARY KEY , rulename TEXT , ruletype INTEGER , rulepromptflag INTEGER , ruleperiod INTEGER , rulemultiplier INTEGER , ruleactiveon INTEGER , ruleproductref INTEGER , ruleaisleref INTEGER )
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Table is rules Column Count = 9 Row Count = 0
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Columns are :- ruleid rulename ruletype rulepromptflag ruleperiod rulemultiplier ruleactiveon ruleproductref ruleaisleref
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Database contains Table shoplist created by SQL CREATE TABLE "shoplist" ("_id" INTEGER PRIMARY KEY NOT NULL , "productref" INTEGER, "dateadded" INTEGER, "numbertoget" INTEGER, "done" BOOL, "dategot" INTEGER, "cost" REAL, "productusageref" INTEGER, "aisleref" INTEGER)
    2018-11-22 07:06:01.453 1993-1993/? D/OADB-HLPR: Table is shoplist Column Count = 9 Row Count = 4
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: Columns are :- _id productref dateadded numbertoget done dategot cost productusageref aisleref
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.





    share|improve this answer
























    • I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

      – Ulrich_Peters
      Nov 26 '18 at 15:54











    • Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

      – Ulrich_Peters
      Nov 29 '18 at 5:58











    • @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

      – MikeT
      Nov 29 '18 at 8:22











    • @Ulrich_Peters also note that file and directory names are case dependant.

      – MikeT
      Nov 29 '18 at 8:59
















    0














    The problem with the code you have is that numerous exceptions are caught by using throws IOException and then you just issue a generic exception.



    Whilst there could be a number of underlying causes.



    It could be that asset itself doesn't exist where it's expected (in the assets folder (e.g. not in the databases directory (SQLiteAssetHelper uses this directory))).



    It could be that the databases folder, within the package doesn't exist (use mkdirs on the DB_PATH). e.g. have something like :-



    private boolean checkDatabase {
    File db = new File(mContext.getDatabasePath(DB_NAME).getPath());
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }



    • Note the use of the Context's getDatabasePath


    The following is code that is very long but provides very comprehensive logging (it also caters for multiple databases (up to 10 by default) and is also caters for directories in the assets folder).



    /**
    * Database Helper that includes ability to open database from assets
    * if the database doesn't exist.
    * (i.e. a pre-defined database)
    *
    */

    public class OpenAssetDBHelper extends SQLiteOpenHelper {

    private static final String LOGTAG = "OADB-HLPR";
    public static final int MAXIMUM_HELPERS = 10;
    private String mDBPath, mAssetPath;
    private static OpenAssetDBHelper mInstance = new OpenAssetDBHelper[MAXIMUM_HELPERS];
    private SQLiteDatabase mDB;

    /**
    * OpenAssetDBHelper Class that will copy a predefined database
    * from the assets folder and then open it is the database;
    *
    * The copy will only be done if the database does not exist.
    *
    * Note this code is intended to be used for development and/or
    * experimentation, hence the extensive logging.
    */

    /**
    * get an OpenAssetDBHelper instance as a singleton;
    * Note! caters for up to 10 OpenAssetDBHelpers for up to 10 databases
    * as specified by the helper_index
    *
    * @param helper_index Index to this instance/database
    * (0-MAXIMUM_HELPERS less 1)
    * @param context Context for the database
    * @param database Database name (i.e. file name)
    * @param dbversion Database version (user_version)
    * @param assetfile Name of the asset file to be copied to the database
    * @param asset_sub_directories String Array of the sub-directories where
    * the asset file is located;
    * MUST be in order
    * @return The resultant OpenAssetDBHelper
    */
    public static synchronized OpenAssetDBHelper getInstance(
    int helper_index,
    Context context,
    String database,
    int dbversion,
    String assetfile,
    String asset_sub_directories) {
    // Checck that helper_index is within bounds
    if (helper_index > (MAXIMUM_HELPERS -1)) {
    throw new RuntimeException(
    "Helper Index greater than " +
    MAXIMUM_HELPERS
    );
    }
    if (helper_index < 0) {
    throw new RuntimeException(
    "Helper Index cannot be negative, must be 0-" +
    MAXIMUM_HELPERS
    );
    }
    // Create the respective OpenAssetDBHelper instance
    if(mInstance[helper_index] == null) {
    mInstance[helper_index] = new OpenAssetDBHelper(context,
    database,
    dbversion,
    assetfile,
    asset_sub_directories);
    }
    return mInstance[helper_index];
    }

    /**
    * Construct an OpenAssetDBHelper instance;
    * Note! can only be called within class
    *
    * @param context the context to be used
    * @param database the database name (equates to filename)
    * @param dbversion the databaae version (user_version)
    * @param assetfile The name of the asset file i.e. the pre-defined db
    * @param directories The hierarchy of directories within the assets folder
    * where the asset file is located
    * (null or zero elements = in the assets folder)
    */
    private OpenAssetDBHelper(Context context,
    String database,
    int dbversion,
    String assetfile,
    String directories) {
    super(context, database, null, dbversion);
    Log.d(LOGTAG,"OpenAssetDBHelper being constructed.");

    mDBPath = context.getDatabasePath(database).getPath();
    if (assetfile == null || assetfile.length() < 1) {
    assetfile = database;
    }
    mAssetPath = buildAssetPath(directories,assetfile);

    if (!ifDatabaseExists(mDBPath)) {
    Log.d(LOGTAG,"Database " + database + " not found at " + mDBPath + " so attempting to copy from assets.");
    if (copyDatabaseFromAssets(context,mDBPath, database, mAssetPath)) {
    Log.d(LOGTAG, "Successfully Copied Database from Assets.");
    } else {
    throw new RuntimeException("No Database Available.");
    }
    }
    // Force Database open and store it
    this.mDB = this.getWritableDatabase();
    logDatabaseTableInformation(mDB);
    Log.d(LOGTAG,"OpenAssetDBHelper constructed.");
    }


    /**
    * onCreate - This is where you would create tables;
    * Typically this is where you would alter the structure of the database;
    * Note that this is called once for the lifetime of the database.
    * @param db The SQLitedatabase
    */
    @Override
    public void onCreate(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // As Database is copied from assets nothing to do in onCreate!
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // Nothing to do as it's early days in the Database's lifetime.
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Check to see if the Database exists,
    * if it doesn't exists then check to see if
    * the database directory exists,
    * if the directory(ies) does(do) not exist then make the directory(ies);
    *
    *
    * @param dbpath The path to the database
    * @return true if the database exists, else false
    */
    private boolean ifDatabaseExists(String dbpath) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    File db = new File(dbpath);
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }

    /**
    * Copy the Database from the assets folder
    * @param context
    * @param dbpath
    * @return
    */
    private boolean copyDatabaseFromAssets(Context context,String dbpath, String dbname, String asset) {
    String thisclass = new Object(){}.getClass().getEnclosingMethod().getName();
    Log.d(LOGTAG,thisclass + " initiated");
    InputStream assetsdb;
    OutputStream database;
    File db = new File(dbpath);
    int filesize;
    // Get the asset file
    try {
    Log.d(LOGTAG,thisclass + " attempting to find asset " + asset);
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    Log.d(LOGTAG,thisclass + " asset " + asset +
    " located successfully with a size of " +
    Integer.toString(filesize)
    );
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass + " Did not locate asset " + asset);
    e.printStackTrace();
    return false;
    }

    // Read the first 16 bytes from the asset file
    byte dbcheck = new byte[16];
    try {
    assetsdb.read(dbcheck,0,16);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed trying to read 16 bytes to check for a valid database. ");
    e.printStackTrace();
    return false;
    }

    // Check that the asset file is an SQLite database
    String chkdb = new String(dbcheck);
    if(!chkdb.equals("SQLite format 3u0000")) {
    Log.d(LOGTAG,thisclass + " asset " +
    asset +
    " is not a valid SQLite Database File (found " +
    chkdb +
    " at bytes 1-16 instead of SQLite format 3)");
    try {
    assetsdb.close();
    } catch (IOException e) {
    // Not worth doing anything
    }
    return false;
    }
    // Close the asset file
    try {
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass +
    " failed to close assets file after checking for a valid database."
    );
    return false;
    }
    // Re-open the asset file
    try {
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed trying to re-open asset " +
    asset +
    " after checking for a valid database."
    );
    e.printStackTrace();
    return false;
    }

    // Read the entire asset file into a buffer
    Log.d(LOGTAG, thisclass +
    " copying asset database " +
    dbname +
    " into buffer of size " +
    filesize
    );
    byte buffer = new byte[filesize];
    // Close the asset file
    try {
    assetsdb.read(buffer);
    Log.d(LOGTAG,thisclass +
    " closing asset database " + dbname
    );
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed while copying asset database " +
    dbname +
    " (or closing asset database)."
    );
    e.printStackTrace();
    return false;
    }
    // Open the new database file
    try {
    Log.d(LOGTAG,thisclass + " attempting to open new database file " + dbpath);
    database = new FileOutputStream(dbpath);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed to open new database file.");
    e.printStackTrace();
    return false;
    }
    // Write the new database file
    try {
    Log.d(LOGTAG, thisclass + " writing new database file " + dbpath);
    database.write(buffer);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while writing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Flush the new database file
    try {
    Log.d(LOGTAG, thisclass + " flushing new database file " + dbpath);
    database.flush();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while flushing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Close the new database file
    try {
    Log.d(LOGTAG, thisclass + " closing new database file " + dbpath);
    database.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while closing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    return true;
    }

    /**
    * Log Database table Information
    */
    private void logDatabaseTableInformation(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    String mastertable = "sqlite_master";
    String typecolumn = "type";
    String namecolumn = "name";
    String sqlcolumn = "sql";
    String args = new String{"table","android_metadata"};
    Cursor csr = db.query(mastertable,
    null,
    typecolumn + "=? AND " + namecolumn + "!=?",
    args,
    null,null,null
    );
    while (csr.moveToNext()) {
    Log.d(LOGTAG,"Database contains Table " +
    csr.getString(csr.getColumnIndex(namecolumn)) +
    " created by SQL " +
    csr.getString(csr.getColumnIndex(sqlcolumn))
    );
    logTableInformation(db, csr.getString(csr.getColumnIndex(namecolumn)));
    }
    csr.close();
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Write Table information, Table name, Column Count,
    * Row Count and Column Names to the Log
    * @param table Name of the table to be reported on
    */
    private void logTableInformation(SQLiteDatabase db, String table) {
    Cursor csr = db.query(table,
    null,
    null,
    null,
    null,
    null,
    null
    );
    Log.d(LOGTAG,"Table is " +
    table +
    " Column Count = " +
    Integer.toString(csr.getColumnCount()) +
    " Row Count = " +
    Long.toString(DatabaseUtils.queryNumEntries(mDB,table))
    );
    StringBuilder columns_as_string = new StringBuilder();
    for (String s: csr.getColumnNames()) {
    columns_as_string.append(s).append(" ");
    }
    Log.d(LOGTAG, "tColumns are :- " + columns_as_string);
    csr.close();
    }

    /**
    * Build the sub-path to the asset, according to the directories specified
    *
    * @param directories directories underneath the assets folder where
    * the asset files is located, null or empty
    * array if file is located directly in the
    * assets folder;
    * directories must be specified in the order
    * in which they appear in the path.
    * @param filename The filename of the asset
    * @return The fill sub-path to the asset
    */
    private String buildAssetPath(String directories, String filename) {
    StringBuilder sb = new StringBuilder();
    final String SEPERATOR = "/";
    if (directories != null && directories.length > 0) {
    for (String s: directories) {
    sb.append(s);
    if (!s.substring(s.length()-1,s.length()).equals(SEPERATOR)) {
    sb.append(SEPERATOR);
    }
    }
    sb.append(filename);
    return sb.toString();
    } else {
    return filename;
    }
    }
    }


    Example Usage



    public class MainActivity extends AppCompatActivity {

    public static final int DBVERSION = 1;
    public static final String DBNAME1 = "openassetdb.db";
    public static final int DB1_INDEX = 0;
    public static final String DBNAME2 = "myshopping";
    public static final int DB2_INDEX = 1;

    OpenAssetDBHelper mOADBHlpr;
    OpenAssetDBHelper mShoppingHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example 1 - Database file located in the assets folder and
    // database name same as file name
    mOADBHlpr = OpenAssetDBHelper.getInstance(DB1_INDEX,
    this,
    DBNAME1,
    DBVERSION,
    DBNAME1,
    null
    );
    // Example 2 - Database file in databases directory of the assets folder
    // database name different to the asset filename
    mShoppingHelper = OpenAssetDBHelper.getInstance(DB2_INDEX,
    this,
    DBNAME2,
    DBVERSION,
    "shopper",
    new String{"databases"}
    );
    }
    }


    Result (when no databases exist) :-



    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: Database openassetdb.db not found at /data/user/0/mjt.openassetdb/databases/openassetdb.db so attempting to copy from assets.
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset openassetdb.db located successfully with a size of 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database openassetdb.db into buffer of size 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.425 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table testtable created by SQL CREATE TABLE `testtable` (
    `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
    `name` TEXT,
    `timestamp` INTEGER
    )
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Table is testtable Column Count = 3 Row Count = 2
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Columns are :- _id name timestamp
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table sqlite_sequence created by SQL CREATE TABLE sqlite_sequence(name,seq)
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Table is sqlite_sequence Column Count = 2 Row Count = 1
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Columns are :- name seq
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.


    (2nd)



    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: Database myshopping not found at /data/user/0/mjt.openassetdb/databases/myshopping so attempting to copy from assets.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/shopper
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset databases/shopper located successfully with a size of 262144
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database myshopping into buffer of size 262144
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.443 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.444 1993-1993/? D/OADB-HLPR: Database contains Table shops created by SQL CREATE TABLE shops (_id INTEGER PRIMARY KEY , shopname TEXT , shoporder INTEGER DEFAULT 100 , shopstreet TEXT , shopcity TEXT , shopstate TEXT , shopphone TEXT , shopnotes TEXT )
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Table is shops Column Count = 8 Row Count = 4
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Columns are :- _id shopname shoporder shopstreet shopcity shopstate shopphone shopnotes
    2018-11-22 07:06:01.446 1993-1993/? D/OADB-HLPR: Database contains Table aisles created by SQL CREATE TABLE aisles (_id INTEGER PRIMARY KEY , aislename TEXT , aisleorder INTEGER DEFAULT 100 , aisleshopref INTEGER )
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Table is aisles Column Count = 4 Row Count = 20
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Columns are :- _id aislename aisleorder aisleshopref
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Database contains Table products created by SQL CREATE TABLE products (_id INTEGER PRIMARY KEY , productname TEXT , productorder INTEGER DEFAULT 100 , productaisleref INTEGER , productuses INTEGER DEFAULT 0 , productnotes TEXT )
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Table is products Column Count = 6 Row Count = 10
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Columns are :- _id productname productorder productaisleref productuses productnotes
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Database contains Table productusage created by SQL CREATE TABLE productusage (productailseref INTEGER , productproductref INTEGER , productcost REAL DEFAULT 1.00 , productbuycount INTEGER DEFAULT 0 , productfirstbuydate INTEGER DEFAULT 0 , productlatestbuydate INTEGER DEFAULT 0 , mincost REAL , PRIMARY KEY (productailseref, productproductref))
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Table is productusage Column Count = 7 Row Count = 20
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Columns are :- productailseref productproductref productcost productbuycount productfirstbuydate productlatestbuydate mincost
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Database contains Table rules created by SQL CREATE TABLE rules (ruleid INTEGER PRIMARY KEY , rulename TEXT , ruletype INTEGER , rulepromptflag INTEGER , ruleperiod INTEGER , rulemultiplier INTEGER , ruleactiveon INTEGER , ruleproductref INTEGER , ruleaisleref INTEGER )
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Table is rules Column Count = 9 Row Count = 0
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Columns are :- ruleid rulename ruletype rulepromptflag ruleperiod rulemultiplier ruleactiveon ruleproductref ruleaisleref
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Database contains Table shoplist created by SQL CREATE TABLE "shoplist" ("_id" INTEGER PRIMARY KEY NOT NULL , "productref" INTEGER, "dateadded" INTEGER, "numbertoget" INTEGER, "done" BOOL, "dategot" INTEGER, "cost" REAL, "productusageref" INTEGER, "aisleref" INTEGER)
    2018-11-22 07:06:01.453 1993-1993/? D/OADB-HLPR: Table is shoplist Column Count = 9 Row Count = 4
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: Columns are :- _id productref dateadded numbertoget done dategot cost productusageref aisleref
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.





    share|improve this answer
























    • I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

      – Ulrich_Peters
      Nov 26 '18 at 15:54











    • Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

      – Ulrich_Peters
      Nov 29 '18 at 5:58











    • @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

      – MikeT
      Nov 29 '18 at 8:22











    • @Ulrich_Peters also note that file and directory names are case dependant.

      – MikeT
      Nov 29 '18 at 8:59














    0












    0








    0







    The problem with the code you have is that numerous exceptions are caught by using throws IOException and then you just issue a generic exception.



    Whilst there could be a number of underlying causes.



    It could be that asset itself doesn't exist where it's expected (in the assets folder (e.g. not in the databases directory (SQLiteAssetHelper uses this directory))).



    It could be that the databases folder, within the package doesn't exist (use mkdirs on the DB_PATH). e.g. have something like :-



    private boolean checkDatabase {
    File db = new File(mContext.getDatabasePath(DB_NAME).getPath());
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }



    • Note the use of the Context's getDatabasePath


    The following is code that is very long but provides very comprehensive logging (it also caters for multiple databases (up to 10 by default) and is also caters for directories in the assets folder).



    /**
    * Database Helper that includes ability to open database from assets
    * if the database doesn't exist.
    * (i.e. a pre-defined database)
    *
    */

    public class OpenAssetDBHelper extends SQLiteOpenHelper {

    private static final String LOGTAG = "OADB-HLPR";
    public static final int MAXIMUM_HELPERS = 10;
    private String mDBPath, mAssetPath;
    private static OpenAssetDBHelper mInstance = new OpenAssetDBHelper[MAXIMUM_HELPERS];
    private SQLiteDatabase mDB;

    /**
    * OpenAssetDBHelper Class that will copy a predefined database
    * from the assets folder and then open it is the database;
    *
    * The copy will only be done if the database does not exist.
    *
    * Note this code is intended to be used for development and/or
    * experimentation, hence the extensive logging.
    */

    /**
    * get an OpenAssetDBHelper instance as a singleton;
    * Note! caters for up to 10 OpenAssetDBHelpers for up to 10 databases
    * as specified by the helper_index
    *
    * @param helper_index Index to this instance/database
    * (0-MAXIMUM_HELPERS less 1)
    * @param context Context for the database
    * @param database Database name (i.e. file name)
    * @param dbversion Database version (user_version)
    * @param assetfile Name of the asset file to be copied to the database
    * @param asset_sub_directories String Array of the sub-directories where
    * the asset file is located;
    * MUST be in order
    * @return The resultant OpenAssetDBHelper
    */
    public static synchronized OpenAssetDBHelper getInstance(
    int helper_index,
    Context context,
    String database,
    int dbversion,
    String assetfile,
    String asset_sub_directories) {
    // Checck that helper_index is within bounds
    if (helper_index > (MAXIMUM_HELPERS -1)) {
    throw new RuntimeException(
    "Helper Index greater than " +
    MAXIMUM_HELPERS
    );
    }
    if (helper_index < 0) {
    throw new RuntimeException(
    "Helper Index cannot be negative, must be 0-" +
    MAXIMUM_HELPERS
    );
    }
    // Create the respective OpenAssetDBHelper instance
    if(mInstance[helper_index] == null) {
    mInstance[helper_index] = new OpenAssetDBHelper(context,
    database,
    dbversion,
    assetfile,
    asset_sub_directories);
    }
    return mInstance[helper_index];
    }

    /**
    * Construct an OpenAssetDBHelper instance;
    * Note! can only be called within class
    *
    * @param context the context to be used
    * @param database the database name (equates to filename)
    * @param dbversion the databaae version (user_version)
    * @param assetfile The name of the asset file i.e. the pre-defined db
    * @param directories The hierarchy of directories within the assets folder
    * where the asset file is located
    * (null or zero elements = in the assets folder)
    */
    private OpenAssetDBHelper(Context context,
    String database,
    int dbversion,
    String assetfile,
    String directories) {
    super(context, database, null, dbversion);
    Log.d(LOGTAG,"OpenAssetDBHelper being constructed.");

    mDBPath = context.getDatabasePath(database).getPath();
    if (assetfile == null || assetfile.length() < 1) {
    assetfile = database;
    }
    mAssetPath = buildAssetPath(directories,assetfile);

    if (!ifDatabaseExists(mDBPath)) {
    Log.d(LOGTAG,"Database " + database + " not found at " + mDBPath + " so attempting to copy from assets.");
    if (copyDatabaseFromAssets(context,mDBPath, database, mAssetPath)) {
    Log.d(LOGTAG, "Successfully Copied Database from Assets.");
    } else {
    throw new RuntimeException("No Database Available.");
    }
    }
    // Force Database open and store it
    this.mDB = this.getWritableDatabase();
    logDatabaseTableInformation(mDB);
    Log.d(LOGTAG,"OpenAssetDBHelper constructed.");
    }


    /**
    * onCreate - This is where you would create tables;
    * Typically this is where you would alter the structure of the database;
    * Note that this is called once for the lifetime of the database.
    * @param db The SQLitedatabase
    */
    @Override
    public void onCreate(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // As Database is copied from assets nothing to do in onCreate!
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // Nothing to do as it's early days in the Database's lifetime.
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Check to see if the Database exists,
    * if it doesn't exists then check to see if
    * the database directory exists,
    * if the directory(ies) does(do) not exist then make the directory(ies);
    *
    *
    * @param dbpath The path to the database
    * @return true if the database exists, else false
    */
    private boolean ifDatabaseExists(String dbpath) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    File db = new File(dbpath);
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }

    /**
    * Copy the Database from the assets folder
    * @param context
    * @param dbpath
    * @return
    */
    private boolean copyDatabaseFromAssets(Context context,String dbpath, String dbname, String asset) {
    String thisclass = new Object(){}.getClass().getEnclosingMethod().getName();
    Log.d(LOGTAG,thisclass + " initiated");
    InputStream assetsdb;
    OutputStream database;
    File db = new File(dbpath);
    int filesize;
    // Get the asset file
    try {
    Log.d(LOGTAG,thisclass + " attempting to find asset " + asset);
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    Log.d(LOGTAG,thisclass + " asset " + asset +
    " located successfully with a size of " +
    Integer.toString(filesize)
    );
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass + " Did not locate asset " + asset);
    e.printStackTrace();
    return false;
    }

    // Read the first 16 bytes from the asset file
    byte dbcheck = new byte[16];
    try {
    assetsdb.read(dbcheck,0,16);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed trying to read 16 bytes to check for a valid database. ");
    e.printStackTrace();
    return false;
    }

    // Check that the asset file is an SQLite database
    String chkdb = new String(dbcheck);
    if(!chkdb.equals("SQLite format 3u0000")) {
    Log.d(LOGTAG,thisclass + " asset " +
    asset +
    " is not a valid SQLite Database File (found " +
    chkdb +
    " at bytes 1-16 instead of SQLite format 3)");
    try {
    assetsdb.close();
    } catch (IOException e) {
    // Not worth doing anything
    }
    return false;
    }
    // Close the asset file
    try {
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass +
    " failed to close assets file after checking for a valid database."
    );
    return false;
    }
    // Re-open the asset file
    try {
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed trying to re-open asset " +
    asset +
    " after checking for a valid database."
    );
    e.printStackTrace();
    return false;
    }

    // Read the entire asset file into a buffer
    Log.d(LOGTAG, thisclass +
    " copying asset database " +
    dbname +
    " into buffer of size " +
    filesize
    );
    byte buffer = new byte[filesize];
    // Close the asset file
    try {
    assetsdb.read(buffer);
    Log.d(LOGTAG,thisclass +
    " closing asset database " + dbname
    );
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed while copying asset database " +
    dbname +
    " (or closing asset database)."
    );
    e.printStackTrace();
    return false;
    }
    // Open the new database file
    try {
    Log.d(LOGTAG,thisclass + " attempting to open new database file " + dbpath);
    database = new FileOutputStream(dbpath);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed to open new database file.");
    e.printStackTrace();
    return false;
    }
    // Write the new database file
    try {
    Log.d(LOGTAG, thisclass + " writing new database file " + dbpath);
    database.write(buffer);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while writing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Flush the new database file
    try {
    Log.d(LOGTAG, thisclass + " flushing new database file " + dbpath);
    database.flush();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while flushing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Close the new database file
    try {
    Log.d(LOGTAG, thisclass + " closing new database file " + dbpath);
    database.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while closing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    return true;
    }

    /**
    * Log Database table Information
    */
    private void logDatabaseTableInformation(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    String mastertable = "sqlite_master";
    String typecolumn = "type";
    String namecolumn = "name";
    String sqlcolumn = "sql";
    String args = new String{"table","android_metadata"};
    Cursor csr = db.query(mastertable,
    null,
    typecolumn + "=? AND " + namecolumn + "!=?",
    args,
    null,null,null
    );
    while (csr.moveToNext()) {
    Log.d(LOGTAG,"Database contains Table " +
    csr.getString(csr.getColumnIndex(namecolumn)) +
    " created by SQL " +
    csr.getString(csr.getColumnIndex(sqlcolumn))
    );
    logTableInformation(db, csr.getString(csr.getColumnIndex(namecolumn)));
    }
    csr.close();
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Write Table information, Table name, Column Count,
    * Row Count and Column Names to the Log
    * @param table Name of the table to be reported on
    */
    private void logTableInformation(SQLiteDatabase db, String table) {
    Cursor csr = db.query(table,
    null,
    null,
    null,
    null,
    null,
    null
    );
    Log.d(LOGTAG,"Table is " +
    table +
    " Column Count = " +
    Integer.toString(csr.getColumnCount()) +
    " Row Count = " +
    Long.toString(DatabaseUtils.queryNumEntries(mDB,table))
    );
    StringBuilder columns_as_string = new StringBuilder();
    for (String s: csr.getColumnNames()) {
    columns_as_string.append(s).append(" ");
    }
    Log.d(LOGTAG, "tColumns are :- " + columns_as_string);
    csr.close();
    }

    /**
    * Build the sub-path to the asset, according to the directories specified
    *
    * @param directories directories underneath the assets folder where
    * the asset files is located, null or empty
    * array if file is located directly in the
    * assets folder;
    * directories must be specified in the order
    * in which they appear in the path.
    * @param filename The filename of the asset
    * @return The fill sub-path to the asset
    */
    private String buildAssetPath(String directories, String filename) {
    StringBuilder sb = new StringBuilder();
    final String SEPERATOR = "/";
    if (directories != null && directories.length > 0) {
    for (String s: directories) {
    sb.append(s);
    if (!s.substring(s.length()-1,s.length()).equals(SEPERATOR)) {
    sb.append(SEPERATOR);
    }
    }
    sb.append(filename);
    return sb.toString();
    } else {
    return filename;
    }
    }
    }


    Example Usage



    public class MainActivity extends AppCompatActivity {

    public static final int DBVERSION = 1;
    public static final String DBNAME1 = "openassetdb.db";
    public static final int DB1_INDEX = 0;
    public static final String DBNAME2 = "myshopping";
    public static final int DB2_INDEX = 1;

    OpenAssetDBHelper mOADBHlpr;
    OpenAssetDBHelper mShoppingHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example 1 - Database file located in the assets folder and
    // database name same as file name
    mOADBHlpr = OpenAssetDBHelper.getInstance(DB1_INDEX,
    this,
    DBNAME1,
    DBVERSION,
    DBNAME1,
    null
    );
    // Example 2 - Database file in databases directory of the assets folder
    // database name different to the asset filename
    mShoppingHelper = OpenAssetDBHelper.getInstance(DB2_INDEX,
    this,
    DBNAME2,
    DBVERSION,
    "shopper",
    new String{"databases"}
    );
    }
    }


    Result (when no databases exist) :-



    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: Database openassetdb.db not found at /data/user/0/mjt.openassetdb/databases/openassetdb.db so attempting to copy from assets.
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset openassetdb.db located successfully with a size of 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database openassetdb.db into buffer of size 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.425 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table testtable created by SQL CREATE TABLE `testtable` (
    `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
    `name` TEXT,
    `timestamp` INTEGER
    )
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Table is testtable Column Count = 3 Row Count = 2
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Columns are :- _id name timestamp
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table sqlite_sequence created by SQL CREATE TABLE sqlite_sequence(name,seq)
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Table is sqlite_sequence Column Count = 2 Row Count = 1
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Columns are :- name seq
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.


    (2nd)



    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: Database myshopping not found at /data/user/0/mjt.openassetdb/databases/myshopping so attempting to copy from assets.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/shopper
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset databases/shopper located successfully with a size of 262144
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database myshopping into buffer of size 262144
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.443 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.444 1993-1993/? D/OADB-HLPR: Database contains Table shops created by SQL CREATE TABLE shops (_id INTEGER PRIMARY KEY , shopname TEXT , shoporder INTEGER DEFAULT 100 , shopstreet TEXT , shopcity TEXT , shopstate TEXT , shopphone TEXT , shopnotes TEXT )
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Table is shops Column Count = 8 Row Count = 4
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Columns are :- _id shopname shoporder shopstreet shopcity shopstate shopphone shopnotes
    2018-11-22 07:06:01.446 1993-1993/? D/OADB-HLPR: Database contains Table aisles created by SQL CREATE TABLE aisles (_id INTEGER PRIMARY KEY , aislename TEXT , aisleorder INTEGER DEFAULT 100 , aisleshopref INTEGER )
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Table is aisles Column Count = 4 Row Count = 20
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Columns are :- _id aislename aisleorder aisleshopref
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Database contains Table products created by SQL CREATE TABLE products (_id INTEGER PRIMARY KEY , productname TEXT , productorder INTEGER DEFAULT 100 , productaisleref INTEGER , productuses INTEGER DEFAULT 0 , productnotes TEXT )
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Table is products Column Count = 6 Row Count = 10
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Columns are :- _id productname productorder productaisleref productuses productnotes
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Database contains Table productusage created by SQL CREATE TABLE productusage (productailseref INTEGER , productproductref INTEGER , productcost REAL DEFAULT 1.00 , productbuycount INTEGER DEFAULT 0 , productfirstbuydate INTEGER DEFAULT 0 , productlatestbuydate INTEGER DEFAULT 0 , mincost REAL , PRIMARY KEY (productailseref, productproductref))
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Table is productusage Column Count = 7 Row Count = 20
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Columns are :- productailseref productproductref productcost productbuycount productfirstbuydate productlatestbuydate mincost
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Database contains Table rules created by SQL CREATE TABLE rules (ruleid INTEGER PRIMARY KEY , rulename TEXT , ruletype INTEGER , rulepromptflag INTEGER , ruleperiod INTEGER , rulemultiplier INTEGER , ruleactiveon INTEGER , ruleproductref INTEGER , ruleaisleref INTEGER )
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Table is rules Column Count = 9 Row Count = 0
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Columns are :- ruleid rulename ruletype rulepromptflag ruleperiod rulemultiplier ruleactiveon ruleproductref ruleaisleref
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Database contains Table shoplist created by SQL CREATE TABLE "shoplist" ("_id" INTEGER PRIMARY KEY NOT NULL , "productref" INTEGER, "dateadded" INTEGER, "numbertoget" INTEGER, "done" BOOL, "dategot" INTEGER, "cost" REAL, "productusageref" INTEGER, "aisleref" INTEGER)
    2018-11-22 07:06:01.453 1993-1993/? D/OADB-HLPR: Table is shoplist Column Count = 9 Row Count = 4
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: Columns are :- _id productref dateadded numbertoget done dategot cost productusageref aisleref
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.





    share|improve this answer













    The problem with the code you have is that numerous exceptions are caught by using throws IOException and then you just issue a generic exception.



    Whilst there could be a number of underlying causes.



    It could be that asset itself doesn't exist where it's expected (in the assets folder (e.g. not in the databases directory (SQLiteAssetHelper uses this directory))).



    It could be that the databases folder, within the package doesn't exist (use mkdirs on the DB_PATH). e.g. have something like :-



    private boolean checkDatabase {
    File db = new File(mContext.getDatabasePath(DB_NAME).getPath());
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }



    • Note the use of the Context's getDatabasePath


    The following is code that is very long but provides very comprehensive logging (it also caters for multiple databases (up to 10 by default) and is also caters for directories in the assets folder).



    /**
    * Database Helper that includes ability to open database from assets
    * if the database doesn't exist.
    * (i.e. a pre-defined database)
    *
    */

    public class OpenAssetDBHelper extends SQLiteOpenHelper {

    private static final String LOGTAG = "OADB-HLPR";
    public static final int MAXIMUM_HELPERS = 10;
    private String mDBPath, mAssetPath;
    private static OpenAssetDBHelper mInstance = new OpenAssetDBHelper[MAXIMUM_HELPERS];
    private SQLiteDatabase mDB;

    /**
    * OpenAssetDBHelper Class that will copy a predefined database
    * from the assets folder and then open it is the database;
    *
    * The copy will only be done if the database does not exist.
    *
    * Note this code is intended to be used for development and/or
    * experimentation, hence the extensive logging.
    */

    /**
    * get an OpenAssetDBHelper instance as a singleton;
    * Note! caters for up to 10 OpenAssetDBHelpers for up to 10 databases
    * as specified by the helper_index
    *
    * @param helper_index Index to this instance/database
    * (0-MAXIMUM_HELPERS less 1)
    * @param context Context for the database
    * @param database Database name (i.e. file name)
    * @param dbversion Database version (user_version)
    * @param assetfile Name of the asset file to be copied to the database
    * @param asset_sub_directories String Array of the sub-directories where
    * the asset file is located;
    * MUST be in order
    * @return The resultant OpenAssetDBHelper
    */
    public static synchronized OpenAssetDBHelper getInstance(
    int helper_index,
    Context context,
    String database,
    int dbversion,
    String assetfile,
    String asset_sub_directories) {
    // Checck that helper_index is within bounds
    if (helper_index > (MAXIMUM_HELPERS -1)) {
    throw new RuntimeException(
    "Helper Index greater than " +
    MAXIMUM_HELPERS
    );
    }
    if (helper_index < 0) {
    throw new RuntimeException(
    "Helper Index cannot be negative, must be 0-" +
    MAXIMUM_HELPERS
    );
    }
    // Create the respective OpenAssetDBHelper instance
    if(mInstance[helper_index] == null) {
    mInstance[helper_index] = new OpenAssetDBHelper(context,
    database,
    dbversion,
    assetfile,
    asset_sub_directories);
    }
    return mInstance[helper_index];
    }

    /**
    * Construct an OpenAssetDBHelper instance;
    * Note! can only be called within class
    *
    * @param context the context to be used
    * @param database the database name (equates to filename)
    * @param dbversion the databaae version (user_version)
    * @param assetfile The name of the asset file i.e. the pre-defined db
    * @param directories The hierarchy of directories within the assets folder
    * where the asset file is located
    * (null or zero elements = in the assets folder)
    */
    private OpenAssetDBHelper(Context context,
    String database,
    int dbversion,
    String assetfile,
    String directories) {
    super(context, database, null, dbversion);
    Log.d(LOGTAG,"OpenAssetDBHelper being constructed.");

    mDBPath = context.getDatabasePath(database).getPath();
    if (assetfile == null || assetfile.length() < 1) {
    assetfile = database;
    }
    mAssetPath = buildAssetPath(directories,assetfile);

    if (!ifDatabaseExists(mDBPath)) {
    Log.d(LOGTAG,"Database " + database + " not found at " + mDBPath + " so attempting to copy from assets.");
    if (copyDatabaseFromAssets(context,mDBPath, database, mAssetPath)) {
    Log.d(LOGTAG, "Successfully Copied Database from Assets.");
    } else {
    throw new RuntimeException("No Database Available.");
    }
    }
    // Force Database open and store it
    this.mDB = this.getWritableDatabase();
    logDatabaseTableInformation(mDB);
    Log.d(LOGTAG,"OpenAssetDBHelper constructed.");
    }


    /**
    * onCreate - This is where you would create tables;
    * Typically this is where you would alter the structure of the database;
    * Note that this is called once for the lifetime of the database.
    * @param db The SQLitedatabase
    */
    @Override
    public void onCreate(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // As Database is copied from assets nothing to do in onCreate!
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    // Nothing to do as it's early days in the Database's lifetime.
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Check to see if the Database exists,
    * if it doesn't exists then check to see if
    * the database directory exists,
    * if the directory(ies) does(do) not exist then make the directory(ies);
    *
    *
    * @param dbpath The path to the database
    * @return true if the database exists, else false
    */
    private boolean ifDatabaseExists(String dbpath) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    File db = new File(dbpath);
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
    dir.mkdirs();
    }
    return false;
    }

    /**
    * Copy the Database from the assets folder
    * @param context
    * @param dbpath
    * @return
    */
    private boolean copyDatabaseFromAssets(Context context,String dbpath, String dbname, String asset) {
    String thisclass = new Object(){}.getClass().getEnclosingMethod().getName();
    Log.d(LOGTAG,thisclass + " initiated");
    InputStream assetsdb;
    OutputStream database;
    File db = new File(dbpath);
    int filesize;
    // Get the asset file
    try {
    Log.d(LOGTAG,thisclass + " attempting to find asset " + asset);
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    Log.d(LOGTAG,thisclass + " asset " + asset +
    " located successfully with a size of " +
    Integer.toString(filesize)
    );
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass + " Did not locate asset " + asset);
    e.printStackTrace();
    return false;
    }

    // Read the first 16 bytes from the asset file
    byte dbcheck = new byte[16];
    try {
    assetsdb.read(dbcheck,0,16);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed trying to read 16 bytes to check for a valid database. ");
    e.printStackTrace();
    return false;
    }

    // Check that the asset file is an SQLite database
    String chkdb = new String(dbcheck);
    if(!chkdb.equals("SQLite format 3u0000")) {
    Log.d(LOGTAG,thisclass + " asset " +
    asset +
    " is not a valid SQLite Database File (found " +
    chkdb +
    " at bytes 1-16 instead of SQLite format 3)");
    try {
    assetsdb.close();
    } catch (IOException e) {
    // Not worth doing anything
    }
    return false;
    }
    // Close the asset file
    try {
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG,thisclass +
    " failed to close assets file after checking for a valid database."
    );
    return false;
    }
    // Re-open the asset file
    try {
    assetsdb = context.getAssets().open(asset);
    filesize = assetsdb.available();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed trying to re-open asset " +
    asset +
    " after checking for a valid database."
    );
    e.printStackTrace();
    return false;
    }

    // Read the entire asset file into a buffer
    Log.d(LOGTAG, thisclass +
    " copying asset database " +
    dbname +
    " into buffer of size " +
    filesize
    );
    byte buffer = new byte[filesize];
    // Close the asset file
    try {
    assetsdb.read(buffer);
    Log.d(LOGTAG,thisclass +
    " closing asset database " + dbname
    );
    assetsdb.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass +
    " failed while copying asset database " +
    dbname +
    " (or closing asset database)."
    );
    e.printStackTrace();
    return false;
    }
    // Open the new database file
    try {
    Log.d(LOGTAG,thisclass + " attempting to open new database file " + dbpath);
    database = new FileOutputStream(dbpath);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed to open new database file.");
    e.printStackTrace();
    return false;
    }
    // Write the new database file
    try {
    Log.d(LOGTAG, thisclass + " writing new database file " + dbpath);
    database.write(buffer);
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while writing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Flush the new database file
    try {
    Log.d(LOGTAG, thisclass + " flushing new database file " + dbpath);
    database.flush();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while flushing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    // Close the new database file
    try {
    Log.d(LOGTAG, thisclass + " closing new database file " + dbpath);
    database.close();
    } catch (IOException e) {
    Log.d(LOGTAG, thisclass + " failed while closing new database file " + dbpath);
    e.printStackTrace();
    return false;
    }
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    return true;
    }

    /**
    * Log Database table Information
    */
    private void logDatabaseTableInformation(SQLiteDatabase db) {
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " initiated.");
    String mastertable = "sqlite_master";
    String typecolumn = "type";
    String namecolumn = "name";
    String sqlcolumn = "sql";
    String args = new String{"table","android_metadata"};
    Cursor csr = db.query(mastertable,
    null,
    typecolumn + "=? AND " + namecolumn + "!=?",
    args,
    null,null,null
    );
    while (csr.moveToNext()) {
    Log.d(LOGTAG,"Database contains Table " +
    csr.getString(csr.getColumnIndex(namecolumn)) +
    " created by SQL " +
    csr.getString(csr.getColumnIndex(sqlcolumn))
    );
    logTableInformation(db, csr.getString(csr.getColumnIndex(namecolumn)));
    }
    csr.close();
    Log.d(LOGTAG,new Object(){}.getClass().getEnclosingMethod().getName() + " completed.");
    }

    /**
    * Write Table information, Table name, Column Count,
    * Row Count and Column Names to the Log
    * @param table Name of the table to be reported on
    */
    private void logTableInformation(SQLiteDatabase db, String table) {
    Cursor csr = db.query(table,
    null,
    null,
    null,
    null,
    null,
    null
    );
    Log.d(LOGTAG,"Table is " +
    table +
    " Column Count = " +
    Integer.toString(csr.getColumnCount()) +
    " Row Count = " +
    Long.toString(DatabaseUtils.queryNumEntries(mDB,table))
    );
    StringBuilder columns_as_string = new StringBuilder();
    for (String s: csr.getColumnNames()) {
    columns_as_string.append(s).append(" ");
    }
    Log.d(LOGTAG, "tColumns are :- " + columns_as_string);
    csr.close();
    }

    /**
    * Build the sub-path to the asset, according to the directories specified
    *
    * @param directories directories underneath the assets folder where
    * the asset files is located, null or empty
    * array if file is located directly in the
    * assets folder;
    * directories must be specified in the order
    * in which they appear in the path.
    * @param filename The filename of the asset
    * @return The fill sub-path to the asset
    */
    private String buildAssetPath(String directories, String filename) {
    StringBuilder sb = new StringBuilder();
    final String SEPERATOR = "/";
    if (directories != null && directories.length > 0) {
    for (String s: directories) {
    sb.append(s);
    if (!s.substring(s.length()-1,s.length()).equals(SEPERATOR)) {
    sb.append(SEPERATOR);
    }
    }
    sb.append(filename);
    return sb.toString();
    } else {
    return filename;
    }
    }
    }


    Example Usage



    public class MainActivity extends AppCompatActivity {

    public static final int DBVERSION = 1;
    public static final String DBNAME1 = "openassetdb.db";
    public static final int DB1_INDEX = 0;
    public static final String DBNAME2 = "myshopping";
    public static final int DB2_INDEX = 1;

    OpenAssetDBHelper mOADBHlpr;
    OpenAssetDBHelper mShoppingHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example 1 - Database file located in the assets folder and
    // database name same as file name
    mOADBHlpr = OpenAssetDBHelper.getInstance(DB1_INDEX,
    this,
    DBNAME1,
    DBVERSION,
    DBNAME1,
    null
    );
    // Example 2 - Database file in databases directory of the assets folder
    // database name different to the asset filename
    mShoppingHelper = OpenAssetDBHelper.getInstance(DB2_INDEX,
    this,
    DBNAME2,
    DBVERSION,
    "shopper",
    new String{"databases"}
    );
    }
    }


    Result (when no databases exist) :-



    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.408 1993-1993/? D/OADB-HLPR: Database openassetdb.db not found at /data/user/0/mjt.openassetdb/databases/openassetdb.db so attempting to copy from assets.
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset openassetdb.db located successfully with a size of 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database openassetdb.db into buffer of size 12288
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database openassetdb.db
    2018-11-22 07:06:01.409 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/openassetdb.db
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.410 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.421 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.425 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table testtable created by SQL CREATE TABLE `testtable` (
    `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
    `name` TEXT,
    `timestamp` INTEGER
    )
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Table is testtable Column Count = 3 Row Count = 2
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Columns are :- _id name timestamp
    2018-11-22 07:06:01.426 1993-1993/? D/OADB-HLPR: Database contains Table sqlite_sequence created by SQL CREATE TABLE sqlite_sequence(name,seq)
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Table is sqlite_sequence Column Count = 2 Row Count = 1
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: Columns are :- name seq
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.


    (2nd)



    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    2018-11-22 07:06:01.427 1993-1993/? D/OADB-HLPR: ifDatabaseExists initiated.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: Database myshopping not found at /data/user/0/mjt.openassetdb/databases/myshopping so attempting to copy from assets.
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/shopper
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets asset databases/shopper located successfully with a size of 262144
    2018-11-22 07:06:01.428 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets copying asset database myshopping into buffer of size 262144
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing asset database myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets attempting to open new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets writing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets flushing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets closing new database file /data/user/0/mjt.openassetdb/databases/myshopping
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: copyDatabaseFromAssets completed.
    2018-11-22 07:06:01.429 1993-1993/? D/OADB-HLPR: Successfully Copied Database from Assets.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate initiated.
    2018-11-22 07:06:01.440 1993-1993/? D/OADB-HLPR: onCreate completed.
    2018-11-22 07:06:01.443 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation initiated.
    2018-11-22 07:06:01.444 1993-1993/? D/OADB-HLPR: Database contains Table shops created by SQL CREATE TABLE shops (_id INTEGER PRIMARY KEY , shopname TEXT , shoporder INTEGER DEFAULT 100 , shopstreet TEXT , shopcity TEXT , shopstate TEXT , shopphone TEXT , shopnotes TEXT )
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Table is shops Column Count = 8 Row Count = 4
    2018-11-22 07:06:01.445 1993-1993/? D/OADB-HLPR: Columns are :- _id shopname shoporder shopstreet shopcity shopstate shopphone shopnotes
    2018-11-22 07:06:01.446 1993-1993/? D/OADB-HLPR: Database contains Table aisles created by SQL CREATE TABLE aisles (_id INTEGER PRIMARY KEY , aislename TEXT , aisleorder INTEGER DEFAULT 100 , aisleshopref INTEGER )
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Table is aisles Column Count = 4 Row Count = 20
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Columns are :- _id aislename aisleorder aisleshopref
    2018-11-22 07:06:01.448 1993-1993/? D/OADB-HLPR: Database contains Table products created by SQL CREATE TABLE products (_id INTEGER PRIMARY KEY , productname TEXT , productorder INTEGER DEFAULT 100 , productaisleref INTEGER , productuses INTEGER DEFAULT 0 , productnotes TEXT )
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Table is products Column Count = 6 Row Count = 10
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Columns are :- _id productname productorder productaisleref productuses productnotes
    2018-11-22 07:06:01.449 1993-1993/? D/OADB-HLPR: Database contains Table productusage created by SQL CREATE TABLE productusage (productailseref INTEGER , productproductref INTEGER , productcost REAL DEFAULT 1.00 , productbuycount INTEGER DEFAULT 0 , productfirstbuydate INTEGER DEFAULT 0 , productlatestbuydate INTEGER DEFAULT 0 , mincost REAL , PRIMARY KEY (productailseref, productproductref))
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Table is productusage Column Count = 7 Row Count = 20
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Columns are :- productailseref productproductref productcost productbuycount productfirstbuydate productlatestbuydate mincost
    2018-11-22 07:06:01.451 1993-1993/? D/OADB-HLPR: Database contains Table rules created by SQL CREATE TABLE rules (ruleid INTEGER PRIMARY KEY , rulename TEXT , ruletype INTEGER , rulepromptflag INTEGER , ruleperiod INTEGER , rulemultiplier INTEGER , ruleactiveon INTEGER , ruleproductref INTEGER , ruleaisleref INTEGER )
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Table is rules Column Count = 9 Row Count = 0
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Columns are :- ruleid rulename ruletype rulepromptflag ruleperiod rulemultiplier ruleactiveon ruleproductref ruleaisleref
    2018-11-22 07:06:01.452 1993-1993/? D/OADB-HLPR: Database contains Table shoplist created by SQL CREATE TABLE "shoplist" ("_id" INTEGER PRIMARY KEY NOT NULL , "productref" INTEGER, "dateadded" INTEGER, "numbertoget" INTEGER, "done" BOOL, "dategot" INTEGER, "cost" REAL, "productusageref" INTEGER, "aisleref" INTEGER)
    2018-11-22 07:06:01.453 1993-1993/? D/OADB-HLPR: Table is shoplist Column Count = 9 Row Count = 4
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: Columns are :- _id productref dateadded numbertoget done dategot cost productusageref aisleref
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: logDatabaseTableInformation completed.
    2018-11-22 07:06:01.454 1993-1993/? D/OADB-HLPR: OpenAssetDBHelper constructed.






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 21 '18 at 20:12









    MikeTMikeT

    17.3k112643




    17.3k112643













    • I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

      – Ulrich_Peters
      Nov 26 '18 at 15:54











    • Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

      – Ulrich_Peters
      Nov 29 '18 at 5:58











    • @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

      – MikeT
      Nov 29 '18 at 8:22











    • @Ulrich_Peters also note that file and directory names are case dependant.

      – MikeT
      Nov 29 '18 at 8:59



















    • I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

      – Ulrich_Peters
      Nov 26 '18 at 15:54











    • Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

      – Ulrich_Peters
      Nov 29 '18 at 5:58











    • @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

      – MikeT
      Nov 29 '18 at 8:22











    • @Ulrich_Peters also note that file and directory names are case dependant.

      – MikeT
      Nov 29 '18 at 8:59

















    I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

    – Ulrich_Peters
    Nov 26 '18 at 15:54





    I tester your database adapter and it is working. I will investigate my own code later. Thank you very much for your reply!

    – Ulrich_Peters
    Nov 26 '18 at 15:54













    Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

    – Ulrich_Peters
    Nov 29 '18 at 5:58





    Ok. Somehow it is not working anymore. I simply get an D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset NewDATABASE.db even though i have NewDATABASE.db in my assets folder.

    – Ulrich_Peters
    Nov 29 '18 at 5:58













    @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

    – MikeT
    Nov 29 '18 at 8:22





    @Ulrich_Peters, I've added an explanatory answer (had to add another due to size restriction). I would initially suspect that you have specified a directory but not placed the asset in the directory or vice-versa. What you have/have not specified will be in the log before and after the line you have shown (there's no way that that is the only line in the log, unless you've made numerous changes)

    – MikeT
    Nov 29 '18 at 8:22













    @Ulrich_Peters also note that file and directory names are case dependant.

    – MikeT
    Nov 29 '18 at 8:59





    @Ulrich_Peters also note that file and directory names are case dependant.

    – MikeT
    Nov 29 '18 at 8:59













    0














    Additional - Asset not found example



    using



        mShopper = OpenAssetDBHelper.getInstance(DB3_INDEX,
    this,
    DBNAME3,
    DBVERSION,
    "Shopper.lite", // not the asset name
    new String{"databases"}
    );


    Where
    - DBNAME3 resolves to rumplestiltskin (the final database name)
    - DBVERSION is 1
    - and the asset filename is Shopper.lite which should be in the databases folder (doesn't exist though).



    The resultant log is :-



    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper constructed.
    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: ifDatabaseExists initiated.
    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: Database rumplestilskin not found at /data/data/mjt.openassetdb/databases/rumplestilskin so attempting to copy from assets.
    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets initiated
    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite
    11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite
    11-29 07:46:22.603 4816-4816/? W/System.err: java.io.FileNotFoundException: databases/Shopper.lite
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.openAsset(Native Method)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:315)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:289)
    11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.copyDatabaseFromAssets(OpenAssetDBHelper.java:187)
    11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:117)
    11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
    11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Activity.performCreate(Activity.java:5008)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:130)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Looper.loop(Looper.java:137)
    11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:4745)
    11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
    11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
    11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    11-29 07:46:22.603 4816-4816/? W/System.err: at dalvik.system.NativeStart.main(Native Method)
    11-29 07:46:22.603 4816-4816/? D/AndroidRuntime: Shutting down VM
    11-29 07:46:22.603 4816-4816/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6265288)
    11-29 07:46:22.603 4816-4816/? E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    at android.app.ActivityThread.access$600(ActivityThread.java:130)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.RuntimeException: No Database Available.
    at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:120)
    at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
    at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
    at android.app.Activity.performCreate(Activity.java:5008)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
    at android.app.ActivityThread.access$600(ActivityThread.java:130) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4745) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 


    The first pertinent line is D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite



    This provides the path within the assets folder where the asset is expected to be found (in this example the filename is expected to be Shopper.lite in the databases subfolder/directory)



    The line D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite reports that the asset file was not found.



    This is followed by the trapped exception (not the actual crash)



    Processing continues until the final crash as reported by :-



    E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.





    share|improve this answer




























      0














      Additional - Asset not found example



      using



          mShopper = OpenAssetDBHelper.getInstance(DB3_INDEX,
      this,
      DBNAME3,
      DBVERSION,
      "Shopper.lite", // not the asset name
      new String{"databases"}
      );


      Where
      - DBNAME3 resolves to rumplestiltskin (the final database name)
      - DBVERSION is 1
      - and the asset filename is Shopper.lite which should be in the databases folder (doesn't exist though).



      The resultant log is :-



      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper constructed.
      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: ifDatabaseExists initiated.
      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: Database rumplestilskin not found at /data/data/mjt.openassetdb/databases/rumplestilskin so attempting to copy from assets.
      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets initiated
      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite
      11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite
      11-29 07:46:22.603 4816-4816/? W/System.err: java.io.FileNotFoundException: databases/Shopper.lite
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.openAsset(Native Method)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:315)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:289)
      11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.copyDatabaseFromAssets(OpenAssetDBHelper.java:187)
      11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:117)
      11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
      11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Activity.performCreate(Activity.java:5008)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:130)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Looper.loop(Looper.java:137)
      11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:4745)
      11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
      11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
      11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
      11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
      11-29 07:46:22.603 4816-4816/? W/System.err: at dalvik.system.NativeStart.main(Native Method)
      11-29 07:46:22.603 4816-4816/? D/AndroidRuntime: Shutting down VM
      11-29 07:46:22.603 4816-4816/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6265288)
      11-29 07:46:22.603 4816-4816/? E/AndroidRuntime: FATAL EXCEPTION: main
      java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
      at android.app.ActivityThread.access$600(ActivityThread.java:130)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loop(Looper.java:137)
      at android.app.ActivityThread.main(ActivityThread.java:4745)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:511)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
      at dalvik.system.NativeStart.main(Native Method)
      Caused by: java.lang.RuntimeException: No Database Available.
      at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:120)
      at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
      at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
      at android.app.Activity.performCreate(Activity.java:5008)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
      at android.app.ActivityThread.access$600(ActivityThread.java:130) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:4745) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:511) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
      at dalvik.system.NativeStart.main(Native Method) 


      The first pertinent line is D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite



      This provides the path within the assets folder where the asset is expected to be found (in this example the filename is expected to be Shopper.lite in the databases subfolder/directory)



      The line D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite reports that the asset file was not found.



      This is followed by the trapped exception (not the actual crash)



      Processing continues until the final crash as reported by :-



      E/AndroidRuntime: FATAL EXCEPTION: main
      java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.





      share|improve this answer


























        0












        0








        0







        Additional - Asset not found example



        using



            mShopper = OpenAssetDBHelper.getInstance(DB3_INDEX,
        this,
        DBNAME3,
        DBVERSION,
        "Shopper.lite", // not the asset name
        new String{"databases"}
        );


        Where
        - DBNAME3 resolves to rumplestiltskin (the final database name)
        - DBVERSION is 1
        - and the asset filename is Shopper.lite which should be in the databases folder (doesn't exist though).



        The resultant log is :-



        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper constructed.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: ifDatabaseExists initiated.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: Database rumplestilskin not found at /data/data/mjt.openassetdb/databases/rumplestilskin so attempting to copy from assets.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets initiated
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite
        11-29 07:46:22.603 4816-4816/? W/System.err: java.io.FileNotFoundException: databases/Shopper.lite
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.openAsset(Native Method)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:315)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:289)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.copyDatabaseFromAssets(OpenAssetDBHelper.java:187)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:117)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Activity.performCreate(Activity.java:5008)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:130)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Looper.loop(Looper.java:137)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:4745)
        11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
        11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
        11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        11-29 07:46:22.603 4816-4816/? W/System.err: at dalvik.system.NativeStart.main(Native Method)
        11-29 07:46:22.603 4816-4816/? D/AndroidRuntime: Shutting down VM
        11-29 07:46:22.603 4816-4816/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6265288)
        11-29 07:46:22.603 4816-4816/? E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.RuntimeException: No Database Available.
        at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:120)
        at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
        at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
        at android.app.ActivityThread.access$600(ActivityThread.java:130) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 


        The first pertinent line is D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite



        This provides the path within the assets folder where the asset is expected to be found (in this example the filename is expected to be Shopper.lite in the databases subfolder/directory)



        The line D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite reports that the asset file was not found.



        This is followed by the trapped exception (not the actual crash)



        Processing continues until the final crash as reported by :-



        E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.





        share|improve this answer













        Additional - Asset not found example



        using



            mShopper = OpenAssetDBHelper.getInstance(DB3_INDEX,
        this,
        DBNAME3,
        DBVERSION,
        "Shopper.lite", // not the asset name
        new String{"databases"}
        );


        Where
        - DBNAME3 resolves to rumplestiltskin (the final database name)
        - DBVERSION is 1
        - and the asset filename is Shopper.lite which should be in the databases folder (doesn't exist though).



        The resultant log is :-



        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper constructed.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: OpenAssetDBHelper being constructed.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: ifDatabaseExists initiated.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: Database rumplestilskin not found at /data/data/mjt.openassetdb/databases/rumplestilskin so attempting to copy from assets.
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets initiated
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite
        11-29 07:46:22.603 4816-4816/? D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite
        11-29 07:46:22.603 4816-4816/? W/System.err: java.io.FileNotFoundException: databases/Shopper.lite
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.openAsset(Native Method)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:315)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.content.res.AssetManager.open(AssetManager.java:289)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.copyDatabaseFromAssets(OpenAssetDBHelper.java:187)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:117)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
        11-29 07:46:22.603 4816-4816/? W/System.err: at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Activity.performCreate(Activity.java:5008)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:130)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.os.Looper.loop(Looper.java:137)
        11-29 07:46:22.603 4816-4816/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:4745)
        11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
        11-29 07:46:22.603 4816-4816/? W/System.err: at java.lang.reflect.Method.invoke(Method.java:511)
        11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        11-29 07:46:22.603 4816-4816/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        11-29 07:46:22.603 4816-4816/? W/System.err: at dalvik.system.NativeStart.main(Native Method)
        11-29 07:46:22.603 4816-4816/? D/AndroidRuntime: Shutting down VM
        11-29 07:46:22.603 4816-4816/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6265288)
        11-29 07:46:22.603 4816-4816/? E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.RuntimeException: No Database Available.
        at mjt.openassetdb.OpenAssetDBHelper.<init>(OpenAssetDBHelper.java:120)
        at mjt.openassetdb.OpenAssetDBHelper.getInstance(OpenAssetDBHelper.java:80)
        at mjt.openassetdb.MainActivity.onCreate(MainActivity.java:87)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
        at android.app.ActivityThread.access$600(ActivityThread.java:130) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 


        The first pertinent line is D/OADB-HLPR: copyDatabaseFromAssets attempting to find asset databases/Shopper.lite



        This provides the path within the assets folder where the asset is expected to be found (in this example the filename is expected to be Shopper.lite in the databases subfolder/directory)



        The line D/OADB-HLPR: copyDatabaseFromAssets Did not locate asset databases/Shopper.lite reports that the asset file was not found.



        This is followed by the trapped exception (not the actual crash)



        Processing continues until the final crash as reported by :-



        E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.openassetdb/mjt.openassetdb.MainActivity}: java.lang.RuntimeException: No Database Available.






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 29 '18 at 8:17









        MikeTMikeT

        17.3k112643




        17.3k112643






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414789%2fandroid-sqlite-errorcopyingdatabase-error%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()