今天我們來說說SQLite,小書學到兩種方法,一種是繼承SQLiteOpenHelper實作,一種是利用Java的I/O來處理(關於儲存方法,可以參考這裡,是這篇的翻譯。),分別封裝成class。
首先是利用SQLiteOpenHelper實作的class,亦或可以參考這裡:
會覺得怪怪的嗎?
沒錯,這個class沒有辦法把SQLite放到SD卡中,該怎麼做呢?目前已知有兩解,如果還有錯請指正。
然而,說回頭的第二種方法,就是先在assets中建立一個空的.db3檔,然後
對它進行存取操作,注意裡面的context.getAssets().open(DATABASE_FILENAME)方法,
它便是獲取assets之中的檔案,複製到SD卡之中的資料夾(如果沒有則創建):
然後,老師有說過,可以學SQL語句,再利用.execSQL()來代替android裡面的調用方法。
有關SQL語句可以參考這個、或是這個。
最後附上原本的SQLiteOpenHelper.class:
最後注意別忘記加上權限呀!
首先是利用SQLiteOpenHelper實作的class,亦或可以參考這裡:
/*
參考:
http://www.moke.tw/wordpress/computer/advanced/249
http://www.moke.tw/wordpress/computer/advanced/238
http://www.moke.tw/wordpress/computer/advanced/245
*/
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class SQLite extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "moke_config.db"; //資料庫名稱
private static final int DATABASE_VERSION = 1; //資料庫版本
private SQLiteDatabase db;
public SQLite(Context context) { //建構子
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String DATABASE_CREATE_TABLE =
"create table config ("
+ "_ID INTEGER PRIMARY KEY,"
+ "name TEXT,"
+ "value INTEGER"
+ ");";
//建立config資料表,詳情請參考SQL語法
db.execSQL(DATABASE_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//oldVersion=舊的資料庫版本;newVersion=新的資料庫版本
db.execSQL("DROP TABLE IF EXISTS config"); //刪除舊有的資料表
onCreate(db);
}
// 取得所有記錄
public Cursor getAll() {
return db.rawQuery("SELECT * FROM table_name", null);
}
// 取得所有記錄
public Cursor getAll() {
return db.query("table_name", //資料表名稱
new String[] {"_ID", "name", "value"}, //欄位名稱
null, // WHERE
null, // WHERE 的參數
null, // GROUP BY
null, // HAVING
null // ORDOR BY
);
}
// 取得一筆紀錄
public Cursor get(long rowId) throws SQLException {
Cursor cursor = db.query(true,
"table_name", //資料表名稱
new String[] {"_ID", "name", "value"}, //欄位名稱
"_ID=" + rowId, //WHERE
null, // WHERE 的參數
null, // GROUP BY
null, // HAVING
null, // ORDOR BY
null // 限制回傳的rows數量
);
// 注意:不寫會出錯
if (cursor != null) {
cursor.moveToFirst(); //將指標移到第一筆資料
}
return cursor;
}
//新增一筆記錄,成功回傳rowID,失敗回傳-1
public long create(String name, String value) {
ContentValues args = new ContentValues();
args.put("name", name);
args.put("value", value);
return db.insert("table_name", null, args);
}
//修改記錄,回傳成功修改筆數
public int update(long rowId, String value) {
ContentValues args = new ContentValues();
args.put("value", value);
return db.update("table_name", //資料表名稱
args, //VALUE
"_ID=" + rowId, //WHERE
null //WHERE的參數
);
}
}
會覺得怪怪的嗎?
沒錯,這個class沒有辦法把SQLite放到SD卡中,該怎麼做呢?目前已知有兩解,如果還有錯請指正。
將apk設定安裝在SD卡中。4/2後來發現沒這回事:
可以直接在上述的那個class中,將DATABASE_NAME改為:
就可以啦!哈哈!有關確定手機是否有安裝SD卡,參考這裡。static final String DATABASE = android.os.Environment .getExternalStorageDirectory().getAbsolutePath() +"/檔案名稱.db3";
- 或是參考下面的code,用它來取代我們之前繼承的 SQLiteOpenHelper :
import java.io.File;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
/**
* A helper class to manage database creation and version management.
* You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
* optionally {@link #onOpen}, and this class takes care of opening the database
* if it exists, creating it if it does not, and upgrading it as necessary.
* Transactions are used to make sure the database is always in a sensible state.
* <p>For an example, see the NotePadProvider class in the NotePad sample application,
* in the <em>samples/</em> directory of the SDK.</p>
*/
public abstract class SDSQLiteOpenHelper {
private static final String TAG = SDSQLiteOpenHelper.class.getSimpleName();
private final Context mContext;
private final String mName;
private final CursorFactory mFactory;
private final int mNewVersion;
private SQLiteDatabase mDatabase = null;
private boolean mIsInitializing = false;
/**
* Create a helper object to create, open, and/or manage a database.
* The database is not actually created or opened until one of
* {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
*
* @param context to use to open or create the database
* @param name of the database file, or null for an in-memory database
* @param factory to use for creating cursor objects, or null for the default
* @param version number of the database (starting at 1); if the database is older,
* {@link #onUpgrade} will be used to upgrade the database
*/
public SDSQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
mContext = context;
mName = name;
mFactory = factory;
mNewVersion = version;
}
/**
* Create and/or open a database that will be used for reading and writing.
* Once opened successfully, the database is cached, so you can call this
* method every time you need to write to the database. Make sure to call
* {@link #close} when you no longer need it.
*
* <p>Errors such as bad permissions or a full disk may cause this operation
* to fail, but future attempts may succeed if the problem is fixed.</p>
*
* @throws SQLiteException if the database cannot be opened for writing
* @return a read/write database object valid until {@link #close} is called
*/
public synchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
throw new IllegalStateException("getWritableDatabase called recursively");
}
// If we have a read-only database open, someone could be using it
// (though they shouldn't), which would cause a lock to be held on
// the file, and our attempts to open the database read-write would
// fail waiting for the file lock. To prevent that, we acquire the
// lock on the read-only database, which shuts out other users.
boolean success = false;
SQLiteDatabase db = null;
try {
mIsInitializing = true;
if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
String path = getDatabasePath(mName).getPath();
db = SQLiteDatabase.DatabopenOrCreatease(path, mFactory);
}
int version = db.getVersion();
if (version != mNewVersion) {
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
onUpgrade(db, version, mNewVersion);
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
success = true;
return db;
} finally {
mIsInitializing = false;
if (success) {
if (mDatabase != null) {
try { mDatabase.close(); } catch (Exception e) { }
}
mDatabase = db;
} else {
if (db != null) db.close();
}
}
}
/**
* Create and/or open a database. This will be the same object returned by
* {@link #getWritableDatabase} unless some problem, such as a full disk,
* requires the database to be opened read-only. In that case, a read-only
* database object will be returned. If the problem is fixed, a future call
* to {@link #getWritableDatabase} may succeed, in which case the read-only
* database object will be closed and the read/write object will be returned
* in the future.
*
* @throws SQLiteException if the database cannot be opened
* @return a database object valid until {@link #getWritableDatabase}
* or {@link #close} is called.
*/
public synchronized SQLiteDatabase getReadableDatabase() {
if (mDatabase != null && mDatabase.isOpen()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
throw new IllegalStateException("getReadableDatabase called recursively");
}
try {
return getWritableDatabase();
} catch (SQLiteException e) {
if (mName == null) throw e; // Can't open a temp database read-only!
Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);
}
SQLiteDatabase db = null;
try {
mIsInitializing = true;
String path = getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READWRITE);
if (db.getVersion() != mNewVersion) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + path);
}
onOpen(db);
Log.w(TAG, "Opened " + mName + " in read-only mode");
mDatabase = db;
return mDatabase;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) db.close();
}
}
/**
* Close any open database object.
*/
public synchronized void close() {
if (mIsInitializing) throw new IllegalStateException("Closed during initialization");
if (mDatabase != null && mDatabase.isOpen()) {
mDatabase.close();
mDatabase = null;
}
}
public File getDatabasePath(String name)
{
return new File("/sdcard/" + name);
}
/**
* Called when the database is created for the first time. This is where the
* creation of tables and the initial population of the tables should happen.
*
* @param db The database.
*/
public abstract void onCreate(SQLiteDatabase db);
/**
* Called when the database needs to be upgraded. The implementation
* should use this method to drop tables, add tables, or do anything else it
* needs to upgrade to the new schema version.
*
* <p>The SQLite ALTER TABLE documentation can be found
* <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns
* you can use ALTER TABLE to insert them into a live table. If you rename or remove columns
* you can use ALTER TABLE to rename the old table, then create the new table and then
* populate the new table with the contents of the old table.
*
* @param db The database.
* @param oldVersion The old database version.
* @param newVersion The new database version.
*/
public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
/**
* Called when the database has been opened.
* Override method should check {@link SQLiteDatabase#isReadOnly} before
* updating the database.
*
* @param db The database.
*/
public void onOpen(SQLiteDatabase db) {}
}
然而,說回頭的第二種方法,就是先在assets中建立一個空的.db3檔,然後
對它進行存取操作,注意裡面的context.getAssets().open(DATABASE_FILENAME)方法,
它便是獲取assets之中的檔案,複製到SD卡之中的資料夾(如果沒有則創建):
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class DataBasePlus {
private static final String TAG = "DatabasePlus";//做Log用
private SQLiteDatabase db;
/** {"column1","colume2","column3"} */
public static final String[] COLUMN_LIST = { "column1","colume2","column3" };//欄位的列表
private final String DATABASE_TABLE = "table";//table,如果有需要做兩個以上的table,可增加成為array
public static final String DATABASE_PATH = android.os.Environment
.getExternalStorageDirectory().getAbsolutePath() + "/Doubt";//路徑,標示了到SD卡資料夾的絕對路徑
public static final String DATABASE_NAME = "GiRu.db3";//database的檔案名稱
private Context context;
public DataBasePlus(Context context) {
this.context = context;
Log.d(TAG, "public DataBaseTwins().");
}
/**開啟SQLite使用*/
public synchronized boolean openSQLite() {
if (isDataBaseOpen()) {
Log.d(TAG, "it's already open.");
return false;
}
db = openDatabase(DATABASE_NAME);
Log.d(TAG, "database is not open!.");
return true;
}
private SQLiteDatabase openDatabase(String DATABASE_FILENAME) {
String databaseFilename;
databaseFilename = DATABASE_PATH + "/" + DATABASE_FILENAME;
File dir = new File(DATABASE_PATH);
if (!dir.exists()) {
Log.d(TAG, "file of dir is not exists.");
dir.mkdir();
}
if ((!(new File(databaseFilename)).exists())) {
Log.d(TAG, "SQlite is not exists.");
InputStream is;
FileOutputStream fos;
try {
Log.d(TAG, "context.getAssets().open(DATABASE_FILENAME);.");
is = context.getAssets().open(DATABASE_FILENAME);
Log.d(TAG, "new FileOutputStream(databaseFilename).");
fos = new FileOutputStream(databaseFilename);
byte[] buffer = new byte[1024];
int count = 0;
while ((count = is.read(buffer)) > 0) {
Log.d(TAG, "write..");
fos.write(buffer, 0, count);
}
Log.d(TAG, "close().");
fos.close();
is.close();
} catch (IOException e) {
Log.e(TAG, "fail for IOException.");
e.printStackTrace();
}
} else {
Log.d(TAG, "SQlte is already exists.");
}
db = SQLiteDatabase.openOrCreateDatabase(databaseFilename, null);
return db;
}
public synchronized boolean add(ContentValues cv) {
Log.d(TAG, "add()");
if (isDataBaseOpen()) {
Log.d(TAG, "DataBase is open.");
return db.insert(DATABASE_TABLE, null, cv) > 0;
}
return false;
}
public synchronized Cursor quary(String column, String term) {
Cursor cursor = null;
if (isDataBaseOpen()) {
cursor = db.query(this.DATABASE_TABLE, DataBasePlus.COLUMN_LIST,
column + "=?", new String[] { term }, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
}
return cursor;
}
public synchronized Cursor quaryAll() {
Cursor cursor = null;
if (isDataBaseOpen()) {
cursor = db.query(this.DATABASE_TABLE, DataBasePlus.COLUMN_LIST,
null, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
}
return cursor;
}
public synchronized boolean close() throws SQLException {
if (isDataBaseOpen()) {
db.close();
Log.d(TAG, "db.close()");
return true;
}
return false;
}
public synchronized boolean clearAll() {
Log.d(TAG, "clearAll()");
if (isDataBaseOpen()) {
try {
Log.d(TAG, "clearAll(),isOpen, prepare to clear");
return db.delete(DATABASE_TABLE, null, null) > 0;
} catch (SQLException e) {
Log.e(TAG, "fail for SQLException.");
}
}
Log.d(TAG, "database is not open.");
return false;
}
public synchronized boolean isDataBaseOpen() throws SQLException {
if ((db == null) || (!db.isOpen())) {
return false;
}
return true;
}
}
然後,老師有說過,可以學SQL語句,再利用.execSQL()來代替android裡面的調用方法。
有關SQL語句可以參考這個、或是這個。
最後附上原本的SQLiteOpenHelper.class:
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.database.sqlite;
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.DefaultDatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
/**
* A helper class to manage database creation and version management.
*
* <p>You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
* optionally {@link #onOpen}, and this class takes care of opening the database
* if it exists, creating it if it does not, and upgrading it as necessary.
* Transactions are used to make sure the database is always in a sensible state.
*
* <p>This class makes it easy for {@link android.content.ContentProvider}
* implementations to defer opening and upgrading the database until first use,
* to avoid blocking application startup with long-running database upgrades.
*
* <p>For an example, see the NotePadProvider class in the NotePad sample application,
* in the <em>samples/</em> directory of the SDK.</p>
*
* <p class="note"><strong>Note:</strong> this class assumes
* monotonically increasing version numbers for upgrades.</p>
*/
public abstract class SQLiteOpenHelper {
private static final String TAG = SQLiteOpenHelper.class.getSimpleName();
private final Context mContext;
private final String mName;
private final CursorFactory mFactory;
private final int mNewVersion;
private SQLiteDatabase mDatabase = null;
private boolean mIsInitializing = false;
private final DatabaseErrorHandler mErrorHandler;
/**
* Create a helper object to create, open, and/or manage a database.
* This method always returns very quickly. The database is not actually
* created or opened until one of {@link #getWritableDatabase} or
* {@link #getReadableDatabase} is called.
*
* @param context to use to open or create the database
* @param name of the database file, or null for an in-memory database
* @param factory to use for creating cursor objects, or null for the default
* @param version number of the database (starting at 1); if the database is older,
* {@link #onUpgrade} will be used to upgrade the database; if the database is
* newer, {@link #onDowngrade} will be used to downgrade the database
*/
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
this(context, name, factory, version, new DefaultDatabaseErrorHandler());
}
/**
* Create a helper object to create, open, and/or manage a database.
* The database is not actually created or opened until one of
* {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
*
* <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
* used to handle corruption when sqlite reports database corruption.</p>
*
* @param context to use to open or create the database
* @param name of the database file, or null for an in-memory database
* @param factory to use for creating cursor objects, or null for the default
* @param version number of the database (starting at 1); if the database is older,
* {@link #onUpgrade} will be used to upgrade the database
* @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
* corruption.
*/
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
DatabaseErrorHandler errorHandler) {
if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
if (errorHandler == null) {
throw new IllegalArgumentException("DatabaseErrorHandler param value can't be null.");
}
mContext = context;
mName = name;
mFactory = factory;
mNewVersion = version;
mErrorHandler = errorHandler;
}
/**
* Return the name of the SQLite database being opened, as given tp
* the constructor.
*/
public String getDatabaseName() {
return mName;
}
/**
* Create and/or open a database that will be used for reading and writing.
* The first time this is called, the database will be opened and
* {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
* called.
*
* <p>Once opened successfully, the database is cached, so you can
* call this method every time you need to write to the database.
* (Make sure to call {@link #close} when you no longer need the database.)
* Errors such as bad permissions or a full disk may cause this method
* to fail, but future attempts may succeed if the problem is fixed.</p>
*
* <p class="caution">Database upgrade may take a long time, you
* should not call this method from the application main thread, including
* from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
*
* @throws SQLiteException if the database cannot be opened for writing
* @return a read/write database object valid until {@link #close} is called
*/
public synchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// darn! the user closed the database by calling mDatabase.close()
mDatabase = null;
} else if (!mDatabase.isReadOnly()) {
return mDatabase; // The database is already open for business
}
}
if (mIsInitializing) {
throw new IllegalStateException("getWritableDatabase called recursively");
}
// If we have a read-only database open, someone could be using it
// (though they shouldn't), which would cause a lock to be held on
// the file, and our attempts to open the database read-write would
// fail waiting for the file lock. To prevent that, we acquire the
// lock on the read-only database, which shuts out other users.
boolean success = false;
SQLiteDatabase db = null;
if (mDatabase != null) mDatabase.lock();
try {
mIsInitializing = true;
if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
}
int version = db.getVersion();
if (version != mNewVersion) {
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
success = true;
return db;
} finally {
mIsInitializing = false;
if (success) {
if (mDatabase != null) {
try { mDatabase.close(); } catch (Exception e) { }
mDatabase.unlock();
}
mDatabase = db;
} else {
if (mDatabase != null) mDatabase.unlock();
if (db != null) db.close();
}
}
}
/**
* Create and/or open a database. This will be the same object returned by
* {@link #getWritableDatabase} unless some problem, such as a full disk,
* requires the database to be opened read-only. In that case, a read-only
* database object will be returned. If the problem is fixed, a future call
* to {@link #getWritableDatabase} may succeed, in which case the read-only
* database object will be closed and the read/write object will be returned
* in the future.
*
* <p class="caution">Like {@link #getWritableDatabase}, this method may
* take a long time to return, so you should not call it from the
* application main thread, including from
* {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
*
* @throws SQLiteException if the database cannot be opened
* @return a database object valid until {@link #getWritableDatabase}
* or {@link #close} is called.
*/
public synchronized SQLiteDatabase getReadableDatabase() {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// darn! the user closed the database by calling mDatabase.close()
mDatabase = null;
} else {
return mDatabase; // The database is already open for business
}
}
if (mIsInitializing) {
throw new IllegalStateException("getReadableDatabase called recursively");
}
try {
return getWritableDatabase();
} catch (SQLiteException e) {
if (mName == null) throw e; // Can't open a temp database read-only!
Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);
}
SQLiteDatabase db = null;
try {
mIsInitializing = true;
String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY,
mErrorHandler);
if (db.getVersion() != mNewVersion) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + path);
}
onOpen(db);
Log.w(TAG, "Opened " + mName + " in read-only mode");
mDatabase = db;
return mDatabase;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) db.close();
}
}
/**
* Close any open database object.
*/
public synchronized void close() {
if (mIsInitializing) throw new IllegalStateException("Closed during initialization");
if (mDatabase != null && mDatabase.isOpen()) {
mDatabase.close();
mDatabase = null;
}
}
/**
* Called when the database is created for the first time. This is where the
* creation of tables and the initial population of the tables should happen.
*
* @param db The database.
*/
public abstract void onCreate(SQLiteDatabase db);
/**
* Called when the database needs to be upgraded. The implementation
* should use this method to drop tables, add tables, or do anything else it
* needs to upgrade to the new schema version.
*
* <p>The SQLite ALTER TABLE documentation can be found
* <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns
* you can use ALTER TABLE to insert them into a live table. If you rename or remove columns
* you can use ALTER TABLE to rename the old table, then create the new table and then
* populate the new table with the contents of the old table.
*
* @param db The database.
* @param oldVersion The old database version.
* @param newVersion The new database version.
*/
public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
/**
* Called when the database needs to be downgraded. This is stricly similar to
* onUpgrade() method, but is called whenever current version is newer than requested one.
* However, this method is not abstract, so it is not mandatory for a customer to
* implement it. If not overridden, default implementation will reject downgrade and
* throws SQLiteException
*
* @param db The database.
* @param oldVersion The old database version.
* @param newVersion The new database version.
*/
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
throw new SQLiteException("Can't downgrade database from version " +
oldVersion + " to " + newVersion);
}
/**
* Called when the database has been opened. The implementation
* should check {@link SQLiteDatabase#isReadOnly} before updating the
* database.
*
* @param db The database.
*/
public void onOpen(SQLiteDatabase db) {}
}
最後注意別忘記加上權限呀!
沒有留言:
張貼留言
你好,我是小書,如果文章內容有錯誤,或是看到有建議以及任何感想時,歡迎提出分享,我們一起學習一起努力。