Cannot open Database file - android

I have an application that creates a database file at '/storage/emulated/0/databases/mydb.db' and there are files within this DB.
I have another application which tries to open this database. But I get error code 14. Could not open database when trying to oprn the table in this db.
public class DataBaseHelper extends SQLiteOpenHelper {
public SQLiteDatabase myDataBase;
public String TABLE_NAME;
// Database Information
static final String DB_NAME = "mydb.DB";
public static final String FILE_DIR = "databases";
private String DB_PATH = Environment.getExternalStorageDirectory()
+ File.separator + FILE_DIR + File.separator + DB_NAME;
public DataBaseHelper(Context context, String name) {
super(context, name, null, 1);
TABLE_NAME = name;
}
public void openDatabase() throws SQLiteException {
String DBPath = DB_PATH + "/" +TABLE_NAME;
myDataBase = SQLiteDatabase.openDatabase(DBPath,null,SQLiteDatabase.OPEN_READWRITE);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
I get an error at myDataBase = SQLiteDatabase.openDatabase(DBPath,null,SQLiteDatabase.OPEN_READWRITE);

Another thing to note is Environment.getExternalStorageDirectory() has been deprecated in API 29:
https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory()
This method was deprecated in API level 29.
To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

1. Permission
Your app needs file read permission. Above Android 6.0, you need to request runtime permission.
See this: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
2. Wrong path
It seems that the path
/storage/emulated/0/databases/mydb.db
is not same as path below.
Environment.getExternalStorageDirectory()
+ File.separator + FILE_DIR + File.separator + DB_NAME
So, before open database file, compare two paths to check it is same.
if (DB_PATH.compareTo("/storage/emulated/0/databases/mydb.db")){
// Do something
}
And check the to find out it really exists.
File file = new File(myPath);
if (file.exists() && !file.isDirectory()) {
// Do something
}
Details: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database trouble

Related

How to store SQLite DB on SD card? [duplicate]

i want to create my sqlite database in sdcard instead of default path...i want to access all my data from sdcard also
I have Used This Code:
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
SQLiteDatabase.openOrCreateDatabase("/sdcard/"+DATABASE_NAME,null);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "
+ TABLE_NAME
+ " (id INTEGER PRIMARY KEY, name TEXT, number TEXT, skypeId TEXT, address TEXT, image BLOB)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
Problem:
When i see the database file in default path i can see all the data
and table but when i see the database file created in sd card it
doesnot shows any data but it only shows the database file
IN constructor it only creates the file in sdcard but in default path it does everything well.....
How to store all Sqlitedata on sdcard for further access?
I created my DB with
public DatabaseHelper(final Context context) {
super(context, Environment.getExternalStorageDirectory()
+ File.separator + FILE_DIR
+ File.separator + DATABASE_NAME, null, DATABASE_VERSION);
}
and had no problems further on. I guess your call to super() should reference the sdcard as well.
You are providing an incomplete name in your super() call. Try using:
OpenHelper(Context context) {
super(context, "/sdcard/"+DATABASE_NAME, null, DATABASE_VERSION);
SQLiteDatabase.openOrCreateDatabase("/sdcard/"+DATABASE_NAME,null);
}
Other than that, you should always use Environment.getExternalStoreDirectory() to get the path to the external storage, and you should also check the state of the external storage before attempting to use it.
public DataBaseHelper(final Context context) {
super(context, Environment.getExternalStorageDirectory()
+ File.separator+ MYDATABASE_NAME, null, MYDATABASE_VERSION);
}
**Also Add permission in android Manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />**
Just give path in constructor ;
DatabaseHelper(Context context) {
super(context, Environment.getExternalStorageDirectory()
+ File.separator + "/DataBase/" + File.separator
+ DB_NAME, null, DB_VERSION);
}
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app.
For getting permissions at runtime, you will have to request the user. You can do that in following way.
First request for permissions.
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, WRITE_REQUEST_CODE);
And then you can check the results in
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case WRITE_REQUEST_CODE:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Permission granted.
//Continue with writing files...
}
else{
//Permission denied.
}
break;
}
}
Here is good learning source requesting-runtime-permissions-in-android-marshmallow/
The use of Environment.getExternalStorageDirectory() method is deprecated,
This method was deprecated in API level 29. To improve user privacy,
direct access to shared/external storage devices is deprecated. When
an app targets Build.VERSION_CODES.Q, the path returned from this
method is no longer directly accessible to apps. Apps can continue to
access content stored on shared/external storage by migrating to
alternatives such as Context#getExternalFilesDir(String), MediaStore,
or Intent#ACTION_OPEN_DOCUMENT.
now we must use getExternalFilesDir(), this is an example:
public class MyDataBaseHelper extends SQLiteOpenHelper {
//Constructor
MyDataBaseHelper(Context context) {
super(context, context.getExternalFilesDir()
+ File.separator + "/Database/" + File.separator
+ DATABASE_QUESTION, null, DATABASE_VERSION);
}
...
...
}

