I have this android application that I am developing in Unity. I am using SQLite to save and access my data.
When I run my code on Unity editor it works fine. But when I tried it in my android device after some changes in the database, it did not work. So I undid those changes and use Android Device Monitor to check what was happening. I found out that, even though it looked to be working, it was throwing a Unity error: Unable to find SQLite.
I just can't understand what is going on. It works on Unity editor, and, before changes in my database, it also worked (or that was what it seemed) on android device.
This is the code I use to connect to database:
private void conecta()
{
if (Application.platform != RuntimePlatform.Android)
{
dbFile = Application.dataPath + "/StreamingAssets/" + databasefile;
}
else
{
dbFile = Application.persistentDataPath + "/" + databasefile;
if (!File.Exists(dbFile))
{
WWW load = new WWW("jar:file://" + Application.dataPath + "!/assets/" + databasefile);
while (!load.isDone)
{
}
File.WriteAllBytes(dbFile, load.bytes);
}
}
print("aaaaaaaaaaaaaaa");
connection = new SqliteConnection("URI=file:" + dbFile);
print("bbbbbbbbbbbbbb");
}
On my project, I have some dll in my Plugins folder.
And I have libsqlite3.so in my Android folder that can be seen in the picture.
I don't understand what's going on, because when I run the app it accesses the database data and stores more data, but apparently it also throws this error. Can anyone please help me?
If this information is not enough, please let me know. I will complete my question.
UPDATE
I now know the exact line of code that is giving the error. I use the code above to establish a connection with the SQLite database in some scripts. But in this specific script, which is attached to the first screen of the application, the error is coming from this line:
connection = new SqliteConnection("URI=file:" + dbFile);
I don't know why. I use that code as a method and use it some times in this script. I have some buttons that only become interactable if I have data in my database. And when I run it on my device they became interactable. That's why I did not see the error until yesterday when I changed the database file. Below you can see the error when accessing the new column and the table structure in database.
I added one column in two tables, and when I try to access one of those columns it throws an error saying that the table does not have a column with that name.
NEW UPDATE
I got tired of this error and deleted my database file. After that I did a new one, with columns I addes before. What happened was that the Unable to find SQLite continues. After taht it keeps saying that my table does not have the especific column I added in the other file. I don't understant what's going on. That new database had the column from the very begining.
I still don't know what was the problem with the app. But I did a new database file with a different name and it is now working.
Related
As I changed the android version and the path from externalized to the default database-folder, I don't know where the error come from.
I found that the reason might be problems accessing the journal file is locked (it is created by the program).
the "test" is reading data and if it exists it updates and if not it inserts. This is done in a loop while reading lines from a file. For testing purpose i simplified it but the error is the same.
package ...;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class test {
public test(SQLiteDatabase MyDB)
{
MyDB.execSQL("CREATE TABLE IF NOT EXISTS testtable (mytext TEXT, number INT PRIMARY KEY)", new String[] {});
for (int i = 1; i < 5; i++)
{
String[] ColArray = { "any text", String.valueOf(i) };
Cursor readCursor = MyDB.rawQuery("SELECT mytext FROM testtable WHERE number=?", new String[] { String.valueOf(i) });
if (!readCursor.moveToNext()) // Error when executing moveToNext
/*
In the 2nd time it runs over this point an Error occurs:
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
I need to remove the journal file to be able to connect to the database it again - the change made by the Insert/Update is successfully saved!
*/ {
readCursor.close();
MyDB.execSQL("INSERT INTO testtable (mytext, number) VALUES(?, ?)", ColArray);
}
else {
readCursor.close();
MyDB.execSQL("UPDATE testtable SET mytext=? WHERE number=?", ColArray);
}
}
}
}
MyDB is a valid DB-Connection.
1) The Table is created
2) The Table is READ but Line 1 is not found
2a) READ again is possible until now if the read is closed.
3) Line 1 is INSERTED
4) when trying to READ again (the line 2 would not be found, too), moving the cursor fails.
The journalfile need to be deleted manually or the app will fail to start again when trying to connect.
Please Help! Thank you.
Maybe you should use the specialized insert and update methods.
In the documentation of the SQLiteDatabase it says for execSQL:
Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
There are specialized methods for insert and update with similar names. I guess, that there is some problem generated, when the unspecific "execSQL" statement is used.
i solved it after hours of testing.
possibly the sqlite version is different in the old and new system... i changed the rom again - for some reason, this time i didn't copy the databasefile into the data-folder. Instead i let the program create a empty database and imported the data from text by the program itself from a csv-export.
I currently don't know if the problem was within the rom or (what seem to be the reason in my opinion) i created the problem by using the origin database which might be read and writeable but has problems when the journalfile should get processed. if somebody has an equal problem, he should try to create a new empty database in the new system.
I'm implementing Foreign Keys in my SQLite DB in Android.
I had my DB working well without FK, but now, I have several problems.
One is when I try to get reference to db, I have this error.
E/SQLiteLog﹕ (10) Failed to do file read, got: 0, amt: 100, last Errno: 2
My Function:
public synchronized SQLiteDatabase openDatabase() {
if (mOpenCounter.incrementAndGet() == 1) {
// Opening new database
mDatabase = mDatabaseHelper.getWritableDatabase();
// Get Foreign Key Support
mDatabase.execSQL("PRAGMA foreign_keys=ON");
}
return mDatabase;
}
The error happens in the line:
mDatabase = mDatabaseHelper.getWritableDatabase();
It seems to be the first time that this line is called.
Other time, there is no pb.
I'm not sure it gives me direct errors, but I have several problems in SQLite, so it might contribute to bad behaviour.
Tx
Try this:
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
Not sure if this is/was also your case. I just encountered this now and what I was trying to do was to download a sqlite zipped dump from my server and extracting it as my SQLite database. I used this blog post as my guide (still works well in 2016).
I was getting the same error as you are, and when I downloaded the zip file to my laptop and tried to extract it (there were other posts saying that you'd encounter this error if your new database has change in structure and then you forgot to update your database version number) so I can get to the raw sql file, and I received an "Unable to expand ... Error 2" Error - meaning that the zip file is corrupt.
I am trying to get an updated version/backup of the zip file to test this theory but so far, all roads pointed to a corrupt zip file. I shall keep this posted.
I'm getting a weird error in DDMS, it appears just after the innocent "Finalizing a Cursor that has not been deactivated or closed", comming from my own DataAdapter (about that in next question)
Error:
"Finalizing a Cursor that has not been deactivated or closed. database = /data/data/net.toload.main/databases/lime, table = null, query = SELECT _id, code, code3r, word, score FROM mapping WHERE code3r = '0' AND code ='HTT' ORDER BY cod"
I didn't create any tables with such columns in my app! And my localdatabase isn't stored there... /databases/lime, but this error seems to come just after my real error from my own DataAdapter. I tried to pull the lime.db file to read the contents of the database but the pulled file is always of 0 bytes, though on DDMS-FileExplorer is much more, now 26624bytes.
So ... im thinking that maybe android/google is tracking my every move!! and the app doesnt run in a isolated process...
Anyway can you explain this error?
Your project must be using this Lime IME (Lightweight Input Method Editor):
http://code.google.com/p/limeime/
This question already has answers here:
Query if Android database exists!
(7 answers)
Closed 7 years ago.
How can I quickly check if a database exists in Android?
(not a Table - the entire database)
Open your database and catch the SQLitException which will be thrown in case if database doesn't exist. Note that, you should not call the openOrCreateDatabase() method. See this post for details; Query if Android database exists!
My way to check to see if your database exists is to open a file handle on it and see if the file exists. from my experience using "openOrCreateDatabase()" function will not throw an error if the db doesn't exist. take a look a the name "Open OR Create Database". meaning if there's no db to open it'll just make a new one, so regardless of if there was one before there is one now. I think the only time you'll get an error thrown is if it can't do either. which from what the guy said I don't believe is what they are trying to test for, I think he wanted his program to know if the db was already there before hand, and not to automatically create a blank one if there wasn't. so Since all db's are stored as files, the first parameter in that open database command is the file name. So I think the best option is to check to see if the db file exists like so:
File dbtest = new File("/data/data/yourpackagename/databases/dbfilename");
//If you have Context, you could get the Database file using the following syntax
//File dbtest = getApplicationContext().getDatabasePath("dbfilename.db");
if(dbtest.exists())
{
// what to do if it does exist
}
else
{
// what to do if it doesn't exist
}
I would like to delete the database file from the Android file system programatically? Can I have a shell script launch adb which in turns runs a shell script in the Android space to do the database deletion? Can I get this done from within a JUnit test case (with a system() call)?
How do I delete an entire database in Android? I need to make the whole thing go away so I can test database creation. I can drop tables, but that's not enough. This is in the emulator, not on a phone.
Once you have your Context and know the name of the database, use:
context.deleteDatabase(DATABASE_NAME);
When this line gets run, the database should be deleted.
The SQLiteDatabase.deleteDatabase(File file) static method was added in API 16. If you want to write apps that support older devices, how do you do this?
I tried: file.delete();
but it messes up SQLiteOpenHelper.
Thanks.
NEVER MIND! I later realized you are using Context.deleteDatabase(). The Context one works great and deletes the journal too. Works for me.
Also, I found I needed to call SQLiteOpenHelp.close() before doing the delete, so that I could then use LoaderManager to recreate it.
It's easy just type from your shell:
adb shell
cd /data/data
cd <your.application.java.package>
cd databases
su rm <your db name>.db
Try:
this.deleteDatabase(path);
or
context.deleteDatabase(path);
context.deleteDatabase("database_name.db");
This might help someone. You have to mention the extension otherwise, it will not work.
Also from Eclipse you can use DDMS which makes it really easy.
Just make sure your emulator is running, and then switch to DDMS perspective in Eclipse. You'll have full access to the File Explorer which will allow you to go in and easily delete the entire database.
context.deleteDatabase(DATABASE_NAME); will delete the database only if all the connections are closed. If you are maintaining singleton instance for handling your database helper - it is easy to close the opened Connection.
Incase the databasehelper is used in multiple place by instantiating directly, the deleteDatabase + killProcess will do the job even if some connections are open. This can be used if the application scenario doesn't have any issues in restarting the app.
Delete old Db when uninstall the app.
Setting android:allowBackup="false" in the application tag in AndroidManifest.xml fixed the problem. It seems that for some weird reason the Android OS was restoring from a backup every time I deployed the app.
you can create a file object of current database path and then delete it as we delete file from folder
File data = Environment.getDataDirectory();
String currentDBPath = "/data/com.example.demo/databases/" + DATABASE_NAME;
File currentDB = new File(data, currentDBPath);
boolean deleted = SQLiteDatabase.deleteDatabase(currentDB);
I used Android database delete method and database removed successfully
public bool DeleteDatabase()
{
var dbName = "TenderDb.db";
var documentDirectoryPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var path = Path.Combine(documentDirectoryPath, dbName);
return Android.Database.Sqlite.SQLiteDatabase.DeleteDatabase(new Java.IO.File(path));
}
I have used the following for "formatting" the database on device after I have changed the structure of the database in assets. I simply uncomment the line in MainActivity when I wanted that the database is read from the assets again. This will reset the device database values and structure to mach with the preoccupied database in assets folder.
//database initialization. Uncomment to clear the database
//deleteDatabase("questions.db");
Next, I will implement a button that will run the deleteDatabase so that the user can reset its progress in the game.
If you are going to delete Table or Database , this way is worked:
1- Delete Table - It means keep Database but clean data from a table
* Just in DataHelper class add
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("delete from " + TABLE_NAME);
2- Delete Database - It means clean all records but keep file name
In the Activity
myDb = new DbHelper(this);
myDb.close();
myDb.delAll(getApplicationContext());
recreate();
In DataHelper class add
public void delAll(Context context) {
context.deleteDatabase(DB_NAME);
}
From Application Manager, you can delete whole application with data. Or just data by it self. This includes database.
Navigate to Settings. You can get to the settings menu either in
your apps menu or, on most phones, by pulling down the notification
drawer and tapping a button there.
Select the Apps submenu. On some phones this menu will have a
slightly different name such as Application Manager.
Swipe right to
the All apps list. Ignore the lists of Running and Downloaded apps.
You want the All apps list.
Select the app you wish to disable. A properties screen appears with
a button for Force Stop on the upper left and another for either
Disable or Uninstall updates on the upper right side.
Delete data.