This question already has answers here:
Ship an application with a database
(15 answers)
Closed 7 years ago.
I created a sqlite database (mydb.db) using sql browser
then I created assets folder in the android application and added the mydb.db file on it.
How to connect to this database?
I use this code, but it doesn't work properly.
SQLiteDatabase db;
db = openOrCreateDatabase("DataBase.db",
SQLiteDatabase.CREATE_IF_NECESSARY, null);
Cursor c = db.rawQuery("SELECT * FROM user", null);
c.moveToFirst();
while(!c.isAfterLast()) {
Toast.makeText(this, c.getString(0) + " " + c.getString(1), Toast.LENGTH_SHORT).show();
c.moveToNext();
}
db.close();
You can use SQLiteAssetHelper, which has all the code stuff that you need to install a pre-packaged database when your app is first run.
You cannot directly open files from assets folder. You have to copy the database-file of your assets folder into an internal/external storage and then use the File path to open the file.
Quick view into code sample for copy the database:
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("/data/data/(packagename)/databases /(datbasename).sqlite");
// transfer byte to inputfile to 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();
}
Now you can use the db like:
String mypath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE);
Related
I am using GreenDAO as ORM and using a pre-populated database which is encrypted by SQLite Cipher. Encryption is the feature of GreenDAO. So when a user launches the application I am using below code to copy the database from asset to phone memory.
ContextWrapper cw =new ContextWrapper(context);
if (android.os.Build.VERSION.SDK_INT >= 17) {
DB_PATH = cw.getApplicationInfo().dataDir + "/databases/";
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
byte[] buffer = new byte[1024];
OutputStream myOutput = null;
int length;
InputStream myInput = null;
try
{
myInput = mContext.getAssets().open(DB_NAME);
myOutput =new FileOutputStream(DB_PATH+ DB_NAME);
while((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
myOutput.close();
myOutput.flush();
myInput.close();
But on some device, it is showing following error
"Exception java.io.FileNotFoundException: /data/user/0/com.example.appname/databases/my-db.db: open failed: ENOENT (No such file or directory) "
and according to firebase crash report the below line is responsible for the error.
myOutput =new FileOutputStream(DB_PATH+ DB_NAME);
How can I solve this and can ensure that the database will work in all device. However I am using below code to check database exist or not
File file = new File(DB_PATH+ DB_NAME);
if(file.exists()) {
}
The directory
/data/user/0/com.example.appname/databases
does not exist yet.
Before you try to write a file in it check if the directory exists and if not create it.
if(file.getParentFile().exists())
if(!file.getParentFile().mkdirs())
return false.
I'm getting NullpointerException while trying to access db in Assets folder. And the db is indicated red in color on Assets folder.
Image containing Db in Assets
public void createdatabase() throws IOException
{
System.out.println(" came into Create database ");
//Open your local db as the input stream
InputStream myinput = mycontext.getAssets().open(DB_NAME);
System.out.println(" myinput = "+myinput.toString());
System.out.println(" Got input ");
// Path to the just created empty db
String outfilename = DB_PATH + DB_NAME;
System.out.println(" outfilename = "+outfilename);
//Open the empty db as the output stream
OutputStream myoutput = new FileOutputStream(outfilename);
// transfer byte to inputfile to outputfile
System.out.println(" created outputStream");
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();
}
Is there any way to check the db values in String?
DB_NAME does not match with the name of the file in assets folder.
Any reason why you did not tell the values?
I have copied database in Android Project folder and It is working fine. Now, I am inserting values in table. So I want to know that Is there anyway by which I can see those data using SqlLite Database Browser ???
Database in assets folder, I opened it but I can't see any new data.
My Code to insert data:, It is working fine, no errors.
public boolean SaveUserResponse(String QId, String OptionId,
String ResponseDate) {
try {
ContentValues cv = new ContentValues();
cv.put("QId", QId);
cv.put("OptionId", OptionId);
cv.put("ResponseDate", ResponseDate);
mDb.insert("tblUserResponse", null, cv);
Log.d("SaveUserResponse", "User Response has been Saved.");
return true;
} catch (Exception ex) {
Log.d("SaveUserResponse", ex.toString());
return false;
}
You can fetch your DB from device using DDMS (can be found under android-sdk\tools). There open Device -> File Explorer. Then navigate to data\data\your_app and pull your DB to a disk.
BTW, your DB shouldn't be placed under assets, here is a code how to copy it from assets (you can call it on the first run of your app):
void copyDataBase() throws IOException {
String DB_PATH = "/data/data/<app>/databases/";
String DB_NAME = "db.sqlite";
//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();
}
I am currently trying to access my database using my android phone however it doesn't work. It does work on the emulator. So I was wondering if I need to copy the data into my phone's internal memory by using
try{
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();
}catch(SQLiteException e){
Another issue is that I did not use "SQLiteOpenHelper", so does the above method still work? I simply did a
private final String DB_NAME = "MemberData";
private final String TABLE_NAME = "MemberDB";
sampleDB = this.openOrCreateDatabase(DB_NAME, MODE_PRIVATE, null);
Cursor c = sampleDB.rawQuery("SELECT companyNameEng FROM " +
TABLE_NAME + " ORDER BY companyNameEng ASC", null);
Yes, you must copy the db file out of the apk and into your apps database directory (or somewhere else that your app can access). The assets directory is not really a directory when the .apk file is created... it's just data that certain functions in the framework (getAssets()) know how to access. To allow other functions that expect a real path to work, you need to copy the data out to a proper directory on the device.
The usual destination for a database is "data/data/your.package.name/databases/".
Your method looks like will work fine... it is standard java io. SQLiteOpenHelper is more for helping you do upgrades and create new dbs. I always use one (never know if I'm going to change how I do things even if I don't need it initially), but you certainly don't have to.
Is it possible to supply prefilled SQLite DB to my app? I want to use db as ordinary SQLite db which will have tables filled manually and I want to include it into my .apk file.
Yes, include it in your assets folder and copy it into the /databases folder when your application first launches.
try this
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();
}
Including in the assets folder is one option (Apk size will be increased.)
How about storing the pre-filled db on any cloud storage service provider and downloading the file on the first run of the app?