I am developing my android application using Netbeans and java. When I am using the emulator I can access the File explorer and insert an SQLite database in to device internal memory by accessing the following path, data/data/com.example.helloandroid/database
But I can not access this location to push the SQLite File in to the phone's internal storage (location) when I am using the real device.
Can someone please help me how to add the file in to phones internal storage. Thanks
I think the device doesn't have root permission, that's why you can't access it. If you want to do in your app with programmatically then it is possible. If anybody knows better then this please share it.
EDIT: ok, first of all,
1. copy your Database.db file in your projects assets folder.
2. now using code copy database file from /asset to device's internal storage
(data/data/<package name>/database folder).
For copy file use below code,
try {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open("your database file name");
// Path to the just created empty db
String outFileName = "/data/data/<your_app_package_name>/databases/<database_file_name>";
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
catch (Exception e)
{
Log.e("error", e.toString());
}
Related
I need a local database for my application.I created one and i encrypted it.(I know the password).Now i want to load this db to my original application.I want to decrypte it before copy. I had a copy code like this this is working for unencrpyted db. How can I translate this for my encrypted db.Thanks
private void copyDataBase() throws IOException {
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
Looking on the wiki on DB Browser for SQLite repo, DB Browser uses SQLCipher as a default encryption extension, so I assume that you have used the default SQLCipher extension. This means that to use that encrypted DB file on Android, you need to use SQLCipher's Android Port.
More examples and documentation can be found in their Android Repo and here.
Update:
This update explains a sample setup for using SQLiteCipher.
Add SQLCipher dependency in your application's build.gradle file:
compile net.zetetic:android-database-sqlcipher:3.5.7#aar
Initialize SQLCipher's native library before performing any db ops by calling:
net.sqlcipher.database.SQLiteDatabase.loadLibs(context)
(optional, recommended) Create an implementation of:
net.sqlcipher.database.SQLiteOpenHelper or, better yet, make your existing SQLiteOpenHelper extend from this class
Then whenever you request a database (getReadableDatabase() or getWriteableDatabase()), supply your encryption password with it, e.g.,
SQLiteDatabase db = helper.getReadableDatabase(_PASSWORD_)
See more details on this gist.
Also, in your case you need to copy the encrypted database from the raw assets folder to the path returned by calling Context.getDatabasePath() for the first time your app is run.
Hope this explains the things to you,
Regards
I create a table in sqlite database I am doing all the CRUD operation but I want to see my database schema . I try through DDMS tool of eclipse IDE but there is no database. How can I see my database.i am using real device. Please Help me.
Thanks in advance
You can use this method:
STEP 1: First export the database by writing function :
public static void backupDatabase() throws IOException {
//Open your local db as the input stream
String inFileName = "/data/data/com.myapp.main/databases/MYDB";
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
String outFileName = Environment.getExternalStorageDirectory()+"/MYDB";
//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();
}
Taken from Stack overflow link
Then download DB Browser for SQLite and open database file there.DB Browser for SQLite
And you are good to go.Inform me if you found any difficulties while implementing this.
In a real device you cannot access the SQLite DB unless ur phone is rooted.. in a virtual device however you can access it. but there is no way u can see the actual schema. all you see is some text files and once you open them up your columns(data fields) are separated by tabs or something. so
How can I see my database? YOU CAN'T
Only rooted real device can be access using some jar in eclipse. Other wise you can seed database structure in emulator from DDMS Respective. To know how to do this.
Please red this to solve your problem.
I have made an android app. I am using database in it. I have installed the .apk file on my phone and it works fine. But it does not show me any data I entered in database while I was on emulator. I need to use database tables filled previously. My database does not create on run time. How can I get the database on my phone to see app running perfectly fine with the database?
You can save your database file under assets or res/raw directory, on the app's first startup, copy that database file to /data/data/com.company.yourapp/databases/, and open your database like usual.
The difference between saving files under assets and res/raw directories is that files under res/raw are compressed, while files under assets are not. And files under res/raw cannot exceed 1 MB before Android 2.3. So I'd suggest that you compress your database file yourself and save it to assets and in your code decompress the file using GZIPInputStream.
If you need your database out side the application for testing then i think you should export it into your sdcard.
public static void exportfile(String applicationPackageName,String databaseName,String pathOfFolder) throws FileNotFoundException, IOException
{
InputStream myInput;
myInput = new FileInputStream("/data/data/"+applicationPackageName+"/databases/"+databaseName);
File directory = new File("/sdcard"+pathOfFolder);
if (!directory.exists())
{
directory.mkdirs();
}
OutputStream myOutput = new FileOutputStream(directory.getPath()+"/"+databaseName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0)
{
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
applicationPackageName :- application package name
databaseName :- database file name
pathOfFolder :- path of folder where to export the file in sdcard
don't forget to add <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> in your manifest file.
And download any SQLite Manager to open that file.
Thanks.. hope it helps you.
All i need to bind .db and .apk at run time in single .apk so user can download and run the application. i don't neeed to . db in assets ,raw ,URL path because we need to Change the .db at run time and we Have so many user and for different user we have different .db. it is ERP based Application. thanks in advance
You put the .db into your /raw/ directory.
Then at runtime you copy this into a new database that is located in your applications memory, which is then modifiable.
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
The code is not mine and is an exert from the full tutorial at: Using your own DB in Android
If your looking to put different database files in your /raw/ you might want to use multiple APK's now that the market allows it or make an ant script for selecting a different DB when the APK is built.
One of my applications downloads a database from a server.
When I install the application onto my phone, it downloads the file correctly and loads the information, no exceptions thrown or anything.
However, when I upload the apk into the Android Market Place and download it onto the phone, the application downloads the database and then crashes, saying that the sqlite handler was not able to open up the database.
Here's the progression of code:
In the SQLiteOpenHelper:
this.FULL_DB_PATH = new String(this.getWritableDatabase().getPath());
this.getWritableDatabase();
// Code for retrieving the database off of the server:
private void copyDataBase(){
InputStream myInput=null;
OutputStream myOutput=null;
try{
// opening connections
URL url = new URL("server_url_here");
URLConnection ucon=url.openConnection();
myInput = ucon.getInputStream();
myOutput = new FileOutputStream(this.FULL_DB_PATH);
// write to the db here
byte[] buffer = new byte[1024*1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
catch(Exception e)
{
try{
myOutput.flush();
myOutput.close();
myInput.close();
}
catch(Exception es){}
}
}
I don't know why my colleague is saving the db with a mp3 extension but...it works when we're installing the apk ad-hoc.
For:
myOutput = new FileOutputStream(this.FULL_DB_PATH);
I've also tried:
myOutput = this.getApplicationContext().openFileOutput(this.FULL_DB_PATH, Context.MODE_WORLD_READABLE);
But that doesn't work either.
Any help is greatly appreciated!! I've been tearing my hair out for a couple of hours over this and I just want it to end haha.
What you are doing is copying the file into the /data folder in the android file system. On a normal phone with normal permissions this is not allowed for security reasons. You can do this on the emulator and rooted phones because you have been granted permission to write to /data (normally only read).
To get around this you will need to manually add the information to the database using db.insert(String, String, ContentValues) and db.update(String, ContentValues, String, String[])
It would be nice to be able to do what you are trying but for security reasons it's a very good thing you can't.
The Emulator gives you special access that real phones don't. In other words, I suspect you are directly copying the file into the databases directory on the phone? If so, you can't do that on a non-rooted phone. Hopefully someone will chime in and prove me wrong because this is a problem for me too. I'd like to easily download a db file and install it. What I end up having to do as a work-around is create a new database and load the schema and data through queries.
EDIT:
I would like to share a trick with you. It's simple really. Instead of using just db.insert/db.update/ by themselves, scope them into transactions. In fact, I would scope the whole DB Build as a transaction, or at least just individual tables. I've experienced a 10-50x increase in speed of transactions when they're scoped and then committed all at once.
The other two answers are incorrect, I do believe. I have a backup system in my app where backups are copied to the sd-card, and then copied back to the /data/-folder when the backup is restored. While I have no idea why your code wont work, here is my code to copy the database from the sd-card:
final InputStream in = new FileInputStream(from);
final OutputStream out = new FileOutputStream(to);
final byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
Just to closer investigare the error, try to download to the sd-card instead and then use my code to copy it to the data-folder. The "to" object in my code I get like this:
public static final String DATABASE_PATH = "/data/data/"+SomeClass.class.getPackage().getName()+"/databases/"+ DATABASE_NAME;
final File to = new File(Constant.DATABASE_PATH);