1

我想在我的应用程序中使用一个预先创建的数据库,然后使用游标加载器来呈现来自数据库的数据。首先,我根据本教程 [http://goo.gl/1XS84] 从 assets 文件夹中复制数据库,然后我想将 CursorLoader 与 CursorAdapter 一起使用。

CursorLoader 虽然需要一些数据库的查询 Uri,但我不知道我应该指定什么 URI。有什么帮助吗?

4

1 回答 1

2

以下是如何从内容提供商的资产中使用数据库的摘录。

public class MyProvider extends ContentProvider {

    private SQLiteOpenHelper mOpenHelper;
    ...

    private static class DatabaseHelper extends SQLiteOpenHelper {

        private static final String DATABASE_NAME = "database.db";
        private static final int DATABASE_VERSION = 1;
        private static final String SP_KEY_DB_VER = "db_ver";
        private final Context mContext;
            ...

        public DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            mContext = context;
            initialize();
        }

        /**
         * Initializes database. Creates database if doesn't exist.
         */
        private void initialize() {
            if (databaseExists()) {
                SharedPreferences prefs = PreferenceManager
                        .getDefaultSharedPreferences(mContext);
                int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
                if (DATABASE_VERSION != dbVersion) {
                    File dbFile = mContext.getDatabasePath(DATABASE_NAME);
                    if (!dbFile.delete()) {
                        Log.w(TAG, "Unable to update database");
                    }
                }
            }
            if (!databaseExists()) {
                createDatabase();
            }
        }

        /**
         * Returns true if database file exists, false otherwise.
         */
        private boolean databaseExists() {
            File dbFile = mContext.getDatabasePath(DATABASE_NAME);
            return dbFile.exists();
        }

        /**
         * Creates database by copying it from assets directory.
         */
        private void createDatabase() {
            String parentPath = mContext.getDatabasePath(DATABASE_NAME).getParent();
            String path = mContext.getDatabasePath(DATABASE_NAME).getPath();

            File file = new File(parentPath);
            if (!file.exists()) {
                if (!file.mkdir()) {
                    Log.w(TAG, "Unable to create database directory");
                    return;
                }
            }

            InputStream is = null;
            OutputStream os = null;
            try {
                is = mContext.getAssets().open(DATABASE_NAME);
                os = new FileOutputStream(path);

                byte[] buffer = new byte[1024];
                int length;
                while ((length = is.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }
                os.flush();
                SharedPreferences prefs = PreferenceManager
                        .getDefaultSharedPreferences(mContext);
                SharedPreferences.Editor editor = prefs.edit();
                editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
                editor.commit();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        }

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

注意:我建议在单独的线程中执行 I/O 操作。

于 2012-07-20T11:22:33.780 回答