如何在Assets中使用Android中预加载的SQLite数据库

时间:2011-11-26 12:53:06

标签: android sqlite android-assets

我想在我的应用程序中使用preloaded database意味着在安装apk时尝试获取数据库,因此可以使用已保存在其中的数据。我复制“ingredients.db” 资产文件夹中的文件。并使用以下代码 但这会出现错误“问题从资源文件复制数据库”

我该如何解决这个问题? 请建议我尽可能的方式

我的数据库帮助程序类就是那个

class IngredientHelper extends SQLiteOpenHelper {
        private static final String DATABASE_PATH = "/data/data/com.example.preloadeddatabase/databases/";
        private static final String DATABASE_NAME = "ingredients.db";

        private static final String TABLE_NAME = "Ingredients";
        private static final String COLUMN_ID = "_id";
        private static final String COLUMN_TITLE = "ingredient_name";

        private static final int SCHEMA_VERSION = 1;

        public SQLiteDatabase dbSqlite;
        private final Context myContext;

        public IngredientHelper(Context context) {
            super(context, DATABASE_NAME, null, SCHEMA_VERSION);
            this.myContext = context;

        }

        @Override
        public void onCreate(SQLiteDatabase db) {

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        }

        public void createDatabase() {

            createDB();
        }

        public void createDB() {

            boolean dbExist = DbExists();

            if (!dbExist) {
                this.getReadableDatabase();
                copyDataBase();

            }
        }

        private boolean DbExists() {
            SQLiteDatabase db = null;
            try {
                String databasePath = DATABASE_PATH + DATABASE_NAME;
                db = SQLiteDatabase.openDatabase(databasePath, null,
                        SQLiteDatabase.OPEN_READWRITE);

                db.setLocale(Locale.getDefault());
                db.setLockingEnabled(true);
                db.setVersion(1);

            }

            catch (SQLiteException e) {
                Log.e("SqlHelper", "Database Not Found");
            }

            if (db != null) {
                db.close();
            }

            return db != null ? true : false;
        }

        private void copyDataBase() {
            InputStream iStream = null;
            OutputStream oStream = null;
            String outFilePath = DATABASE_PATH + DATABASE_NAME;
            try {
                iStream = myContext.getAssets().open(DATABASE_NAME);
                oStream = new FileOutputStream(outFilePath);
                byte[] buffer = new byte[2048];
                int length;
                while ((length = iStream.read(buffer)) > 0) {
                    oStream.write(buffer, 0, length);
                }
                oStream.flush();
                oStream.close();
                iStream.close();
            }

            catch (IOException e) {
                throw new Error("Problem Copying Database From Resource File");
            }
        }

        public void openDatabase() throws SQLException {

            String myPath = DATABASE_PATH + DATABASE_NAME;
            dbSqlite = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READWRITE);
        }

        @Override
        public synchronized void close() {

            if (dbSqlite != null) {
                dbSqlite.close();
            }
            super.close();

        }

        public Cursor getCursor() {
            SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
            queryBuilder.setTables(TABLE_NAME);
            String[] asColumnsToReturn = new String[] { COLUMN_ID, COLUMN_TITLE };

            Cursor mCursor = queryBuilder.query(dbSqlite, asColumnsToReturn,
                    null, null, null, null, "ingredient_name ASC");

            return mCursor;
        }

        public String getName(Cursor c) {
            return (c.getString(1));
        }

3 个答案:

答案 0 :(得分:2)

在将资源文件复制到数据库目录之前,请勿打开可读数据库。您可能正在尝试写入已打开的文件(因为在调用getReadableDatabase()时它会被打开),因此您可能会收到异常。

答案 1 :(得分:1)

这是你问题的simple solution,但在这种方法中有一个错误。当你使用方法this.getReadableDatabase();时,数据库是打开的,即它应该关闭this.close(); 此错误对HTC Desire设备尤为重要

使用this solution,解决了打开数据库的问题。

答案 2 :(得分:0)

数据库文件必须具有扩展名“.sqlite”而不是“.db”