標籤:var 通過 許可權 update class art base nal ora
假設使用預設的系統管理,預設放在包以下。比較省心。並且在卸載app後不會造成資料殘留。可是這樣也有一個問題。比方我做一個背單詞的軟體,那麼當使用者卸載掉這個app時,他辛辛苦苦下載的單詞庫也沒了...
所以我想到的解決方式。就是把資料庫路徑改下。不放到包以下,放到SD卡上。
細緻看看。還真不easy做,網上有人甚至去更改原始碼。只是最後還是找到瞭解決方式:
查看SQLiteOpenHelper原始碼。會發現有這樣一段代碼:
if (mName == null) { db = SQLiteDatabase.create(null); } else { db = mContext.openOrCreateDatabase(mName, 0, mFactory); }
能夠看到,當mName非空的時候。由mContext進行完畢建立和開啟。而這個mContext能夠通過建構函式傳入。
看下sqlliteOpenhelper這個實作類別:
package cn.com.xx.xx.util;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;/** * DataBase helper class * @author howlaa * @date 2015-1-5 14:38:28 */public class DBOpenHelper extends SQLiteOpenHelper {private static final String DBNAME = "test.db"; private static final int VERSION = 11;public DBOpenHelper(Context context) { super(context, DBNAME, null, VERSION);//it's location is data/data/pakage/database}@Overridepublic void onCreate(SQLiteDatabase db) {//It will be called when the database was created first db.execSQL("CREATE TABLE IF NOT EXISTS exam_type (id integer primary key autoincrement, type_name varchar(100), type_id INTEGER)"); }@Override // It'll be called when the database was updatedpublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
剩下的就要完畢這個mContext的實現了:
package cn.com.smartcost.scexam.util;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;/** * 用於支援對儲存在SD卡上的資料庫的訪問**/public class DatabaseContext extends ContextWrapper { /** * 建構函式 * @param base 上下文環境 */ 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().toString(); dbDir += "/scexam";//資料庫所在檔案夾 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);
最後不要忘記,加上讀寫SD卡的許可權:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Android使用sqlliteOpenhelper更改資料庫的儲存路徑放到SD卡上