安装应用程序时,不是从资产/数据库复制数据库文件并将其安装到设备上的应用程序目录中,而是创建一个在DBHelper类中指定相同名称的空数据库。
创建的Sqlite文件具有相同的名称,但它只包含一个名为android_metadata的表,其中包含名为android_metadata的行。我知道这是因为我使用Device Monitor检索了文件。
之前一切正常,资产中的数据库自动安装然后突然开始发生。
DBHelper:
public class DBHelper extends SQLiteOpenHelper {
private static String TAG = "DBHelper";
private static final String DB_PATH = "/data/data/com.borehog.express.bhexpress/databases/";
private static String DB_NAME = "BHMock.db";
private static int DB_VERSION = 1;
private static DBHelper db;
private static Context context;
/**
* Constructor should be private to prevent direct instantiation.
* Make a call to the static method "getInstance()" instead.
*/
private DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
public static synchronized DBHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
if (db == null) {
db = new DBHelper(context.getApplicationContext());
}
Log.d(TAG, "getInstance()");
return db;
}
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
this.context = context;
Log.d(TAG, "DBHelper() Init");
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
if(dbExist()) {
Log.d(TAG, "DB Exists");
}
Log.d(TAG, "onCreate()");
} catch (Exception ex) {
Log.d(TAG, "onCreate: " + ex.getMessage());
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Log.d(TAG, "onUpgrade()");
} catch (Exception ex) {
Log.d(TAG, "onUpgrade: " + ex.getMessage());
}
}
}
我像这样初始化数据库:
db = DBHelper.getInstance(getApplicationContext());
但由于某种原因,它不是从Assets安装嵌入式数据库。 有什么想法吗?
答案 0 :(得分:-1)
这是满足您需求的最佳方式。
像这样使用:
public class DbAdapter {
private static final String TAG = DbAdapter.class.getSimpleName();
public static Context context;
public static DataBaseHelper DBHelper;
public static SQLiteDatabase mDb;
private static String DB_PATH = "";
private static final String DATABASE_NAME = "BHMock.sqlite";
private static final String ASSETS_DATABASE_NAME = "BHMock.sqlite";
private static final int DATABASE_VERSION = 1;
/**
* This is singleton pattern means : There is one instance of DBHelper in
* all application : If object created then it will return old instance : If
* not then create new DBHelper instance
*/
public DbAdapter(Context ctx) {
context = ctx;
if (DBHelper == null) {
DBHelper = new DataBaseHelper(context);
}
}
/**
* This is database helper class where all db table is created and
* drop if there is any update
*/
public static class DataBaseHelper extends SQLiteOpenHelper {
private DataBaseHelper(Context mcontext) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DB_PATH = context.getApplicationInfo().dataDir + "/databases/"+DATABASE_NAME;
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/"+DATABASE_NAME;
}
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.e(TAG, "onCreate Database");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Log.e(TAG, "Upgrading database from version " + oldVersion
+ " to " + newVersion);
// we want both updates, so no break statement here...
switch (oldVersion) {
case 1:
case 2:
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
// If database not exists copy it from the assets
public void CopyAndCreateDataBase() throws IOException {
boolean mDataBaseExist = checkDataBase();
if (!mDataBaseExist) {
this.getReadableDatabase();
this.getWritableDatabase();
this.close();
try {
// Copy the database from assests
copyDataBase();
String mPath = DB_PATH + DATABASE_NAME ;
Log.v(TAG, "Database created : " + mPath);
} catch (IOException mIOException) {
throw new Error("ErrorCopyingDataBase");
}
}
}
// Check that the database exists here: /data/data/your package/databases/DatabaseName
private boolean checkDataBase() {
File dbFile = new File(DB_PATH + DATABASE_NAME);
Log.e(Constants.TAG, dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
// Copy the database from assets
private void copyDataBase() throws IOException {
InputStream mInput = context.getAssets().open(ASSETS_DATABASE_NAME);
String outFileName = DB_PATH + DATABASE_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();
}
public static void copyDatabaseToSdCard() {
try {
File f1 = new File(DB_PATH);
if (f1.exists()) {
File f2 = new File(Environment
.getExternalStorageDirectory().getAbsoluteFile()
+ "/" + DATABASE_NAME);
f2.createNewFile();
InputStream in = new FileInputStream(f1);
OutputStream out = new FileOutputStream(f2);
byte[] buf = new byte[2048];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public synchronized void close() {
if (mDb != null)
mDb.close();
super.close();
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
}
}
// opens the database
public synchronized SQLiteDatabase openDatabase() throws SQLException {
if (mDb == null) {
mDb = DBHelper.getWritableDatabase();
Log.e(Constants.TAG, "Database opened");
}
return mDb;
}
// close the database
public synchronized void closeDatabase() {
// db.setTransactionSuccessful();
// db.endTransaction();
DBHelper.close();
}
public synchronized void exit() {
try {
if (DBHelper != null)
DBHelper = null;
if (mDb != null) {
mDb.close();
mDb = null;
}
Log.e(TAG, "dbhelper : " + DBHelper + " Db " + mDb);
} catch (Exception e) {
e.printStackTrace();
}
}
}
并致电
DbAdapter mAdapter = new DbAdapter(this);
如果您需要任何帮助,请参阅此example
答案 1 :(得分:-1)
You can use this code, It is working in my app
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class SqlLiteDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "mydb.sqlite";
private static final String DB_PATH_SUFFIX = "/databases/";
static Context ctx;
public SqlLiteDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
ctx = context;
}
public ArrayList<Contact> getDetails() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<Contact> contList = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT * FROM demo", null);
if (cursor != null) {
while (cursor.moveToNext()) {
Contact cont = new Contact(cursor.getInt(0), cursor.getString(1), cursor.getString(2));
contList.add(cont);
}
cursor.close();
db.close();
}
return contList;
}
public void CopyDataBaseFromAsset() throws IOException {
InputStream myInput = ctx.getAssets().open(DATABASE_NAME);
// Path to the just created empty db
String outFileName = getDatabasePath();
// if the path doesn't exist first, create it
File f = new File(ctx.getApplicationInfo().dataDir + DB_PATH_SUFFIX);
if (!f.exists())
f.mkdir();
// 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();
}
private static String getDatabasePath() {
return ctx.getApplicationInfo().dataDir + DB_PATH_SUFFIX
+ DATABASE_NAME;
}
public SQLiteDatabase openDataBase() throws SQLException {
File dbFile = ctx.getDatabasePath(DATABASE_NAME);
if (!dbFile.exists()) {
try {
CopyDataBaseFromAsset();
System.out.println("Copying sucess from Assets folder");
} catch (IOException e) {
throw new RuntimeException("Error creating source database", e);
}
}
return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.CREATE_IF_NECESSARY);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
For more details visit this link
http://androideve.com/2017/02/android-read-sqlite-databse-assets-folder/