Not able to open pre-installed database using Sqlite AssetHelper library

I am working on pre-installed database and using SqliteAssetHelper library for that.
This is my db code
public class DBController extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "user.db";
private static final int DATABASE_VERSION = 1;
private final String TABLE_NAME = "User";
public DBController(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public ArrayList<UserData> getAllUserData() {
ArrayList<UserData> data_list = new ArrayList<>();
try {
// open database to query
SQLiteDatabase mySqliteDb = getWritableDatabase();
} catch (Exception e) {
Log.e("exception", "" + e);
}
close();
return data_list;
}
}
Error: Missing databases/user.db file (or .zip, .gz archive) in assets, or target folder not writable
and when I change my code to SQLiteDatabase mySqliteDb = getReadableDatabase(); I am getting android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database error.
I search for the problem and mostly everyon saying check your db present inside databases folder or not.
I tried using zip also still no luck. I guess I am missing something.
Your assets/ directory belongs inside main/, not inside app/.

No such table error when opening SQLite database from external storage Android

I'm trying to open and perform queries on a SQLite database that is stored in external storage.
I'm opening the database using the following piece of code.
db = SQLiteDatabase.openDatabase(DB_PATH+"/"+DATABASE_NAME, null, DATABASE_VERSION);
However whenever I run this I get the no such table error even though the table does exist in the database. As the database isn't stored in the assets folder I assume you don't have to copy the database before you can read it but I might be wrong.
public static final String DATABASE_NAME = "BB2SoulDatabase.db";
public DBHelper(Context context) {
super(context, Environment.getExternalStorageDirectory().getAbsolutePath() + "/SoulInfoDatabase"
+ "/" + DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
DB_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SoulInfoDatabase";
}

Android Custom SQLite Build - cannot open database

My goal is to build a custom version of SQLite (specifically with R-Tree enabled) to include in my Android project. The motivation stems from:
Android SQLite R-Tree - How to install module?
SQLite has some instructions in how to do this:
http://www.sqlite.org/android/doc/trunk/www/index.wiki
I have compiled SQLite and successfully included the shared library in my project. The problem I am having is that as soon as I call an operation such as getReadableDatabase() or getWriteableDatabase() I receive a SQLiteCantOpenDatabaseException.
It is important to note that I am using:
import org.sqlite.database.sqlite.SQLiteDatabase;
import org.sqlite.database.sqlite.SQLiteOpenHelper;
in place of:
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
In order to use the custom SQLite build through the NDK and JNI.
MySQLiteHelper:
public class MySQLiteHelper extends SQLiteOpenHelper {
static {
System.loadLibrary("sqliteX");
}
private static final String DATABASE_NAME = "mydata.db";
private static final int DATABASE_VERSION = 1;
Context myContext;
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
myContext = context;
}
public void getEntry(){
SQLiteDatabase db = this.getReadableDatabase();
db.close();
}
public void createEntry(){
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
//...
//...
db.close();
}
#Override
public void onCreate(SQLiteDatabase database) {
String create_rtree = "CREATE VIRTUAL TABLE demo_index USING rtree(\n" +
" id, -- Integer primary key\n" +
" minX, maxX, -- Minimum and maximum X coordinate\n" +
" minY, maxY -- Minimum and maximum Y coordinate\n" +
");";
database.execSQL(create_rtree);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(MySQLiteHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + "demo_index");
onCreate(db);
}
}
Main Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MySQLiteHelper helper = new MySQLiteHelper(this);
helper.createEntry();
setContentView(R.layout.activity_my);
}
Stack Trace:
10-29 13:45:38.356 2360-2360/com.example.nathanielwendt.lstrtree E/SQLiteLog﹕ (14) os_unix.c:30589: (2) open(//arrrr.db) -
10-29 13:45:38.376 2360-2360/com.example.nathanielwendt.lstrtree E/SQLiteDatabase﹕ Failed to open database 'arrrr.db'.
org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:201)
at org.sqlite.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:467)
at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:809)
at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:794)
at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:699)
at org.sqlite.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:722)
at org.sqlite.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:228)
at org.sqlite.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:168)
at com.example.nathanielwendt.lstrtree.MySQLiteHelper.createEntry(MySQLiteHelper.java:65)
at com.example.nathanielwendt.lstrtree.MyActivity.onCreate(MyActivity.java:25)
I have seen several posts here on SO about this same exception, but they all seem to be related to importing the database from somewhere else on disk in which they do not set the file path correctly. This seems to be the most related post: Android SQLiteOpenHelper cannot open database file, but none of the suggestions worked.
I have tried this with 2 different phones and with the emulator and I receive the same error. Furthermore, I have replaced the imports discussed above with the default android sqlite imports and it works fine (given I don't try to create an R-Tree since it is not included in the default Android SQLite install). Changing permissions of database dir and .db file to 777 did not fix the issue, neither did adding WRITE_PERMISSION to my manifest.
This is an incompatibility in the SQLite Android bindings.
The original Android code opens the database like this:
db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
mFactory, mErrorHandler);
while org.sqlite.database.sqlite.SQLiteOpenHelper does not use the context:
db = SQLiteDatabase.openOrCreateDatabase(
mName, mFactory, mErrorHandler
);
This means that the database path is not prepended to the database name.
Use something like this to get the complete path of the database:
String path = context.getDatabasePath(DATABASE_NAME).getPath();
and use that as the database name.

