I have an sqlite database (.db), copied it in assets folder and have to copy it to /data/data/package_name/databases. The problem is I don't have databases folder and did not succeed to create it.
String dirPath = "/data/data/com.gatec.douaa/databases/";
Log.d("Directory",dirPath);
File projDir = new File(dirPath);
if (!projDir.exists())
projDir.mkdirs();
Can you please help me to create that folder to store on it the database?
Thank you very much.
In my experieces, the "databases" directory is created the first time you use the database. So, if you want copy the database from "asset" directory, you have to force the database creation in the path "data/data/package_name/databases".
This happens only in the lollipop (android 5), in my experiences.
Then you can use the code below:
File file = new File(context.getDatabasePath("database_name.db").getPath());
if (!file.exists())
{
try
{
file.createNewFile();
}
catch (IOException e)
{
}
}
Related
After clearing application storage & cache, started getting unknown error (code 14 SQLITE_CANTOPEN): Could not open database. Before clearing storage, everything was working properly, both Emulator and Device.
I tried deleting application from Emulator, wiped Emulator and cleaned project, but still crashing when opening MainActivity. For the sake of problem solving, I've put writing permissions in AndroidManifest but still the same error.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Instead of doing
this.baza_putanja = "/data/data/" + context.getPackageName() + "/" + "databases/";
I did
baza_putanja = context.getDatabasePath(baza_ime).getPath();
What bothers me is if I'm trying to open database using a path that does not include the database name - why was it working before clearing application storage & cache?
BazaPodatakaHelper.java
private String baza_putanja = null;
private static final String baza_ime = "eng_dictionary.db";
private SQLiteDatabase econDictionary;
private final Context mContext;
public BazaPodatakaHelper(Context context) {
super(context, baza_ime, null, 1);
this.mContext = context;
this.baza_putanja = "/data/data/" + context.getPackageName() + "/" + "databases/";
Log.e("Putanja 1", baza_putanja);
}
public void kreirajBazuPodataka() throws IOException {
boolean bazaPodatakaPostoji = provjeriBazuPodataka();
if ( !bazaPodatakaPostoji ) {
this.getReadableDatabase();
try {
kopirajBazuPodataka();
} catch (IOException e) {
throw new Error("Greška prilikom kopiranja baze podataka");
}
}
}
public boolean provjeriBazuPodataka() {
SQLiteDatabase provjera;
try {
String putanja = baza_putanja + baza_ime;
provjera = SQLiteDatabase.openDatabase(putanja, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
throw new Error("Greška prilikom provjeravanja baze podataka");
}
if (provjera != null) {
provjera.close();
}
return provjera != null;
}
Error Log:
2019-07-17 20:39:30.482 7885-7885/com.benjaminkljn.econdictionary E/Putanja 1: /data/data/com.benjaminkljn.econdictionary/assets/ 2019-07-17 20:39:30.485 7885-7885/com.benjaminkljn.econdictionary E/SQLiteLog: (14) cannot open file at line 36683 of [c255889bd9] 2019-07-17 20:39:30.485 7885-7885/com.benjaminkljn.econdictionary E/SQLiteLog: (14) os_unix.c:36683: (2) open(/data/data/com.benjaminkljn.econdictionary/assets/eng_dictionary.db)
- 2019-07-17 20:39:30.491 7885-7885/com.benjaminkljn.econdictionary E/SQLiteDatabase: Failed to open database '/data/data/com.benjaminkljn.econdictionary/assets/eng_dictionary.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14 SQLITE_CANTOPEN): Could not open database
The message is saying
/data/data/com.benjaminkljn.econdictionary/assets/eng_dictionary.db
Your code above does not include assets in the path, so your issue is probably based around that.
Typically, and specifically, if using context.getDatabasePath(your_database), the attempt would be to open
/data/data/com.benjaminkljn.econdictionary/databases/eng_dictionary.db
i.e. the databases folder not the assets.
Additionally in your comments you mention :-
>I've deleted and re-imported database
Typically, importing the database, at least for an App, would be copying the database to be imported (included with the app) to the assets folder.
As such it could be that you are trying to open the database from what you think is the assets folder, but you cannot use the included/imported assets folder directly as the assets are managed by AssetsManager.
You could probably use Device Explorer to create the assets folder in /data/data/com.benjaminkljn.econdictionary and then copy the database into that folder and then the open may then work.
If you did that previously then, after deleting/uninstalling the App would, if the database hasn't been manually copied into the assets folder (and thus the assets folder has be created), result in the issue you have encountered.
When an App is installed the /data/data/com.benjaminkljn.econdictionary folder will be created but not the sub folders databases not the sub folder named assets, Clearing the App's storage effectively returns to this point.
However, manually copying the database, will only work for the specific App. It wouldn't work if you published the App, as you would not have access to copy the file manually.
To use a pre-existing database in an App then the recommended way is to :-
Create the App or part of the App
Create the assets folder in main/src/ (same location as where the res/java folders and android.manaifest are located).
Note if using SQLiteAssetHelper then create the databases folder in the assets folder.
Copy the database into the assets
The App should then before attempting to use the database, copy the database from the assets folder, accessing the database using AssetManager, into the location from which the database will be accessed.
Typically this location is /data/data/the_package_name/databases/your_database
The reliable/recommended way of determening the location is to use context.getDatabasePath(your_database).
Note that the databases folder will not exist for a new App and must be created (SQLiteAssethelper will do this).
SQliteAssethelper simplifies this.
Normally to make changes in my Database I followed the following steps:
Edited Database in SQLite
Delete Database in my assets folder
Copy paste Database in assets folder again
Delete the App from my phone through settings
Rebuild/install the app
This worked for me beforehand many times. No I have the issue that somehow my project does not access this database anymore.
I figured that out by deleting the database from my asset folder and reinstalling the app. The App still works, therefore it does not access the database from my asset folder that I used beforehand, to the best of my knowledge.
I am using the following path to access it:
DB_Path = mContext.getDatabasePath(DB_Name).
Log.e("DB_path", DB_Path);
Which yields
.com.example.chris.projectartifact E/DB_path:/data/user/0/com.example.chris.projectartifact/databases/myDB.db.
Regarding the Comment:
I am using the following method to copy my Database.
This is from a tutorial and it worked fine for a very long time.
From my understanding though FileOutputStream(DB_Path)
copies it to named path.
public void copyDataBase(){
try {
InputStream myInput = mContext.getAssets().open(DB_Name);
OutputStream myOutput = new FileOutputStream(DB_Path);
byte[] buffer = new byte[1024];
int length;
while ((length=myInput.read(buffer))>0){
myOutput.write(buffer,0,length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e){
Log.e("Error:","in CopyDatabase, where are in catch..");
e.printStackTrace();
}
}
The Questions:
Where do I find my database in my structure?
How am I able to update it?
New Question: How do i delete my copied database and renew it from my asset folder?
If your db is in your assets folder, its not on the file system at all- its in your assets- its part of the APK file (and thus read only). If you need it to be read write, you need to copy it to the filesystem first, and then you can put it where you want (although in the database path is traditional it isn't enforced).
I guess I'm a little confused as to how files are stored on an actual machine (or emulator even).
While programming, I can save my xml file in the assets folder manually, but how to write an app that will have to connect to the network and download the file,save it somewhere and then manipulate it ? where will it store said file ?
I want to create a new file, but I read on another post that the assets folder as such is not available once packaged; So where are they created and stored ? How can they be transferred. Its just, I'm new to this platform and the file system is a little confusing.
If you want to use XML that is updated, you should think of copying the file(s) from assets to device storage. You can take a look at How to copy files from 'assets' folder to sdcard? to know how this can be done.
Another alternative is to use the database where you can store the parsed data from the XML. So that you need not parse the file whenever you need to access the contents.
You have two options: call getFilesDir() from your activity to obtain a path to the internal data folder that can only be read/write from your app.
Or, you can write/read your xml file to external storage (SD Card). Use the method Environment.getExternalStorageDirectory() to get the root path of the external storage, then create your own folder as you see fit.
Note that if you write to external storage, every app in the phone will have access to it.
Even I faced this issue. Now I have a xml file which is has application properties.This is packaged in the assets folder.Once packaged we cannot edit a file in assets folder.
Now on app load I just copy this file to path returned by
context.getFilesDir().getAbsolutePath();
And the application edit it from the same place. You can see if the file is modified in the FileExplorer panel of DDMS view. The file is stored in the folder named same as your application package name for eg: com.abhi.maps
Alternatively you can also copy it to SD card.However it is risky because, sd card may bot be available all the time.
You can use the following code to copy file from assets folder:
private static void copyFile(String filename, Context context) {
AssetManager assetManager = context.getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
String newFileName = context.getFilesDir() + "/" + filename;
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
Hope it helps! :)
I am using gridview example with image adapter to render images with difference that these images are retrieved from a particular folder in sdcard for e.g. /sdcard/images.
I am testing this application on emulator.For this i have firstly configured sdcard on emulator and then pushed the images on this particular folder through DDMS under eclipse.
What i want to know is that is it possible to create images folder containing images in sdcard when a user installs the application on the real device and if possible what is the way to do it?
I'm not aware of a way to do it (which is not to say that it cant be done).
One thing that you definitely can do is create the folder when the user first runs the application, and fill it with the images.
You should read the Android Documentation covering the External Storage section.
I think it is possible . you can put all images in a asset folder and when you application will start you can copy it to a particular folder in SD Card. Here is the link for copy the database form asset folder to application . You can try it for copy the images form asset folder to SDCard.
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
You can copy images from assets to SDcard
This method copies images from assets folder to your Sdcard .here Jaydeep's Folder is the name of my folder on sdcard.You can use your folder name in that place.
public void copyImagesInSdcard()
{
assetManager = mycontext.getAssets();
assetManager1 = mycontext.getAssets();
System.out.println("In copyImagesInSdcard");
try
{
str1=assetManager.list("");
ss=assetManager1.list(str1[1]);
InputStream is;
//System.out.println(ss[0]);
File file=new File(Environment.getExternalStorageDirectory().getPath() + "/Jaydeep's Folder");
if(file.exists()!=true)
{
file.mkdir();
}
else
{
if(file.length()==0)
{
file.mkdir();
}
System.out.println("Length:"+file.length());
}
for(int i=0;i<ss.length;i++)
{
is=assetManager1.open(str1[1] + "/" + ss[i]);
file=new File(Environment.getExternalStorageDirectory().getPath() + "/Jaydeep's Folder/" + ss[i] );
FileOutputStream out=new FileOutputStream(file);
//Bitmap bi = BitmapDrawable.createFromStream(is,ss[0]);
byte b[] =new byte[4096];
while (is.read(b) != -1) {
out.write(b);
}
out.close();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This can be done by creating zip of all resources and put them in assets folder and then unzip these folder into sdcard using following reference: http://www.jondev.net/articles/Unzipping_Files_with_Android_%28Programmatically%29
In android, I'd like to include a database at the time of installation i.e. in the .apk file. Is it possible to do that? I have some data in a database that I would want to use in the app. I don't want to use OnCreate method to create a database. So, where should I keep my db file so that it is accessible to the app after installation?
create your database file, include it in your assets directory and on first launch of your application copy it to /data/data/PACKAGE_NAME/databases/
This website helped me out greatly.
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
I create my SQLite databases separately, add them to the assets directory in the app package, and then on launch of the app copy the databases into the /data/data/com.company.appname/databases/ directory for use there.
I also check to see if the file already exists before bothering to copy it over (so I generally only copy it on first ever launch).
eg
boolean createDB= false;
File dbDir = new File(DB_PATH);
File dbFile = new File(DB_PATH + DB_NAME);
if(!dbDir.exists())
{
dbDir.mkdir();
createDB = true;
}
else if (!dbFile.exists())
{
createDB = true;
}