我编写了一个使用资产文件夹中现有数据库中数据的应用程序。复制和使用数据我在ExternalOpenDbHelper后写了:
public class ExternalDbOpenHelper extends SQLiteOpenHelper {
public static String DB_PATH;
private static String TABALE_NAME = "font";
private static String FONT_ID = "_id";
private static String FONT_TYPE = "font_type";
private static String FONT_SIZE = "font_size";
private static String POEM_TABLE = "poem";
private static String POEM_ID = "_id";
private static String READ_POINT = "read_point";
private static String BOOKMARK = "bookmark";
public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;
private static final int DATABASE_VERSION = 2;
public SQLiteDatabase getDb() {
return database;
}
public ExternalDbOpenHelper(Context context, String databaseName) {
super(context, databaseName, null, DATABASE_VERSION);
this.context = context;
String packageName = context.getPackageName();
DB_PATH = String.format("//data//data//%s//databases//", packageName);
DB_NAME = databaseName;
openDataBase();
}
public void createDataBase() {
boolean dbExist = checkDataBase();
if (!dbExist) {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Log.e(this.getClass().toString(), "Copying error");
throw new Error("Error copying database!");
}
} else {
Log.i(this.getClass().toString(), "Database already exists");
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String path = DB_PATH + DB_NAME;
checkDb = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLException e) {
Log.e(this.getClass().toString(), "Error while checking db");
}
if (checkDb != null) {
checkDb.close();
}
return checkDb != null;
}
private void copyDataBase() throws IOException {
InputStream externalDbStream = context.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream localDbStream = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = externalDbStream.read(buffer)) > 0) {
localDbStream.write(buffer, 0, bytesRead);
}
localDbStream.close();
externalDbStream.close();
}
public SQLiteDatabase openDataBase() throws SQLException {
String path = DB_PATH + DB_NAME;
if (database == null) {
createDataBase();
database = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READWRITE);
}
return database;
}
@Override
public synchronized void close() {
if (database != null) {
database.close();
}
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE cat ADD point BOOLEAN NOT NULL DEFAULT 0;");
db.execSQL("ALTER TABLE poem ADD read_point BOOLEAN NOT NULL DEFAULT false;");
db.execSQL("ALTER TABLE poem ADD bookmark INTEGER NOT NULL DEFAULT 0;");
}
}
public int updateFont(int i, String fontName, int p) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues font = new ContentValues();
font.put(FONT_TYPE, fontName);
font.put(FONT_SIZE, p);
String whereClause = FONT_ID + " LIKE ?";
String[] whereArgs = new String[] { String.valueOf(i) };
return db.update(TABALE_NAME, font, whereClause, whereArgs);
}
public void updateReadPoint(int poemId, int readPointTeransfer) {
SQLiteDatabase db = this.getWritableDatabase();
String whereClause;
String[] whereArgs;
if (poemId != readPointTeransfer) {
ContentValues readPoint = new ContentValues();
readPoint.put(READ_POINT, Boolean.toString(true));
whereClause = POEM_ID + " LIKE ?";
whereArgs = new String[] { String.valueOf(poemId) };
db.update(POEM_TABLE, readPoint, whereClause, whereArgs);
if (readPointTeransfer != -1) {
readPoint.put(READ_POINT, Boolean.toString(false));
whereArgs = new String[] { String.valueOf(readPointTeransfer) };
db.update(POEM_TABLE, readPoint, whereClause, whereArgs);
}
}
}
public void updateBookmarkList(int i, String idOfThisPoem) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues bookmarkValue = new ContentValues();
String whereClause = POEM_ID + " LIKE ?";
String[] whereArgs = new String[] { idOfThisPoem };
if (i == 0) {
bookmarkValue.put(BOOKMARK, Integer.toString(0));
db.update(POEM_TABLE, bookmarkValue, whereClause, whereArgs);
} else if (i == 1) {
bookmarkValue.put(BOOKMARK, Integer.toString(1));
db.update(POEM_TABLE, bookmarkValue, whereClause, whereArgs);
}
}
public boolean bookmarkStatus(String idOfThisPoem){
String idOfThisBookmarkedPoem = null;
Boolean iconFull = null;
String[] tableColumns = new String[] { POEM_ID, BOOKMARK };
String whereClause = POEM_ID + " LIKE ?";
String[] whereArgs = new String[] { idOfThisPoem };
Cursor poetCursor = database.query(POEM_TABLE, tableColumns,
whereClause, whereArgs, null, null, POEM_ID);
poetCursor.moveToFirst();
if (!poetCursor.isAfterLast()) {
do {
idOfThisBookmarkedPoem = poetCursor.getString(1);
} while (poetCursor.moveToNext());
}
poetCursor.close();
if (Integer.valueOf(idOfThisBookmarkedPoem) == 0) {
iconFull = false;
} else if (Integer.valueOf(idOfThisBookmarkedPoem) == 1) {
iconFull = true;
}
return iconFull;
}
}
在我的代码中,我检查了手机上是否复制了数据,请勿再次复制,但如果路径上没有,则从资产文件夹中复制并在手机上复制的数据库上读/写。每次app运行时我都无法从资产中复制数据库,因为我只是在数据库上写(// data // data //%s // databases //)。现在我需要在它的两个表上添加新列,因为我发布它之前不喜欢最终用户卸载并再次安装应用程序。我尝试搜索大量工作,但找不到解决方案。我想如果我可以删除数据(//数据//数据//%s //数据库//)路径可以正确执行。
答案 0 :(得分:0)
如何在android app中的资产文件夹中将新列添加到现有数据库?
您无法修改资产。
欢迎您通过调用execSQL()
对象上的SQLiteDatabase
并执行ALTER TABLE
语句来修改数据库的本地副本。
我赞同laalto的评论:请use SQLiteAssetHelper
。除此之外,它还为您提供了多种向现有数据库添加新列的方法。
答案 1 :(得分:0)
您需要对数据库进行版本控制。换句话说,当您打开数据库时,您似乎无法对当前版本进行任何检查。
例如,您定义当前版本:
public static final int DATABASE_VERSION = 1;
但是,您必须添加首选项(SharedPreferences
)或类似内容,以便在安装数据库时保存用户设备上安装的数据库版本。然后在以后的更新中,您可以更改版本并添加代码以将DB更新为新版本。由于您尚未完成此操作,因此您还需要检查未找到版本的情况。
要执行升级,请使用ExternalDbOpenHelper
构造函数或类似openDataBase
甚至checkDataBase
的方法,通过使用当前数据库版本调用onUpgrade
进行版本检查,已安装的数据库版本。
像这样:
onUpgrade(database, settings.getInt(OLD_DB_VERSION, 0), DATABASE_VERSION);
您还必须记住在执行更新或新安装发生后保存新的数据库版本。