【问题标题】:How to use preloaded SQLite database in Android from Assets如何通过 Assets 在 Android 中使用预加载的 SQLite 数据库
【发布时间】:2011-11-26 12:53:06
【问题描述】:

我想在我的应用程序中使用preloaded database 意味着尝试在安装 apk 时获取数据库,以便可以使用已保存在其中的数据。我复制 "ingredients.db" 资产文件夹中的文件。并使用以下代码 但这会得到错误 " Problem Copying Database From Resource File "

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

我的数据库助手类是这样的

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));
        }

【问题讨论】:

    标签: android sqlite android-assets


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      使用this solution,解决打开DB的问题。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • @Jazz-- 在 assets 文件夹或 DATABASE_NAME 中更改 .db 扩展名的位置
        • no no,当您从 sqlite manager 创建 db 文件时,将其保存为 dbname.sqlite(默认)。无需修改
        猜你喜欢
        • 2014-10-20
        • 1970-01-01
        • 2020-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        • 2012-08-25
        • 2014-02-19
        相关资源
        最近更新 更多