Обратите внимание
Код DatabseHelper , приведенный ниже, не включает методы getListProduct
и getProductById
для удобства.
Я считаю, что проблема должна была быть очевидна из журнала.Но в основном, если база данных не существует и вы копируете базу данных после того, как БД была открыта (без БД она не будет открыта, поэтому копирование не будет выполнено).
Ниже приведено исправление нескольких проблем.
Основная проблема - проверить, существует ли файл db в ожидаемом месте.то есть он не пытается открыть базу данных, но видит, существует ли файл.Если этого не произойдет, он скопировал базу данных до того, как будет предпринята попытка открыть ее, выполнив это при создании экземпляра DatabaseHelper.
Кроме того, открытие базы данных с использованием mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
приведет к открытию базы данных БЕЗпотенциал для запуска метода onUpgrade.То есть вы открыли базу данных не через подкласс SQLiteOpenHelper, поэтому она вам не поможет.
Возможно, проблема в том, что у вас есть <PackageName>
.Тем не менее, жесткое кодирование пути к базе данных может вызвать проблемы, поэтому путь определяется в соответствии с методом getDatabasePath для контекста (настоятельно рекомендуется использовать его, только если база данных не размещена где-либо в другом месте) .
Надеемся, что следующее позволит вам двигаться дальше.Примечание. Я настоятельно рекомендую удалить данные приложения, предварительно удалив его.
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "msgDb.db";
public static final String DBLOCATION = "/data/data/<PackageName>/databases/"; //<<<<<<<<< Shouldn't hard code path, really this package name????
private Context mContext;
private SQLiteDatabase mDatabase;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, 2);
this.mContext = context;
//<<<<<<<<<< Copy database if need be
if (!ifDBExists()) {
copyDatabase(context);
}
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("ONCREATE","WARNING!!!! onCreate method shopuldn't be invoked"); //<<<<<<<<<< ADDED
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion)
Log.d("ONUPGRADE","Attempting to copy database"); //<<<<<<<<<< ADDED
copyDatabase(mContext);
}
public void openDatabase() {
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if (mDatabase != null && mDatabase.isOpen()) {
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public void closeDatabase() {
if (mDatabase != null) {
mDatabase.close();
}
}
/**
* Check if the database file exists
* @return
*/
private boolean ifDBExists() {
File db = new File(mContext.getDatabasePath(DBNAME).getPath());
if (db.exists()) return true;
File dbdir = new File(db.getParent());
if (!dbdir.exists()) {
dbdir.mkdirs();
}
return false;
}
private boolean copyDatabase(Context context) {
Log.d("COPYDATABASE","Initiating copy of database");
try {
InputStream inputStream = context.getAssets().open(DatabaseHelper.DBNAME);
String outFileName = context.getDatabasePath(DBNAME).getAbsolutePath(); //<<<<<<<<<< CHANGED
//String outFileName = DatabaseHelper.DBLOCATION + DatabaseHelper.DBNAME; // relies on hard coded
int bytes_copied = 0;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[] buff = new byte[1024];
int length = 0;
while ((length = inputStream.read(buff)) > 0) {
outputStream.write(buff, 0, length);
}
outputStream.flush();
outputStream.close();
Log.d("MainActivity", "DB copied");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void logMsgCatTable() {
openDatabase();
Cursor csr = mDatabase.query("MSG_CAT",null,null,null,null,null, null );
DatabaseUtils.dumpCursor(csr);
}
}
- Обратите внимание, когда счастливы удалить сообщения журнала.
- Примечание также см. / Прочитать комментарии.
- ПРИМЕЧАНИЕ читать дальше, как естьвсе еще проблемы с вышеупомянутым
Запуск вышеупомянутого с очень простой MainActivity согласно: -
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHlpr = new DatabaseHelper(this);
mDBHlpr.logMsgCatTable();
}
}
Первый запуск: -
018-11-26 11:25:47.286 2597-2597/? D/COPYDATABASE: Initiating copy of database
2018-11-26 11:25:47.287 2597-2597/? D/MainActivity: DB copied
2018-11-26 11:25:47.302 2597-2597/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@9bd3b6b
2018-11-26 11:25:47.302 2597-2597/? I/System.out: 0 {
2018-11-26 11:25:47.302 2597-2597/? I/System.out: ID=1
2018-11-26 11:25:47.302 2597-2597/? I/System.out: COL1=mcat col1 001
2018-11-26 11:25:47.303 2597-2597/? I/System.out: COL2=mcat col2 001
2018-11-26 11:25:47.303 2597-2597/? I/System.out: }
2018-11-26 11:25:47.303 2597-2597/? I/System.out: <<<<<
- Примечание DBVERSION (иначе user_version в SQLite не задан / не троган)
Второй запуск: -
Как указано выше, ИСКЛЮЧИТЬ первые 2 сообщения в журнале (т.е. БД не скопированаКроме того, onUpgrade не запускался, так как для DBVERSION установлено значение 2).
Третий запуск
Добавлена еще одна строка в инструмент SQLite, скопирована БД обратно в папку активов, но не изменено значение user_version.После замены исходной БД на измененную БД и увеличения DBVERSION (super(context, DBNAME, null, 3);
): -
Как указано выше, не копируется обновленная БД, так как onUpgrade
не работает, поскольку вы обходите помощника.
Внесение изменений в код: -
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "msgDb.db";
public static final String DBLOCATION = "/data/data/<PackageName>/databases/"; //<<<<<<<<< Shouldn't hard code path, really this package name????
public static final int DBVERSION = 3; //<<<<<<<<<< ADDED STAGE 2
private Context mContext;
private SQLiteDatabase mDatabase;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION); //<<<<<<<<<<CHANGED STAGE2
this.mContext = context;
//<<<<<<<<<< Copy database if need be
if (!ifDBExists()) {
copyDatabase(context);
}
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("ONCREATE","WARNING!!!! onCreate method shopuldn't be invoked"); //<<<<<<<<<< ADDED
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion)
Log.d("ONUPGRADE","Attempting to copy database"); //<<<<<<<<<< ADDED
copyDatabase(mContext);
}
//<<<<<<<<<< CHANGED STAGE2 (checks the user_version, closes the DB does the copy, then opens the DB)
public void openDatabase() {
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if (mDatabase != null && mDatabase.isOpen()) {
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
if (mDatabase.getVersion() < DBVERSION) {
mDatabase.close();
copyDatabase(mContext);
mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
}
if(!mDatabase.isOpen()) {
Log.d("OPENDATABASE","For some reason the Database cannot be opened!!!!!!!!!! ");
}
}
public void closeDatabase() {
if (mDatabase != null) {
mDatabase.close();
}
}
/**
* Check if the database file exists
* @return
*/
private boolean ifDBExists() {
File db = new File(mContext.getDatabasePath(DBNAME).getPath());
if (db.exists()) return true;
File dbdir = new File(db.getParent());
if (!dbdir.exists()) {
dbdir.mkdirs();
}
return false;
}
private boolean copyDatabase(Context context) {
Log.d("COPYDATABASE","Initiating copy of database");
try {
InputStream inputStream = context.getAssets().open(DatabaseHelper.DBNAME);
String outFileName = context.getDatabasePath(DBNAME).getAbsolutePath(); //<<<<<<<<<< CHANGED
//String outFileName = DatabaseHelper.DBLOCATION + DatabaseHelper.DBNAME; // relies on hard coded
int bytes_copied = 0;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[] buff = new byte[1024];
int length = 0;
while ((length = inputStream.read(buff)) > 0) {
outputStream.write(buff, 0, length);
}
outputStream.flush();
outputStream.close();
Log.d("MainActivity", "DB copied");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void logMsgCatTable() {
openDatabase();
Cursor csr = mDatabase.query("MSG_CAT",null,null,null,null,null, null );
DatabaseUtils.dumpCursor(csr);
}
}
ПРИМЕЧАНИЕ Выше приведен код, который следует использовать в качестве основы для решения проблем.
Четвертый прогон: -
2018-11-26 12:03:28.984 3188-3188/so53468569.so53468569messages D/COPYDATABASE: Initiating copy of database
2018-11-26 12:03:28.985 3188-3188/so53468569.so53468569messages D/MainActivity: DB copied
2018-11-26 12:03:28.993 3188-3188/so53468569.so53468569messages I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@7edd361
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: 0 {
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: ID=1
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: COL1=mcat col1 001
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: COL2=mcat col2 001
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: }
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: 1 {
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: ID=2
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: COL1=mcat col1 002
2018-11-26 12:03:28.994 3188-3188/so53468569.so53468569messages I/System.out: COL2=mcat col2 002
2018-11-26 12:03:28.995 3188-3188/so53468569.so53468569messages I/System.out: }
2018-11-26 12:03:28.995 3188-3188/so53468569.so53468569messages I/System.out: <<<<<