Обновление предварительно заполненной базы данных в Android - PullRequest
1 голос
/ 16 ноября 2010

Я потерял последние 3 часа, пытаясь это сделать. Я делаю приложение, которое будет поставляться с БД, заполненной заполненными таблицами, которые не будут меняться на клиентских устройствах. Мне удалось сделать это, поместив его в папку активов и скопировав его в виде потока байтов в соответствующую папку данных на телефоне. Проблема в том, что когда я хочу обновить базу данных, я не могу заставить ее работать. Я удаляю БД в папке данных на телефоне (из кода), но копирование новой базы данных всегда завершается неудачей, или скопированная БД имеет соответствующий размер, но в ней нет таблиц. Как это сделать? Или есть более простой способ? Могу ли я открыть БД напрямую из ресурсов (это будет самый простой способ, если это возможно, но я не могу найти, как получить доступ к пути к ресурсам из кода)?

1 Ответ

4 голосов
/ 03 декабря 2010

Вот код, который я использую:

public class DataBaseHelper extends SQLiteOpenHelper {

    private static final String DB_PATH = "/data/data/com.project.mydb/databases/";
    private static final String DB_NAME = "mydb.db";
    private static final String DB_TABLE = "words";
    private static final int DB_VERSION = 6;
    private static final String TAG = "DataBaseHelper";
    int id = 0;
    Random random = new Random();
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    public DataBaseHelper(Context context){
        super(context, DB_NAME, null, DB_VERSION);
        this.myContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        createDB();
    }

    @Override
    public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion){
        Log.w(TAG, "Upgrading DB from version " + oldVersion + " to " +
                newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
        onCreate(db);
    }

    public void createDataBase(){
        createDB();
    }

    private void createDB(){
        boolean dbExist = dbExists();
        if(!dbExist){
            copyDataBase();
        }
        else if(dbExist){
            copyDataBase();
        }
    }

    private boolean dbExists(){
        SQLiteDatabase db = null;
        try{
            String dbPath = DB_PATH + DB_NAME;
            db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
            db.setLocale(Locale.getDefault());
            db.setLockingEnabled(true);
            db.setVersion(DB_VERSION);
        }
        catch(SQLiteException e){
            Log.e("SQL Helper", "database not found");
        }
        if(db != null){
            db.close();
        }
        return db != null ? true : false;
    }

    private void copyDataBase(){
        InputStream iStream = null;
        OutputStream oStream = null;
        String outFilePath = DB_PATH + DB_NAME;
        try{
            iStream = myContext.getAssets().open(DB_NAME);
            oStream = new FileOutputStream(outFilePath);
            byte[] buffer = new byte[1024];
            int length;
            while((length = iStream.read(buffer))>0){
                oStream.write(buffer,0,length);
            }
            oStream.flush();
            oStream.close();
            iStream.close();
        }
        catch(IOException ioe){
            throw new Error("Problem copying database from resource file.");
        }
    }

    public void openDataBase() throws SQLException {
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }

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