Проблема с кодом, который у вас есть, состоит в том, что многочисленные исключения перехватываются с помощью throws IOException
, а затем вы просто генерируете общее исключение.
Хотя может быть несколько основных причин.
Возможно, сам ресурс не существует там, где он ожидается (в папке ресурсов (например, не в каталоге database (SQLiteAssetHelper использует этот каталог))).
Можетбудь то, что папка базы данных , внутри пакета не существует (используйте mkdirs в DB_PATH).например, иметь что-то вроде: -
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;
}
- Обратите внимание на использование контекста getDatabasePath
Ниже приведен код, который очень длинный, но предоставляеточень полное ведение журнала (оно также обслуживает несколько баз данных (по умолчанию до 10) и также обслуживает каталоги в папке активов).
/**
* 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 3\u0000")) {
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;
}
}
}
Пример использования
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"}
);
}
}
Результат(когда базы данных не существуют): -
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.
(2-й)
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.