How to use an existing database with an Android application
本问题已经有最佳答案,请猛点这里访问。
我已经创建了一个SQLite数据库。 我想在我的Android项目中使用这个数据库文件。 我想将此数据库与我的应用程序捆绑在一起。
应用程序如何才能访问此数据库并将其用作数据库,而不是创建新数据库?
注意:
在尝试此代码之前,请在以下代码中找到以下行:
1 |
这里的DB_NAME是您的数据库的名称。假设您在assets文件夹中有一个数据库副本,例如,如果您的数据库名称是ordersDB,那么DB_NAME的值将是ordersDB,
1 |
将数据库保存在assets文件夹中,然后按照以下步骤操作:
DataHelper类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.content.Context; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DataBaseHelper extends SQLiteOpenHelper { private static String TAG ="DataBaseHelper"; // Tag just for the LogCat window //destination path (location) of our database on device private static String DB_PATH =""; private static String DB_NAME ="YourDbName";// Database name private SQLiteDatabase mDataBase; private final Context mContext; public DataBaseHelper(Context context) { super(context, DB_NAME, null, 1);// 1? Its database Version if(android.os.Build.VERSION.SDK_INT >= 17){ DB_PATH = context.getApplicationInfo().dataDir +"/databases/"; } else { DB_PATH ="/data/data/" + context.getPackageName() +"/databases/"; } this.mContext = context; } public void createDataBase() throws IOException { //If the database does not exist, copy it from the assets. boolean mDataBaseExist = checkDataBase(); if(!mDataBaseExist) { this.getReadableDatabase(); this.close(); try { //Copy the database from assests copyDataBase(); Log.e(TAG,"createDatabase database created"); } catch (IOException mIOException) { throw new Error("ErrorCopyingDataBase"); } } } //Check that the database exists here: /data/data/your package/databases/Da Name private boolean checkDataBase() { File dbFile = new File(DB_PATH + DB_NAME); //Log.v("dbFile", dbFile +" "+ dbFile.exists()); return dbFile.exists(); } //Copy the database from assets private void copyDataBase() throws IOException { InputStream mInput = mContext.getAssets().open(DB_NAME); String outFileName = DB_PATH + DB_NAME; OutputStream mOutput = new FileOutputStream(outFileName); byte[] mBuffer = new byte[1024]; int mLength; while ((mLength = mInput.read(mBuffer))>0) { mOutput.write(mBuffer, 0, mLength); } mOutput.flush(); mOutput.close(); mInput.close(); } //Open the database, so we can query it public boolean openDataBase() throws SQLException { String mPath = DB_PATH + DB_NAME; //Log.v("mPath", mPath); mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); return mDataBase != null; } @Override public synchronized void close() { if(mDataBase != null) mDataBase.close(); super.close(); } } |
编写一个DataAdapter类,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import java.io.IOException; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.util.Log; public class TestAdapter { protected static final String TAG ="DataAdapter"; private final Context mContext; private SQLiteDatabase mDb; private DataBaseHelper mDbHelper; public TestAdapter(Context context) { this.mContext = context; mDbHelper = new DataBaseHelper(mContext); } public TestAdapter createDatabase() throws SQLException { try { mDbHelper.createDataBase(); } catch (IOException mIOException) { Log.e(TAG, mIOException.toString() +" UnableToCreateDatabase"); throw new Error("UnableToCreateDatabase"); } return this; } public TestAdapter open() throws SQLException { try { mDbHelper.openDataBase(); mDbHelper.close(); mDb = mDbHelper.getReadableDatabase(); } catch (SQLException mSQLException) { Log.e(TAG,"open >>"+ mSQLException.toString()); throw mSQLException; } return this; } public void close() { mDbHelper.close(); } public Cursor getTestData() { try { String sql ="SELECT * FROM myTable"; Cursor mCur = mDb.rawQuery(sql, null); if (mCur!=null) { mCur.moveToNext(); } return mCur; } catch (SQLException mSQLException) { Log.e(TAG,"getTestData >>"+ mSQLException.toString()); throw mSQLException; } } } |
现在您可以使用它:
1 2 3 4 5 6 7 | TestAdapter mDbHelper = new TestAdapter(urContext); mDbHelper.createDatabase(); mDbHelper.open(); Cursor testdata = mDbHelper.getTestData(); mDbHelper.close(); |
编辑:感谢JDx
对于Android  4.1(Jelly Bean),更改:
1 | DB_PATH ="/data/data/" + context.getPackageName() +"/databases/"; |
至:
1 | DB_PATH = context.getApplicationInfo().dataDir +"/databases/"; |
在DataHelper类中,此代码适用于JB 4.2多用户。
如果您有预先构建的数据库而不是将其复制到asset文件夹中并创建一个新类作为DataBaseHelper来实现SQLiteOpenHelper
比使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import java.io.File; 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.SQLiteOpenHelper; public class DataBaseHelperClass extends SQLiteOpenHelper{ //The Android's default system path of your application database. private static String DB_PATH ="/data/data/package_name/databases/"; // Data Base Name. private static final String DATABASE_NAME ="DBName.sqlite"; // Data Base Version. private static final int DATABASE_VERSION = 1; // Table Names of Data Base. static final String TABLE_Name ="tableName"; public Context context; static SQLiteDatabase sqliteDataBase; /** * Constructor * Takes and keeps a reference of the passed context in order to access to the application assets and resources. * @param context * Parameters of super() are 1. Context * 2. Data Base Name. * 3. Cursor Factory. * 4. Data Base Version. */ public DataBaseHelperClass(Context context) { super(context, DATABASE_NAME, null ,DATABASE_VERSION); this.context = context; } /** * Creates a empty database on the system and rewrites it with your own database. * 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. * */ public void createDataBase() throws IOException{ //check if the database exists boolean databaseExist = checkDataBase(); if(databaseExist){ // Do Nothing. }else{ this.getWritableDatabase(); copyDataBase(); }// end if else dbExist } // end createDataBase(). /** * 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 */ public boolean checkDataBase(){ File databaseFile = new File(DB_PATH + DATABASE_NAME); return databaseFile.exists(); } /** * 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 transferring byte stream. * */ private void copyDataBase() throws IOException{ //Open your local db as the input stream InputStream myInput = context.getAssets().open(DATABASE_NAME); // Path to the just created empty db String outFileName = DB_PATH + DATABASE_NAME; //Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(outFileName); //transfer bytes from the input file to the output file 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(); } /** * This method opens the data base connection. * First it create the path up till data base of the device. * Then create connection with data base. */ public void openDataBase() throws SQLException{ //Open the database String myPath = DB_PATH + DATABASE_NAME; sqliteDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); } /** * This Method is used to close the data base connection. */ @Override public synchronized void close() { if(sqliteDataBase != null) sqliteDataBase.close(); super.close(); } /** * Apply your methods and class to fetch data using raw or queries on data base using * following demo example code as: */ public String getUserNameFromDB(){ String query ="select User_First_Name From"+TABLE_USER_DETAILS; Cursor cursor = sqliteDataBase.rawQuery(query, null); String userName = null; if(cursor.getCount()>0){ if(cursor.moveToFirst()){ do{ userName = cursor.getString(0); }while (cursor.moveToNext()); } } return userName; } @Override public void onCreate(SQLiteDatabase db) { // No need to write the create table query. // As we are using Pre built data base. // Which is ReadOnly. } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // No need to write the update table query. // As we are using Pre built data base. // Which is ReadOnly. // We should not update it as requirements of application. } } |
希望对你有帮助...
关于这个问题,我遇到了其他DatabaseHelpers的麻烦,不知道为什么
这对我有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG = DatabaseHelper.class.getSimpleName(); private final Context context; private final String assetPath; private final String dbPath; public DatabaseHelper(Context context, String dbName, String assetPath) throws IOException { super(context, dbName, null, 1); this.context = context; this.assetPath = assetPath; this.dbPath ="/data/data/" + context.getApplicationContext().getPackageName() +"/databases/" + dbName; checkExists(); } /** * Checks if the database asset needs to be copied and if so copies it to the * default location. * * @throws IOException */ private void checkExists() throws IOException { Log.i(TAG,"checkExists()"); File dbFile = new File(dbPath); if (!dbFile.exists()) { Log.i(TAG,"creating database.."); dbFile.getParentFile().mkdirs(); copyStream(context.getAssets().open(assetPath), new FileOutputStream( dbFile)); Log.i(TAG, assetPath +" has been copied to" + dbFile.getAbsolutePath()); } } private void copyStream(InputStream is, OutputStream os) throws IOException { byte buf[] = new byte[1024]; int c = 0; while (true) { c = is.read(buf); if (c == -1) break; os.write(buf, 0, c); } is.close(); os.close(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } |
如果您已有数据库,请将其保存在资产文件夹中并将其复制到应用程序中。有关更多详细信息,请参阅Android数据库基础。
您可以使用内容提供商执行此操作。应用程序中使用的每个数据项对应用程序保持私有。如果应用程序想要跨应用程序共享数据,则只有使用内容提供程序实现此目的的技术,内容提供程序提供访问该私有数据的接口。