日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android中使用SQLiteOpenHelper管理SD卡中的數(shù)據(jù)庫(kù)

 muyable 2013-12-11
使用Android中自帶的SQLiteOpenHelper可以完成數(shù)據(jù)庫(kù)的創(chuàng)建與管理,但有兩點(diǎn)局限:
(1)數(shù)據(jù)庫(kù)創(chuàng)建在內(nèi)存卡中,大小受限,創(chuàng)建位置位于/data/data/應(yīng)用程序名/databases中(可使用Eclispe的DDMS查看)。
(2)如果無(wú)法獲取Root權(quán)限,則無(wú)法直接查看創(chuàng)建的數(shù)據(jù)庫(kù)。
鑒于上述限制及實(shí)際需要,打算使用SQLiteOpenHelper管理SD卡上的數(shù)據(jù)庫(kù),通過(guò)研究SQLiteOpenHelper的源碼,發(fā)現(xiàn)其創(chuàng)建或打開(kāi)數(shù)據(jù)庫(kù)的代碼位于getWritableDatabase()函數(shù)中(getReadableDatabase本身也是調(diào)用了getWritableDatabase):
 if (mName == null) {
     db = SQLiteDatabase.create(null);
     } 
else {
     db = mContext.openOrCreateDatabase(mName, 0, mFactory);
     }

 分析上述代碼發(fā)現(xiàn),當(dāng)數(shù)據(jù)庫(kù)名字為非空時(shí),創(chuàng)建數(shù)據(jù)庫(kù)或打開(kāi)由mContext完成,這個(gè)mContext由SQLiteOpenHelper的構(gòu)造函數(shù)傳入:SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)。那么我們對(duì)于傳入的context,重載其openOrCreateDatabase函數(shù),使其將數(shù)據(jù)庫(kù)創(chuàng)建到SD卡中就可完成我們的目標(biāo)了~。

對(duì)應(yīng)的SQLiteOpenHelper實(shí)現(xiàn)類SdCardDBHelper
復(fù)制代碼
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * 數(shù)據(jù)庫(kù)管理和維護(hù)類
**/
public class SdCardDBHelper extends SQLiteOpenHelper{
    
    public static final String TAG = "SdCardDBHelper";
    /**
     * 數(shù)據(jù)庫(kù)名稱
    **/
    public static String DATABASE_NAME = "sddb.db";
    
    /**
     * 數(shù)據(jù)庫(kù)版本
    **/
    public static int DATABASE_VERSION = 1;
        
    /**
     * 構(gòu)造函數(shù)
     * 
     * @param    context 上下文環(huán)境
    **/
    public SdCardDBHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }    
     
    /**
     * 創(chuàng)建數(shù)據(jù)庫(kù)時(shí)觸發(fā),創(chuàng)建離線存儲(chǔ)所需要的數(shù)據(jù)庫(kù)表
     *
     * @param    db
    **/
    @Override
    public void onCreate(SQLiteDatabase db) {
         Log.e(TAG, "開(kāi)始創(chuàng)建數(shù)據(jù)庫(kù)表");
        try{
            //創(chuàng)建用戶表(user)
             db.execSQL("create table if not exists user" +
                     "(_id integer primary key autoincrement,name varchar(20),password varchar(20),role varchar(10),updateTime varchar(20))");
            Log.e(TAG, "創(chuàng)建離線所需數(shù)據(jù)庫(kù)表成功");
        }
        catch(SQLException se){
            se.printStackTrace();
            Log.e(TAG, "創(chuàng)建離線所需數(shù)據(jù)庫(kù)表失敗");
        }        
    }
    
    /** 更新數(shù)據(jù)庫(kù)時(shí)觸發(fā),
     *
     * @param    db
     * @param    oldVersion
     * @param    newVersion
    **/
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //db.execSQL("ALTER TABLE person ADD COLUMN other STRING");  
     }
}
復(fù)制代碼

 

重載的openOrCreateDatabase在sd卡上創(chuàng)建數(shù)據(jù)庫(kù)的Context

復(fù)制代碼
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;

/**
 * 用于支持對(duì)存儲(chǔ)在SD卡上的數(shù)據(jù)庫(kù)的訪問(wèn)
**/
public class DatabaseContext extends ContextWrapper {        
           
        /**
         * 構(gòu)造函數(shù)
         * @param    base 上下文環(huán)境
         */
        public DatabaseContext(Context base){
            super(base);
        }
     
        /**
         * 獲得數(shù)據(jù)庫(kù)路徑,如果不存在,則創(chuàng)建對(duì)象對(duì)象
         * @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卡不存在,請(qǐng)加載SD卡");
                return null;
            } 
            else{//如果存在
                //獲取sd卡路徑
                String dbDir=android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
                dbDir += "/database";//數(shù)據(jù)庫(kù)所在目錄
                String dbPath = dbDir+"/"+name;//數(shù)據(jù)庫(kù)路徑
                //判斷目錄是否存在,不存在則創(chuàng)建該目錄
                File dirFile = new File(dbDir);
                if(!dirFile.exists())
                    dirFile.mkdirs();
                
                //數(shù)據(jù)庫(kù)文件是否創(chuàng)建成功
                boolean isFileCreateSuccess = false; 
                //判斷文件是否存在,不存在則創(chuàng)建該文件
                File dbFile = new File(dbPath);
                if(!dbFile.exists()){
                    try {                    
                        isFileCreateSuccess = dbFile.createNewFile();//創(chuàng)建文件
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                else     
                    isFileCreateSuccess = true;
                
                //返回?cái)?shù)據(jù)庫(kù)文件對(duì)象
                if(isFileCreateSuccess)
                    return dbFile;
                else 
                    return null;
            }
        }
     
        /**
         * 重載這個(gè)方法,是用來(lái)打開(kāi)SD卡上的數(shù)據(jù)庫(kù)的,android 2.3及以下會(huì)調(diào)用這個(gè)方法。
         * 
         * @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會(huì)調(diào)用此方法獲取數(shù)據(jù)庫(kù)。
         * 
         * @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;
        }
    } 
復(fù)制代碼

 調(diào)用程序:

DatabaseContext dbContext = new DatabaseContext(this);
SdCardDBHelper dbHelper = new SdCardDBHelper(dbContext);

 

這里尤其值得注意的是,不同版本的android API會(huì)調(diào)用不同的openOrCreateDatabase函數(shù)。

當(dāng)然也可直接使用SQLiteDatabase創(chuàng)建SD卡上的數(shù)據(jù)庫(kù),或者直接修改SQLiteOpenHelper的源碼重新編譯,不過(guò)前者沒(méi)有對(duì)數(shù)據(jù)庫(kù)進(jìn)行一些檢驗(yàn)容錯(cuò)處理,也不及SQLiteOpenHelper對(duì)數(shù)據(jù)庫(kù)操作方便。后者工作量較大,不建議采用。
最后注意記得加入對(duì)SD卡的讀寫(xiě)權(quán)限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
SQLite桌面查看工具:sqlite administrator、sqlite man或者firefox插件sqlite manager等。
參考資料:

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多