SQLite
系統自帶的SQLite是通過SQLiteOpenHelper實現的,而SQLiteOpenHelper是將數據庫存儲到/data/data/包名/databasas,這樣做的話在沒有root的手機上是沒法看到SQLite數據庫的。
所以,換種方式,將數據庫SQLite存儲到SD卡上。那麼跟其中相關聯的是getWritableDatabase方法。
if (mName == null) {
db = SQLiteDatabase.create(null);
}
else {
db = mContext.openOrCreateDatabase(mName, 0, mFactory);
}
分析上述代碼發現,當數據庫名字為非空時,創建數據庫或打開由mContext完成,這個mContext由SQLiteOpenHelper的構造函數傳入:SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)。那麼我們對於傳入的context,重載其openOrCreateDatabase函數,使其將數據庫創建到SD卡中就可完成我們的目標了。
重載Context
import java.io.File;
import java.io.IOException;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
public class DatabaseContext extends ContextWrapper {
public DatabaseContext(Context base){
super(base);
}
/**
* 獲得數據庫路徑,如果不存在,則創建對象對象
* @param name
* @param mode
* @param factory
*/
@Override
public File getDatabasePath(String name) {
//判斷是否存在sd卡
boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState());
if(!sdExist){//如果不存在,
Log.e("SD卡管理:", "SD卡不存在,請加載SD卡");
return null;
}
else{//如果存在
//獲取sd卡路徑
String dbDir=android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
dbDir += "/database";//數據庫所在目錄
String dbPath = dbDir+"/"+name;//數據庫路徑
//判斷目錄是否存在,不存在則創建該目錄
File dirFile = new File(dbDir);
if(!dirFile.exists())
dirFile.mkdirs();
//數據庫文件是否創建成功
boolean isFileCreateSuccess = false;
//判斷文件是否存在,不存在則創建該文件
File dbFile = new File(dbPath);
if(!dbFile.exists()){
try {
isFileCreateSuccess = dbFile.createNewFile();//創建文件
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
isFileCreateSuccess = true;
//返回數據庫文件對象
if(isFileCreateSuccess)
return dbFile;
else
return null;
}
}
/**
* 重載這個方法,是用來打開SD卡上的數據庫的,android 2.3及以下會調用這個方法。
*
* @param name
* @param mode
* @param factory
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
SQLiteDatabase.CursorFactory factory) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
return result;
}
/**
* Android 4.0會調用此方法獲取數據庫。
*
* @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String, int,
* android.database.sqlite.SQLiteDatabase.CursorFactory,
* android.database.DatabaseErrorHandler)
* @param name
* @param mode
* @param factory
* @param errorHandler
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
return result;
}
}
調用:
DatabaseContext dbContext = new DatabaseContext(this);
SdCardDBHelper dbHelper = new SdCardDBHelper(dbContext);
這裡尤其值得注意的是,不同版本的android API會調用不同的openOrCreateDatabase函數。
當然也可直接使用SQLiteDatabase創建SD卡上的數據庫,或者直接修改SQLiteOpenHelper的源碼重新編譯,不過前者沒有對數據庫進行一些檢驗容錯處理,也不及SQLiteOpenHelper對數據庫操作方便。後者工作量較大,不建議采用。
權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>