How to store sqlite database directly on sdcard - android

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);
}
...
...
}

Related

Upgrading from java-based android app to react native and SQLite storage

I believe there is only one location databases can be stored on Android but also wondering if the file extension for SQLiteOpenHelper is .db3, .db, or user defined and if not defined there is no extension.
Any help?
My scenario is: I have a java based android app in the play store currently and it opens the database like so (relevant code only):
private static final String DATABASE_NAME = "data";
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// do stuff
}
public boolean checkIfColumnExist(SQLiteDatabase db, String column) {
Cursor cursor = db.rawQuery("SELECT * FROM " + DATABASE_TABLE + " limit 1", null);
if(cursor == null) return false;
cursor.moveToFirst();
boolean exist = cursor.getColumnIndex(column) != -1;
cursor.close();
return exist;
}
}
// in constructor of another db wrapper
mDbHelper = new DatabaseHelper(mCtx);
// open function of db wrapper
public void open() throws SQLException {
mDb = mDbHelper.getWritableDatabase();
}
That works fine (older app) and has been for a while.
What I'm doing in react native is using react-native-sqlite-storage like so:
import SQLite from 'react-native-sqlite-storage';
SQLite.enablePromise(true);
const Database = {
DATABASE_NAME: 'data'
};
this.db = await SQLite.openDatabase({ name: Database.DATABASE_NAME, location: 'default' });
The above works on a clean install but when I test upgrading from the older java-based android version to a newer version react native version it doesn't.
One thing to note is that I'm testing this upgrade in a janky way. I'm a "internal tester" for the app and I installed the java-based one via play store and then added myself to the internal tester group, then "updated" it to the react native one. I don't think this would be an issue but it's been a while since I've done internal testing and not sure of all the quirks.

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);
}
...
...
}

Cannot open Database file

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

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";
}

Is it possible to use SQLiteOpenHelper to create DB in cache dir?

I would like to create a database in cache so it could be wiped out when user clicks Clear cache button.
In SQLiteOpenHelper constructor there is only argument to pass a name of database, not a directory (default is dadabases).
Is there any option to delete such DB when user wants to clear cache?
Here is an example of creating a database in your cache directory:
public class CachedDatabase extends SQLiteOpenHelper {
public CachedDatabase(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, new File(context.getCacheDir(), name).getAbsolutePath(), factory, version);
}
#Override public void onCreate(SQLiteDatabase db) {
// just for testing
db.execSQL("CREATE TABLE example (id INTEGER PRIMARY KEY AUTOINCREMENT, foo, bar, baz, qux)");
}
#Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
All you need to do is pass the absolute path as the name parameter in the constructor.
Tested just to make sure it was created in /data/data/[package_name]/cache:
CachedDatabase cachedDatabase = new CachedDatabase(this, "TEST", null, 1);
SQLiteDatabase database = cachedDatabase.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("foo", "foo");
values.put("bar", "bar");
values.put("baz", 123);
values.put("qux", true);
database.insert("example", null, values);
Checking for the database:
$ adb shell
$ run-as [YOUR_PACKAGE_NAME]
$ ls cache
TEST
TEST-journal
You can create and open a database in a specific location, but you need to use SQLiteDatabase class (choose one of the openOrCreateDatabase methods): as you mentioned you can't create a database in a different path using the provided SQLiteOpenHelper.
You can also modify the code of the SQLiteOpenHelper to match your needs. Take the source code from the link, copy in a new class of your project and modify the getDatabaseLocked method.
You can also take inspiration from SQLiteAssetHelper.
If you are looking to clear the data in tabledb.execSQL("delete * from "+ TABLE_NAME);
you can also delete the tables db.delete("TABLE_NAME", null, null);

Categories

Resources