我寫了一個應用程序,它使用資產文件夾中現有數據庫的數據。用於複製和使用的數據我寫了下面的ExternalOpenDbHelper:如何將新列添加到Android應用程序中資產文件夾上的現有數據庫?
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;
}
}
在我的代碼檢查,如果數據被複制在手機上沒有再次複製,但是,如果沒有路徑上從資產文件夾複製和讀/寫在手機上覆制的數據庫。我不能在每次應用程序運行時從資產複製數據庫,因爲我只是在數據庫上寫入(//數據//數據//%s //數據庫//)。現在我需要在它的兩個表格上添加新的列,因爲我之前發佈它不喜歡最終用戶卸載並再次安裝應用程序。我嘗試搜索大量的工作,但找不到解決方案。我想如果我可以刪除數據(//數據//數據//%s //數據庫//)路徑可以做到這一點。
考慮使用https://github.com/jgilfelt/android-sqlite-asset-helper,而不是基於非常古老的博客文章的一些破碎的代碼。 – laalto 2014-08-31 10:44:54
謝謝,但我無法理解你的意思。你說我在我的代碼中選擇了錯誤的路徑,並且必須將其更改爲github上的代碼? – user3752236 2014-08-31 11:45:03