Search code examples
androidandroid-cursoradapterandroid-cursorloader

CursorAdapter with database from assets


I want to use a database in my application, that was created in advance and then use a cursor loader to present the data from the db. First I copy the database from the assets folder according to this tutorial [http://goo.gl/1XS84] and then I want to use CursorLoader with CursorAdapter.

The CursorLoader though needs some query Uri of the database and I don´t know what URI I should specify. Any help?


Solution

  • Here is an excerpt how you can use your database from assets in a content provider.

    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) {
            }
        }
        ...
    

    Note: I would recommend doing I/O operations in a separate thread.