Sqlite database not copied from asset folder Android - android

I am trying to copy a database named "adinpect" from the asset folder to the application databases folder, but it is not working...
Code (in main activity onCreate(), just for testing):
try {
String destPath = "/data/data/" + getPackageName() + "/databases";
File f = new File(destPath);
if (!f.exists()) {
f.mkdirs();
f.createNewFile();
//---copy the db from the assets folder into the databases folder---
CopyDB(getBaseContext().getAssets().open("adinspect"), new FileOutputStream(destPath + "/adinspect"));
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException {
//---copy 1K bytes at a time---
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}//end copyDB
The "databases" folder is created but there in nothing in it, trying to access it by DDMS.
I do not get any errors.
Any suggestion?
Thanks

This code wlll help you to copy DB from assets folder.
You can check first if DB exists or not.
try{
// CHECK IS EXISTS OR NOT
SQLiteDatabase dbe = SQLiteDatabase.openDatabase("/data/data/"+getPackageName+"/databases/dbname.sqlite",null, 0);
dbe.close();
}
catch(Exception e)}
{
// COPY IF NOT EXISTS
AssetManager am = getApplicationContext().getAssets();
OutputStream os = new FileOutputStream("/data/data/"+getPackageName+"/databases/dbname.sqlite");
byte[] b = new byte[100];
int r;
InputStream is = am.open("dbname.sqlite");
while ((r = is.read(b)) != -1) {
os.write(b, 0, r);
}
is.close();
os.close();
}

Related

Suddenly stop copying SQLite Database from assets

I am copying SQLite Database from assets folder to android app. I am using below mentioned code. And it was working fine and I am doing my code smoothly. Suddenly, it stopped copying database to android app.
public class PreCreateDB {
public static void copyDB (Context context) {
try {
String destPath = "/data/data/"+ context.getPackageName()+ "/databases";
File f = new File(destPath);
if (!f.exists()) {
f.mkdir();
rawCopy(context.getAssets().open("dbname.db"), new FileOutputStream(destPath + "/dbname.db"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void rawCopy(InputStream inputStream, OutputStream outputStream) throws IOException{
byte[] buffer = new byte[1024];
int length;
while ((length=inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
}
I found db in Device File Explorer and I see the following lines in it (not whole tables). Kindly help
SQLite format 3  # .�
� � W--ctableandroid_metadataandroid_metadataCREATE TABLE android_metadata (locale TEXT)
� � en_IN
I change my code to the following one, now it's working.
public static void copyDB (Context context) throws IOException {
try (SQLiteDatabase dbe = SQLiteDatabase.openDatabase("/data/data/com.app.example/databases/dbname.db", null, 0)) {
dbe.close();
} catch (Exception e) {
AssetManager am = context.getAssets();
OutputStream os = new FileOutputStream("/data/data/com.app.example/databases/dbname.db");
byte[] b = new byte[100];
int r;
InputStream is = am.open("dbname.db");
while ((r = is.read(b)) != -1) {
os.write(b, 0, r);
}
is.close();
os.close();
}
}

how can i copy file in data directory

i want to copy file from asset to other application data directory.i have also given root acess to it.but this code doesn't work.its work on extenal storage directory .but not copy file in data directory..
public void onClick(View arg1){
String command[] = { "su", "-c", "ls", "/data" };
Shell shell = new Shell();
String text = shell.sendShellCommand(command);
if (new File((Object)Environment.getDataDirectory() + "/data/com.my/shared_pref/com.myxml").exists()) {
Toast.makeText(getApplicationContext(),"copied",Toast.LENGTH_LONG).show();
MainActivity.this.copyAssets();
}
else{
Toast.makeText(getApplicationContext(),"error! copy failed ",Toast.LENGTH_LONG).show();
private void copyAssets()
{
AssetManager assetManager = getAssets();
String[] files = null;
InputStream in = null;
OutputStream out = null;
String filename =
"com.my.xml" ;
try
{
in = assetManager.open( filename);
out = new FileOutputStream((Environment.getDataDirectory().toString() +"/data/com.my/shared_pref/" + filename));
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
}
catch (IOException e)
{
Log. e ( "tag" , "Failed to copy asset file: " , e);
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
if anyone knows how to do it?
Pleaase suggest me.!!
Thanks.!!
This is exactly what you need. This code copies sample.apk from assets to the application data directory. You can change the path to anywhere you want.
private String copyAssets() {
AssetManager assetManager = getActivity().getAssets();
InputStream in = null;
OutputStream out = null;
String filename = "sample.apk";
String path = Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ getActivity().getPackageName()
+ "/files";
try {
in = assetManager.open("files/" + filename);
File outFile = new File(path);
if (!outFile.exists()) {
outFile.mkdirs();
}
out = new FileOutputStream(outFile + "/" + filename);
copyFile(in, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return path + "/" + filename;
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
Use this code. I used this code in my project, Got it on net somewhare, it works.
private void copyDataBase() throws IOException
{
//Open your local db as the input stream
InputStream myInput = _context.getAssets().open(DB_NAME);
// Path to 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();
}

import/export to android sqlite database

Ive seen a few posts on how to import and export a database in android and i found these code, but i cant seem to make it work. I get the error java.io.filenotfoundexception /storage/sdcard0/BackupFolder/DatabaseName:open failed ENOENT (no such file or directory). Ive changed a few things but i still get no file found exception
here is my export:
private void exportDB() {
try {
db.open();
File newFile = new File("/sdcard/myexport");
InputStream input = new FileInputStream(
"/data/data/com.example.mycarfuel/data
bases/MyDatabase");
OutputStream output = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
db.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and my import:
private void importDB() {
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath = "//data//" + "PackageName"
+ "//databases//" + "DatabaseName";
String backupDBPath = "/BackupFolder/DatabaseName
";
File backupDB = new File(data, currentDBPath);
File currentDB = new File(sd, backupDBPath);
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getBaseContext(), backupDB.toString(),
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
.show();
}
}
SQlite database to our local file system-
Function declaration-
try {
backupDatabase();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Function defined-
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();
}
Above accepted answer will not work for Android version on or above 6 because database path is different.
please check below code . It will work on all devices.
public static boolean exportDB(Context context) {
String DATABASE_NAME = "my.db";
String databasePath = context.getDatabasePath(DATABASE_NAME).getPath();
String inFileName = databasePath;
try {
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
String outFileName = Environment.getExternalStorageDirectory() + "/" + DATABASE_NAME;
OutputStream output = new FileOutputStream(outFileName);
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();
return true;
} catch (Exception e) {
return false;
}
}

Copy Database from assets folder in unrooted device

I am trying to copy DB from assets folder to device. This code is working fine on Emulator and rooted Device. I just want to know is it create any problem on unrooted device or it will work same.
private void StoreDatabase() {
File DbFile = new File(
"data/data/packagename/DBname.sqlite");
if (DbFile.exists()) {
System.out.println("file already exist ,No need to Create");
} else {
try {
DbFile.createNewFile();
System.out.println("File Created successfully");
InputStream is = this.getAssets().open("DBname.sqlite");
FileOutputStream fos = new FileOutputStream(DbFile);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
System.out.println("File succesfully placed on sdcard");
// Close the streams
fos.flush();
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This will work for sure in all devices and emulator, no need to root.
/**
* 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(String dbname) throws IOException {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(dbname);
// Path to the just created empty db
File outFileName = myContext.getDatabasePath(dbname);
// 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();
}
/**
* Copy database file from assets folder inside the apk to the system database path.
* #param context Context
* #param databaseName Database file name inside assets folder
* #param overwrite True to rewrite on the database if exists
* #return True if the database have copied successfully or if the database already exists without overwrite, false otherwise.
*/
private boolean copyDatabaseFromAssets(Context context, String databaseName , boolean overwrite) {
File outputFile = context.getDatabasePath(databaseName);
if (outputFile.exists() && !overwrite) {
return true;
}
outputFile = context.getDatabasePath(databaseName + ".temp");
outputFile.getParentFile().mkdirs();
try {
InputStream inputStream = context.getAssets().open(databaseName);
OutputStream outputStream = new FileOutputStream(outputFile);
// transfer bytes from the input stream into the output stream
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
// Close the streams
outputStream.flush();
outputStream.close();
inputStream.close();
outputFile.renameTo(context.getDatabasePath(databaseName));
} catch (IOException e) {
if (outputFile.exists()) {
outputFile.delete();
}
return false;
}
return true;
}
I am not sure, but this works on every device I have tested on. I stole this method (from somewhere here) and made it generic for both backing up and restoring:
public static void movedb(File srcdb, File destdb)
{
try
{
if (Environment.getExternalStorageDirectory().canWrite())
{
if (srcdb.exists())
{
FileChannel src = new FileInputStream(srcdb).getChannel();
FileChannel dst = new FileOutputStream(destdb).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
else
{
//ERROR: "Database file references are incorrect"
}
}
else
{
//ERROR: "Cannot write to file"
}
}
catch (Exception e)
{
//ERROR: e.getMessage()
}
}
Then I just back it up by calling:
movedb(this, getDatabasePath(getDbName()), new File(Environment.getExternalStorageDirectory(), getDatabaseBackupPath()));
Where getDatabasePath() and getDatabaseBackupPath() are just string values
private void copyDataBase(Context context) throws IOException {
//Log.i(TAG, "Opening Asset...");
// Open your local db as the input stream
InputStream myInput = context.getAssets().open(DBHelper.DATABASE_NAME);
// Log.i(TAG, "Getting db path...");
// Path to the just created empty db
File dbFile = getDatabasePath(DBHelper.DATABASE_NAME);
if (!dbFile.exists()) {
SQLiteDatabase checkDB = context.openOrCreateDatabase(DBHelper.DATABASE_NAME, context.MODE_PRIVATE, null);
if (checkDB != null) {
checkDB.close();
}
}
//Log.i(TAG, "Getting output stream...");
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(dbFile);
// Log.i(TAG, "Writing data...");
// 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();
}
This works for Kotlin.
assets.open("sqlite_db_in_assets.db")
.copyTo(getDatabasePath("sqlite_db_in_device.db").outputStream())
While technically feasible, I don't believe copying (either to or from) potentially live database file is a good idea.

SQLiteException when copying/decompressing a zipped DB onto Android

Currently, I am copying a database from my assets folder to the to the /data/data/package folder. This is that code (from the answer here), which works:
public void copyDataBase() throws IOException{
// open db as input stream
InputStream myInput;
//open empty db as output stream
OutputStream myOutPut;
try {
myInput = myContext.getAssets().open(DB_NAME);
//path to newly created db
String outFileName =DB_PATH + DB_NAME;
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);
}
myOutPut.flush();
myOutPut.close();
myInput.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Now in order to save space in the .apk download, I am trying to zip the file before copying it to the /data/data/package folder.
private void copyDataBaseFromZipFile() {
InputStream inputStream = null;
OutputStream outputStream = null;
String sourcePathname = this.getBundledPathname();
String destinationPath = this.getDatabasePathname();
try {
inputStream = this.mContext.getAssets().open(sourcePathname);
ZipInputStream zipStream = new ZipInputStream(inputStream);
int BUFFER = 8096;
outputStream = new FileOutputStream(destinationPath);
BufferedOutputStream dest = new BufferedOutputStream(outputStream, BUFFER);
ZipEntry entry;
while ((entry = zipStream.getNextEntry()) != null) {
if (entry.getName().equals("androidDB.sql")) }
int count;
byte data[] = new byte[BUFFER];
while ((count = zipStream.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
}
}
outputStream.flush();
outputStream.close();
dest.flush();
dest.close();
zipStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
When I attempt to open the database later (with SQLiteDatabse), I get this error: android.database.sqlite.SQLiteException: unable to open database file
I haven't changed anything except the file I'm copy from, which is only a zipped version of the one I was previously copying over. The final database is the right size, so it doesn't seem to be still compressed... If anyone has any suggestions or possible reasons WHY it won't open, it would be greatly appreciated.
You should remove these lines:
outputStream.flush();
outputStream.close();
Your BufferedOutputStream probably has some buffered bytes, but since you close outputStream before you call dest.flush(), those bytes are never actually written to the file.

Categories

Resources