Android SQLite Database Connection not succesfull

i encountered a little problem with my current project. I am doing an android application which needs to connect to a SQLite database to work through some statements. I believe the statements etc are fine, my only problem is the fact that the connection to the database is not succesfull.
LogCat Error:
04-18 08:20:30.688: E/Database(304): sqlite3_open_v2("jdbc:sqlite:res/raw/randomdb.db", &handle, 1, NULL) failed
So my code so far for connecting to the database is like this:
String url = "jdbc:sqlite:res/raw/randomdb.db";
SQLiteDatabase db;
db = SQLiteDatabase.openDatabase(url, null, SQLiteDatabase.OPEN_READONLY);
As you can see, i am trying to acces a database which is located in my project/res/raw folder. Does anyone see the mistake?
!!!UPDATE!!!
*I tried to go the way with SQLiteOpenHelper, but still encouner an error i cannot seem to solver. Here is my new code:*
public class DatabaseAdapter extends SQLiteOpenHelper {
private static String dbPath= "data/data/com.YourPackageName/applicationDb/";
private static String dbName = "YourDBName";
private SQLiteDatabase applicationDatabase;
private final Context applicationContext;
private boolean checkDataBase(){
File dbFile = new File( dbPath + dbName);
return dbFile.exists();
}
public void openDataBase() throws SQLException{
String fullDbPath= dbPath + dbName;
applicationDatabase = SQLiteDatabase.openDatabase( fullDbPath,null,SQLiteDatabase.OPEN_READONLY);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
I get this error:
Implicit super constructor SQLiteOpenHelper() is undefined for default constructor. Must define an explicit constructor
Any ideas? Would be great!
if you want to connect your android application with SQLite database then you need to extends SQLiteOpenHelper
public class AbcClass extends SQLiteOpenHelper
after that you need to Override these method:
onCreate and onUpgrade
and constructor of AbcClass looks like:
public AbcClass(Context context) {
super(context, DB_NAME, null, VERSION); //public static final String DB_NAME = "test.sqlite";
}
public boolean databaseExist()
{
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
This is the solution...
OR-----------------------
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
I think the path you specify is not the correct one and so as mentioned in one of the other answers the database is not found. However I had never used the method openDatabase to read from the raw folder so I do not know which is the correct path.
However once upon a time I had shipped the database along with my application. It resided in the assets folder and once the application started I copied it in the private application storage (much like any database created with SqliteOpenHelper). From then on I used the usual way with SqliteOpenHelper to access the database.
Basically for this I followed the blog mentioned in this thread and because my database file was bigger than 1MB I used the technique described in this thread. Hopefully combining those two you will get your database running!
EDIT Btw you are wrong, openDatabase does not accept url, but path.

Categories

Resources