我是Android SQLite的新手。这就是我所拥有的:
db.sqlite
文件夹中有assets
。db.sqlite
将被替换为新的数据库(我将从项目中删除旧文件并添加新文件)。我关心的是:
这就是我扩展SQLiteOpenHelper课程的方法。我按照我在互联网上找到的教程:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DataBaseHelper extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.mydomain.myapp/databases/";
private static String DB_NAME = "db.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;
/*
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
**/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
Log.i("myapp", "database already exist");
}else{
Log.i("myapp", "database NOT exist");
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* 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{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
@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) {
}
// My public helper methods to access and get content from the database go here
答案 0 :(得分:32)
您无法替换onUpgrade()
中的数据库,因为在此方法中数据库已在使用中。您必须在数据库打开之前执行此操作,就像在DatabaseHelper
的构造函数中一样。由于您无法使用onUpgrade()
,因此您必须自行管理数据库版本控制。使用SharedPreferences
是一种很好的方式。检查数据库是否存在(如果已从assets
目录复制)并检查数据库是否存在。现在,您可以删除旧数据库并从assets
复制新数据库。
见下面的实现。
标记更新后的应用程序是使用assets
中的新数据库发布的,只是DATABASE_VERSION
常量。{/ p>
private static class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 1;
private static final String SP_KEY_DB_VER = "db_ver";
private final Context mContext;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
initialize();
}
/**
* Initializes database. Creates database if doesn't exist.
*/
private void initialize() {
if (databaseExists()) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(mContext);
int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
if (DATABASE_VERSION != dbVersion) {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
if (!dbFile.delete()) {
Log.w(TAG, "Unable to update database");
}
}
}
if (!databaseExists()) {
createDatabase();
}
}
/**
* Returns true if database file exists, false otherwise.
* @return
*/
private boolean databaseExists() {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
return dbFile.exists();
}
/**
* Creates database by copying it from assets directory.
*/
private void createDatabase() {
String parentPath = mContext.getDatabasePath(DATABASE_NAME).getParent();
String path = mContext.getDatabasePath(DATABASE_NAME).getPath();
File file = new File(parentPath);
if (!file.exists()) {
if (!file.mkdir()) {
Log.w(TAG, "Unable to create database directory");
return;
}
}
InputStream is = null;
OutputStream os = null;
try {
is = mContext.getAssets().open(DATABASE_NAME);
os = new FileOutputStream(path);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.commit();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
}
}
答案 1 :(得分:0)
经过多次搜索。我发现这个资产文件夹数据库是只读的。您无法更新资产文件夹中的数据库。假设您的下一个应用版本在google play商店中发布,并在assert文件夹中使用新的更新数据库。如果断言中两个数据库的名称相同(在以前的应用程序和新应用程序中),则android系统将仅读取旧数据库文件。因为文件系统不能包含两个具有相同名称的文件。 您需要做的只是在dataOpenhelper.class中更改新数据库文件名的名称。像database_1.db。
public class DatabaseOpenHelper extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "dbbasic_5.db";
private static final int DATABASE_VERSION = 3;
private Context contaxtDB;
// ********* reminder **********
// only change database_name = like dbbasic_5.6.7.8 .
// ******* do not change database_version
//
public DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
contaxtDB = context;
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
}
}
答案 2 :(得分:0)
这个工作正常,试试吧
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 3;
private static final String SP_KEY_DB_VER = "db_ver";
private static final String DATABASE_NAME = "db.db";
private static String DB_PATH = "/data/data/APP_PACKAGE/databases/";
static SQLiteDatabase db;
public Context context;
SessionManager session;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
session = SessionManager.getInstance(context);;
//initialize();
}
public void createDataBase() throws IOException {
if (!checkDataBase()) {
getWritableDatabase();
copyDataBase();
}
}
public boolean checkDataBase() {
/**/
boolean found = new File(DB_PATH + DATABASE_NAME).exists();
if(found)
{
int dbVersion = Integer.valueOf(session.getData(SP_KEY_DB_VER, "1"));
if (DATABASE_VERSION != dbVersion) {
File dbFile = context.getDatabasePath(DATABASE_NAME);
if (!dbFile.delete()) {
Log.w("Warning: ", "Unable to update database");
}
found = false;
}
}
return found;
}
public void copyDataBase() throws IOException {
InputStream myInput = this.context.getAssets().open(DATABASE_NAME);
OutputStream myOutput = new FileOutputStream(DB_PATH + DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
session.saveData(SP_KEY_DB_VER, String.valueOf(DATABASE_VERSION));
//int dbVersion = prefs.in(SP_KEY_DB_VER, 3);
}
public void openDataBase() throws SQLException {
db = SQLiteDatabase.openDatabase(DB_PATH + DATABASE_NAME, null, 0);
}
}
MainActivity - >的OnCreate
db = new DatabaseHelper(context);
try {
db.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
db.openDataBase();