I'm having a problem with deleting the SQLite file from my application.
I'm using the code as follows:
File file = new File("data/data/" + context.getPackageName() + "/databases/*****");
d = file.delete();
DbAdapter dba = new DbAdapter(context);
dba.open();
dba.close();
Before this, I was using the method context.deleteDatabase(DATABASE_NAME) to do this.
The problem is: after I run this method, the application does not refresh, I have the old database and I am able to do deletes, inserts, etc.
On both cases I have to restart my application to see the new database.
Sometimes, after to run the method, when I try to access some methods that need the database, the app crashes with an error that I have no database and after restart, the new database is created.
What do I do?
EDIT
I have a big system. My database have 26 tables and a lot of constraingns.
It's easier to delete the database and recreate it.
EDIT2
DbAdapter dba = new DbAdapter(context);
SQLiteDatabase sqlite = dba.open();
dba.close();
boolean d = context.deleteDatabase("CarroramaBD");
dba.open();
dba.close();
Im did close the db.
Why doing this
instead you can drop the tables in your db and recreate them which is far more practical than deleting the file.
And as for your views that store old values you can refresh the whole activity by calling this code
public void refrehs_me()
{
Intent intent = getIntent();
finish();
startActivity(intent);
}
Edit : Just a thought passed my mind regarding the creation of the new DB, On the creation of your app a DB file will be created, you make a copy of that file like DB2, and when you delete the DB instead of trying to create a new one just copy back DB2 as DB and so on with each deletion process.
And for the copy - here is the code by #Rakshi
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
Related
I want to copy the data from CSV file to SQLite file for my android application.SQLite table structure i.e. the columns are different than the CSV file columns. There are more columns in the CSV file. I am trying to use DB Browser For SQLite software.
Is it possible to copy data through these this Application or should I be writing some code to do that? Can anyone please suggest?
I would like to suggest using SQLite Studio for importing CSV data and create an SQLite database file from that CSV file. You can find the details here. You can also do that from your command line argument as shown in the link provided.
$ sqlite3 mydb // This creates a new database
.mode csv // Enable to import from the csv
.import c:/sqlite/city.csv cities // import a csv file and create a table having the column name same as found in the first row of your csv file
Once you have got your SQLite database, you can now add, drop or modify columns and their names using the database queries.
Once you have prepared the database, you can put this database file in the asset directory of your Android Studio project and while launching the application, copy the database from your asset directory into your local storage so that it can be accessed by your Android application. I am attaching a sample code for copying database file from the asset directory to your internal storage.
private void copyFromAssetsAndCreateDatabase() {
InputStream mInputStream;
private String DB_PATH = "/data/data/" + "your.application.package.goes.here" + "/databases/";
try {
mInputStream = getApplicationContext().getAssets().open(YOUR_DATABASE_NAME);
File dir = new File(DataHelper.DB_PATH);
if (!dir.exists()) dir.mkdir();
File f = new File(DataHelper.DB_PATH + YOUR_DATABASE_NAME);
if (!f.exists()) {
f.createNewFile();
}
OutputStream mOutput = new FileOutputStream(f);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInputStream.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Hope that helps!
The main way is Read File like this:
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
Get title of the columns:
String dataA = br.readLine();
String[] eachLineA = dataA.split(",");
Read line by line :
while ((dataA = br.readLine()) != null)
Split and Remove " from each cell,
fitData.add(eachLineA[i].replaceAll("\"", ""));
Finally add to database
myDb.addHandler(fitData.get(0), fitData.get(1), fitData.get(2), fitData.get(3), fitData.get(4));
This is a while loop:
while ((dataA = br.readLine()) != null) {
while (way && dataA != null) {
eachLineA = dataA.split(",");//
if (eachLineA.length < leA && fitData.size() < leA) {
way = true;
dataA = br.readLine();
} else way = false;
for (int i = 1; i <= eachLineA.length - 1; i++) {
fitData.add(eachLineA[i].replaceAll("\"", ""));
Log.i("Tag", "N:" + i);
}
}
myDb.addHandler(
fitData.get(0), fitData.get(1), fitData.get(2), fitData.get(3), fitData.get(4)
);
fitData.clear();
way = true;
}
If the columns in your CSV file don't map into the columns in your SQLite table then you need to do some data transformation first i.e. reduce the number of columns to the number of columns in your table, and name them accordingly.
Then you can use the built-in CSV importer to import the data.
Open a terminal and launch a sqlite prompt.
Set mode to csv
sqlite> .mode csv
Import the data from your csv file with the following command:
sqlite> .import c:/path/to/your/file/use/forward/slashes destination_table_name
This is a really good tutorial. http://www.sqlitetutorial.net/sqlite-import-csv/
I have an android application that is supposed to read and expand a database that is already created on sqlite...it works fine on emulator by putting database in "data/data/(packagename)/database" folder on the file explorer of emulator. Now problem is occuring with the real device. Obviously it doesnt have the database to open.I tried to put database in assets folder but I am not getting to open it with the openhelper.
you should copy the .db file from your assets folder to an internal/external storage. You can use following codes,
private static String DB_PATH = "/data/data/your package/database/";
private static String DB_NAME ="final.db";// Database name
To create a database,
public void createDataBase() throws IOException
{
//If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
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/database/DB Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = getApplicationContext().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();
}
i hope it should help you.
you cant access the database from asset folder directly you need to copy it first to the path data/data/(packagename)/database then using it :
private String DB_PATH = "/data/data/" + "yourpackaename" + "/databases/" + "db.db";
in your onCreate()
is = getAssets().open("db.db");
write(is);
Then the method to call:
public void write(InputStream is) {
try {
OutputStream out = new FileOutputStream(new File(DB_PATH));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
is.close();
out.flush();
out.close();
System.err.println(out + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
You need to first copy the Database file from assests to application data location using java code.Can You Post some code to show How are you opening or handling the database?
You cannot directly open files from assets folder. Instead, you need to copy the contents of your assets folder on an internal/external storage and later use the File path to open the file.
In emulators, its easier for you to access the data folder of your apps. However, on a real non-rooted android device, its not possible due to security reasons.
Do you have a pre-populated database and looking to integrate into your app? If yes, you can simply do with my library
On your app's first launch after installation
SuperDatabase database=new SuperDatabase(getApplicationContext(),"foods.db", AssetDatabaseMode.COPY_TO_SYSTEM);
On subsequent launches
SuperDatabase database=new SuperDatabase(getApplicationContext(),"foods.db", AssetDatabaseMode.READ_FROM_DEVICE);
Simply fire SQL queries
database.sqlInject("INSERT INTO food VALUES('Banana','Vitamin A');");
Get results on Array in CSV, JSON, XML
ArrayList<String> rows=new ArrayList<String>();
rows=database.sqlEjectCSV("SELECT * FROM food;");
for (int i=0;i<rows.size();i++)
{
//Do stuffs with each row
}
You need to include my library for this. Documentations here:
https://github.com/sangeethnandakumar/TestTube
There are a few questions here on stackoverflow where people use BackupAgents to synchronize the apps data with googles cloud (see here). In my specific case the requirements are much more restrictive due to the nature of the more or less sensitive data. Everything must only be stored on the device itself and the app must not connect to the internet.
The main Activity contains a ViewPager which hosts a few ListFragments. Each ListFragment has its own Loader which swaps the cursor in a SimpleCursorAdapter class.
Before both backing up and restoring the database I destroy the loaders with:
getLoaderManager().destroy(LOADER_ID);
My backup function is similar to this anwser:
final String inFileName = "/data/data/<your.app.package>/databases/foo.db";
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
String outFileName = Environment.getExternalStorageDirectory()+"/database_copy.db";
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer))>0){
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();
The restore function is similar in that it copies the database from the sdcard back into the internal app folder, stops the loaders and overwrites the database file.
public static void restore(Context context) throws IOException {
if (externalStorageIsWriteable()) {
// getBackupDir() is a path to the folder on the sdcard
File fileBackup = new File(getBackupDir(), WineSQLiteHelper.DB_NAME);
if (!fileBackup.exists()) {
throw new IOException("File not found");
}
File importFile = getImportDatabase();
try {
FileUtils.copyFile(fileBackup, importFile);
MySQLiteHelper dbHelper = new MySQLiteHelper(context);
dbHelper.close();
dbHelper = null;
File file = new File(Environment.getDataDirectory() + "/data/"
+ PACKAGE + "/databases/" + WineSQLiteHelper.DB_NAME);
FileUtils.copyFile(importFile, file);
// Remove temporary import file.
importFile.delete();
} catch (IOException e) {
throw e;
}
} else {
throw new IOException("External Storage not writeable");
}
}
But somehow the MainActivity gets recreated after I've overwritten the database file and I recieve a few
SQLiteException: no such column
My guess is that perhaps there are still open connections to the database, but I'm not sure about that since this is the first time I have to work with databases this closely.
How to properly close all database connections of a ContentProvider? I can't find anything in the documentation about this. And is this necessary?
How do I properly restore the database?
I am copying a database file from my assets folder to the databases folder on install. I have a shared preference named firstRun with a default value of true. If this is true then I copy the database file and set the firstRun value to false. Immediately following this process I then query a database table for some data. On an older Android version (2.1) an SQLite Exception occurs (no such table) and the application crashes, on Android 4.2.1 the dbHelper logs the same message but continues to run and returns the values from the table it just failed to find. With the earlier Android version, if I launch the application again, the database table is found and all operations proceed normally. After the application crashes I can inspect the copied database and the table and rows are present. This does seem to be different from other issues where tables genuinely don't exist as I can see that they do. I wonder if it's some kind of synchronisation issue where the table doesn't exist immediately after the copy process, but does at some point when a process has finished. To my knowledge this is not done asynchronously so I'm not sure why.
Here is some code to show the problem:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean firstRun = prefs.getBoolean(getString(R.string.first_time_run), true);
if (firstRun) {
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean(getString(R.string.first_time_run), Boolean.FALSE);
edit.commit();
try {
dbHelper.createDatabase();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
// This method will fire an exception the first time the app is run - no such table
Bundle metaData = dbHelper.fetchAppMetaData();
this.appTitle = metaData.getString("app_title");
this.normalId = Integer.parseInt(metaData.getString("normal_id"));
The fetchAppMetaData method is a basic sqlite.query:
Bundle metaData = new Bundle();
Cursor dbCursor = null;
SQLiteDatabase database = getReadableDatabase();
String[] cols = new String[] {"app_title", "normal_id"};
dbCursor = database.query(true, TBL_METADATA, cols, null, null, null, null, null, null);
if (dbCursor != null) {
dbCursor.moveToFirst();
which would eventually return a bundle.
The database creation method is:
//Open the local db as the input stream
InputStream dbFromAssets = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
// Check that the directory now exists
File f = new File(DB_PATH);
if (!f.exists()) {
f.mkdir();
}
// Open the empty db as the output stream
OutputStream appDatabase = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = dbFromAssets.read(buffer)) > 0){
appDatabase.write(buffer, 0, length);
}
// Close the streams - don't cross them!
appDatabase.flush();
appDatabase.close();
dbFromAssets.close();
Would be grateful for any ideas please.
Below is a cut and paste from working code. I use this on the launch of the MainActivity each time the application loads. Tested and working with versions 2.3 - 4.2:
Here is the code I'm using that does the check:
try
{
String destPath = "/data/data/" + getPackageName() + "/databases/(...your db...)";
File f = new File(destPath);
File c = new File("/data/data/" + getPackageName() + "/databases/");
// ---if directory doesn't exist then create it---
if (!c.exists())
{
c.mkdir();
}
// ---if db file doesn't exist then create it---
if (!f.exists())
{
CopyDB(getBaseContext().getAssets().open("...name of db from assets foleder..."), new FileOutputStream(destPath));
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
Here is the code I'm using that does the copying if not found:
public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException
{
//---copy 1K bytes at a time---
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0)
{
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
Hope this is hopeful...
The solution for me was to close the dbHelper after the database is created and before I try to use it again.
For example:
try {
dbHelper.createDatabase();
} catch (Exception e) {
}
dbHelper.close();
dbHelper.fetchAppMetaData();
Hope this helps someone else.
Hi everyone i have one question i.e. i have some database table's which are already exist in database but i am not able to use them in my application. I am able to connect to database but i am not getting the tables which i have already created. I am not creating tables programmectically but i want to use existing table in my database. If i am creating tables programmetically then it's fine but how can i use existing table.
If anyone is having any idea plz suggest me some solution.
Answer to my question is simpelly copy your database by using the followig code.
private void CopyDataBase() throws IOException {
// open the local database
InputStream copy = context.getAssets().open(UR_DB_NAME);
// path where database is created
String path_DB = DB_PATH + DB_NAME;
// Open the empty dbOut as the output stream
OutputStream dbOut = new FileOutputStream(path_DB);
// copy database from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = copy.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
// Close the streams
dbOut.flush();
dbOut.close();
copy.close();
}