SQLiteOpenHelper不会从资产安装数据库文件

时间:2017-03-18 09:36:13

标签: java android sqliteopenhelper

安装应用程序时,不是从资产/数据库复制数据库文件并将其安装到设备上的应用程序目录中,而是创建一个在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安装嵌入式数据库。 有什么想法吗?

2 个答案:

答案 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/