Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
162 views
in Technique[技术] by (71.8m points)

android - Is it possible to move the internal DB to the SDCard?

As the database in my app grows, it is going to require more and more of the internal phone space. There isn't any sensitive/private data in the DB, so I'm interested in moving it to the SD card.

I'm using SQLiteOpenHelper to assist with the database work. It's my understanding that you can't use this for DB-access on the SD card as you can't define the DB path. However, there are some (very poor) examples on the Internet that suggest you can override this limitation. However I've never gotten one of those code samples to compile.

Is it possible? And if so--HOW! Please note that Froyo's "apps on SD card" feature won't work as it doesn't move internal files.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Just use:

SQLiteDatabase.openDatabase(DB_FULL_PATH, null, SQLiteDatabase.OPEN_READONLY);

where DB_FULL_PATH can be a path to your sdcard, like /sdcard/mydatabase.db

Edit:

This is what I call in my application to access the database....

private static DBUtil dbHelper = null;

public void openDatabase() {
    if(dbHelper == null) {
        dbHelper = new DBUtil(this.context);
        dbHelper.openDataBase(SQLiteDatabase.OPEN_READWRITE);
    }
}
public void closeDatabase() {
    if(dbHelper != null) {
        dbHelper.close();
        dbHelper = null;
    }
}

... and this is the db helper class I'm using, which in fact extends SQLiteOpenHelper, so you will still have everything you want from this class.

package com.myapp.android.db;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.myapp.android.MyApp;

import java.io.IOException;

/**
 * Standard database utility class.
 * 
 * TODO: Refactor.
 */
public class DBUtil extends SQLiteOpenHelper {

    /**
     * Database directory.
     * 
     * <p>
     * Example: "/sdcard/myapp/db/"
     * </p>
     */
    public static String DB_DIRECTORY = null;

    /**
     * Name of the database file.
     * 
     * <p>
     * Example: "mydatabase.db"
     * </p>
     * 
     */
    public static String DB_NAME = null;

    /**
     * Full absolute path of the database.
     * 
     * <p>
     * Example: "/sdcard/myapp/db/mydatabase.db"
     * </p>
     */
    public static String DB_FULL_PATH = null;
    static {
        DB_DIRECTORY = MyApp.DATA_REPOSITORY_URI + "/myapp/db/";
        DB_NAME = "mydatabase.db";
        DB_FULL_PATH = DB_DIRECTORY + DB_NAME;
    }

    private SQLiteDatabase myDataBase;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     * 
     * @param context
     */
    public DBUtil(Context context) {
        super(context, DB_NAME, null, 1);

        try {
            this.createDataBase();
        } catch (IOException ioe) {
            throw new Error("Unable to create database");
        }
    }

    /**
     * Creates a empty database on the system and rewrites it with your own
     * database.
     * */
    public void createDataBase() throws IOException {        
        if (!checkDataBase()) this.getWritableDatabase();
    }

    /**
     * Check if the database already exist to avoid re-copying the file each
     * time you open the application.
     * 
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            checkDB = SQLiteDatabase.openDatabase(DB_FULL_PATH, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            // database does't exist yet.
        }
        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    public void openDataBase(int mode) throws SQLException {        
        try {
            myDataBase = SQLiteDatabase.openDatabase(DB_FULL_PATH, null, mode);
        } catch(IllegalStateException e) {
            // Sometimes, esp. after application upgrade, the database will be non-closed, raising a IllegalStateException
            // below. Try to avoid by simply opening it again.
            Log.d(MyApp.APP, "Database non-closed. Reopening.");
            myDataBase = SQLiteDatabase.openDatabase(DB_FULL_PATH, null, mode);
        }
    }

    public void openDataBase() throws SQLException {
        openDataBase(SQLiteDatabase.OPEN_READWRITE);
    }

    public SQLiteDatabase getDb() {
        return myDataBase;
    }

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

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...