how to use pre-loaded sqlite database [Android Studio] [duplicate] - java

This question already has answers here:
Ship an application with a database
(15 answers)
Closed 6 years ago.
recently i am trying to build an application that can open existing SQLite database using Android Studio, and i am still a newbie on android programming...when i was searching for the way to open the database, i found this link :
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
btw i still don't know how to implement the code on that link into my project...is there anyone here who is kind enough to help make the examples (or at least give some direction) about how to use it? Just a simple example is really enough for me...thx before :)

You can just use new DBManager().getAllCities() in activity.
/**
* author zaaach on 2016/1/26.
*/
public class DBManager {
private static final String ASSETS_NAME = "china_cities.db";
private static final String DB_NAME = "china_cities.db";
private static final String TABLE_NAME = "city";
private static final String NAME = "name";
private static final String PINYIN = "pinyin";
private static final int BUFFER_SIZE = 1024;
private String DB_PATH;
private Context mContext;
// public static DBManager init(){
// if (mInstance == null){
// synchronized (DBManager.class){
// if (mInstance != null){
// mInstance = new DBManager();
// }
// }
// }
// return mInstance;
// }
public DBManager(Context context) {
this.mContext = context;
DB_PATH = File.separator + "data"
+ Environment.getDataDirectory().getAbsolutePath() + File.separator
+ context.getPackageName() + File.separator + "databases" + File.separator;
}
#SuppressWarnings("ResultOfMethodCallIgnored")
public void copyDBFile(){
File dir = new File(DB_PATH);
if (!dir.exists()){
dir.mkdirs();
}
File dbFile = new File(DB_PATH + DB_NAME);
if (!dbFile.exists()){
InputStream is;
OutputStream os;
try {
is = mContext.getResources().getAssets().open(ASSETS_NAME);
os = new FileOutputStream(dbFile);
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = is.read(buffer, 0, buffer.length)) > 0){
os.write(buffer, 0, length);
}
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public List<City> getAllCities(){
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH + DB_NAME, null);
Cursor cursor = db.rawQuery("select * from " + TABLE_NAME, null);
List<City> result = new ArrayList<>();
City city;
while (cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex(NAME));
String pinyin = cursor.getString(cursor.getColumnIndex(PINYIN));
city = new City(name, pinyin);
result.add(city);
}
cursor.close();
db.close();
Collections.sort(result, new CityComparator());
return result;
}
}

Related

data inserted into external sqlite database but not saving in android studio

I'm using an external sqlite database rather than creating one in my android studio project since the database will have some already populated data in it. But I have to insert some more data as well.
And when I insert any new data, it shows the new data but as I close my android app and open again to see the data, the newly inserted data through the app are somehow deleted, only prepopulated data are shown.
I am using DB browser for sqlite to create the external sqlite database and pre-populate it with some data there. In my android studio project, I added this database into my assets folder and implemented SQLiteOpenHelper class to access this database. Reading the data from the database table is a success. Now as I insert new data I can read the new data temporarily as well. Temporarily in the sense that after i close my app the new data are lost.
the table of my external sqlite database:
CREATE TABLE `table_name` (
`Id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`Content` TEXT NOT NULL
);
SQLiteOpenHelper class:
public class ProcessExternalDBHelper {
private static final String DATABASE_NAME = "database_name.db";
private static final int DATABASE_VERSION = 1;
private static String DATABASE_PATH = "";
private static final String DATABASE_TABLE = "table_name";
private static final String KEY_ROWID = "Id";
private static final String KEY_CONTENT = "Content";
private ExternalDbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class ExternalDbHelper extends SQLiteOpenHelper {
public ExternalDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
if (Build.VERSION.SDK_INT >= 17) {
DATABASE_PATH = context.getApplicationInfo().dataDir +
"/databases/";
} else {
DATABASE_PATH = "/data/data/" + context.getPackageName() +
"/databases/";
}
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
}
}
public ProcessExternalDBHelper(Context context) {
ourContext = context;
}
//for reading
public ProcessExternalDBHelper openRead() throws SQLException {
ourHelper = new ExternalDbHelper(ourContext);
ourDatabase = ourHelper.getReadableDatabase();
return this;
}
//for writing
public ProcessExternalDBHelper openWrite() throws SQLException{
ourHelper = new ExternalDbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close() {
if (ourHelper != null) {
ourHelper.close();
}
}
//Create database in activity
public void createDatabase() throws IOException {
createDB();
}
//Create db if not exists
private void createDB() {
boolean dbExists = checkDatabase();
if (!dbExists) {
openRead();
try {
this.close();
copyDatabase();
} catch (IOException ie) {
throw new Error("Error copying database");
}
}
}
private boolean checkDatabase() {
boolean checkDB = false;
try {
String myPath = DATABASE_PATH + DATABASE_NAME;
File dbfile = new File(myPath);
checkDB = dbfile.exists();
} catch (SQLiteException e) {
}
return checkDB;
}
private void copyDatabase() throws IOException {
InputStream myInput = null;
OutputStream myOutput = null;
String outFileName = DATABASE_PATH + DATABASE_NAME;
try {
myInput = ourContext.getAssets().open(DATABASE_NAME);
myOutput = new FileOutputStream(outFileName);
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 ie) {
throw new Error("Copydatabase() error");
}
}
//To show all available contents in my database
public List<Model> findallContents() {
List<Model> mContents = new ArrayList<>();
String[] columns = new String[]{KEY_CONTENT};
Cursor cursor = ourDatabase.query(DATABASE_TABLE, columns, null, null,
null, null, null);
int iContent = cursor.getColumnIndex(KEY_CONTENT);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
{
Model model= new Model();
model.setContent(cursor.getString(iContent));
mContents.add(model);
}
cursor.close();
return mContents;
}
public void addContent(String content) {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_CONTENT, content);
ourDatabase.insert(DATABASE_TABLE, null, contentValues);
ourDatabase.close();
}
}
My Model.java class:
public class Model {
private String mContent;
public String getContent() {
return mContent;
}
public void setContent(String content) {
this.mContent = content;
}
}
Finally my activity class where i read and write the data:
public class MainActivity extends AppCompatActivity {
private EditText editText_Content;
private ImageButton imageButton_Save;
private List<Model> mContentsArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ProcessExternalDBHelper myDbHelper = new ProcessExternalDBHelper(this);
try {
myDbHelper.createDatabase();
} catch (IOException ioe) {
throw new Error("Unable to CREATE DATABASE");
} finally {
myDbHelper.close();
}
initialize();
GetContents();
imageButton_Save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!(editText_Content.getText().toString().trim().isEmpty()))
{
SaveContents();
}
}
});
}
private void initialize() {
editText_Content = findViewById(R.id.editText_contents);
imageButton_Save = findViewById(R.id.imageButton_save);
mContentsArrayList = new ArrayList<>();
}
//GetContents and show them later in my RecyclerView
private void GetContents() {
try {
mContentsArrayList.clear();
ProcessExternalDBHelper autoProcess = new
ProcessExternalDBHelper(this);
autoProcess.openRead();
mContentsArrayList.addAll(autoProcess.findallContents();
autoProcess.close();
} catch (Exception e) {
}
}
//For saving content into database
private void SaveContents() {
String content = editText_Content.getText().toString();
try {
ProcessExternalDBHelper autoProcess = new
ProcessExternalDBHelper(this);
autoProcess.openWrite(); //for writing into database
autoProcess.addContent(content);
autoProcess.close();
editText_Content.getText().clear();
} catch (Exception e) {
}
}
}
Finally I am using DB Browser for Sqlite (ver 3.10.1), android studio (ver 3.0.1), minSdkVersion 19.
I am expecting the newly inserted data into the database to be saved and later seen even when i close my app and and restart the app later. Thank You!
Your issue is that DATABASE_PATH isn't being reset and is therefore empty when createDatabase is invoked.
Therefore the check to see if the database exists fails to find the database (it's looking purely for the file database_db.db at the highest level of the file system, as such the file will not exist) and the database is copied overwriting the database that has data saved into it.
I'd suggest the following changes :-
private boolean checkDatabase() {
File dbfile = new File(ourContext.getDatabasePath(DATABASE_NAME).getPath());
if ( dbfile.exists()) return true;
File dbdir = dbfile.getParentFile();
if (!dbdir.exists()) {
dbdir.mkdirs();
}
return false;
}
This has the advantage that if the databases directory doesn't exist that it will be created and that it relies solely on the database name for the path.
There is also no need for the try/catch construct.
and optionally :-
private void copyDatabase() throws IOException {
InputStream myInput = null;
OutputStream myOutput = null;
String outFileName = ourContext.getDatabasePath(DATABASE_NAME).getPath(); //<<<<<<<<<< CHANGED
try {
myInput = ourContext.getAssets().open(DATABASE_NAME);
myOutput = new FileOutputStream(outFileName);
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 ie) {
throw new Error("Copydatabase() error");
}
}
Note if the above are applied there is no need for the SDK version check as the getDatabasePath method gets the correct path.

TessAPI Error during processing. in Spring Mvc and tomcat 7

I am using Tesseract ocr in Spring MVC to convert some images in searchable pdf files.
I used tessApi with tessrenderresult that works perfectly fine in simple java project. But, it is not working in spring MVC project while I am deploying it in tomcat 7. I am getting error in line :
int result = api.TessBaseAPIProcessPages1(handle, imagepath, null, 0,
renderer);
I am getting following Exception
Error during processing.
Below is my code :
public class ImageToPDF {
private static String datapath = "F:/Projects Dev/Pfe Projects/GedWeb/.";
private static String language = "fra";
private static TessAPI api;
private static TessBaseAPI handle;
public ImageToPDF() {
super();
api = new TessDllAPIImpl().getInstance();
handle = api.TessBaseAPICreate();
}
public void finalize() throws Throwable {
super.finalize();
}
public void convert(String imagepath) {
File file = new File(imagepath);
String nomfile = FilenameUtils.removeExtension(file.getName());
String parentfolder = file.getParent();
String output = parentfolder + File.separator + nomfile + ".txt";
int set_only_init_params = FALSE;
int oem = TessOcrEngineMode.OEM_DEFAULT;
PointerByReference configs = null;
int configs_size = 0;
String[] params = { "load_system_dawg", "tessedit_char_whitelist" };
String vals[] = { "Relevé", "" }; // 0123456789-.IThisalotfpnex
PointerByReference vars_vec = new PointerByReference();
vars_vec.setPointer(new StringArray(params));
PointerByReference vars_values = new PointerByReference();
vars_values.setPointer(new StringArray(vals));
NativeSize vars_vec_size = new NativeSize(params.length);
api.TessBaseAPISetOutputName(handle, output);
int rc = api.TessBaseAPIInit4(handle, datapath, language, oem, configs,
configs_size, vars_vec, vars_values, vars_vec_size,
set_only_init_params);
System.out.println(rc);
if (rc != 0) {
api.TessBaseAPIDelete(handle);
System.err.println("Could not initialize tesseract.");
return;
}
TessResultRenderer renderer = api.TessHOcrRendererCreate();
api.TessResultRendererInsert(renderer, api.TessBoxTextRendererCreate());
api.TessResultRendererInsert(renderer, api.TessTextRendererCreate());
String dataPath = api.TessBaseAPIGetDatapath(handle);
api.TessResultRendererInsert(renderer,
api.TessPDFRendererCreate(dataPath));
api.TessResultRendererBeginDocument(renderer, imagepath);
int result = api.TessBaseAPIProcessPages1(handle, imagepath, null, 0,
renderer);
api.TessResultRendererEndDocument(renderer);
System.out.println(handle.toString());
System.out.println(renderer.toString());
if (result == FALSE) {
System.err.println("Error during processing.");
return;
}
File file1 = new File(imagepath);
String parent = file1.getParent();
String nomfile1 = FilenameUtils.removeExtension(file1.getName());
String outputbase = parent + File.separator + nomfile1;
for (; renderer != null; renderer = api
.TessResultRendererNext(renderer)) {
String ext = api.TessResultRendererExtention(renderer).getString(0);
System.out
.println(String
.format("TessResultRendererExtention: %s\nTessResultRendererTitle: %s\nTessResultRendererImageNum: %d",
ext, api.TessResultRendererTitle(renderer)
.getString(0),
api.TessResultRendererImageNum(renderer)));
PointerByReference data = new PointerByReference();
IntByReference dataLength = new IntByReference();
result = api
.TessResultRendererGetOutput(renderer, data, dataLength);
if (result == TRUE) {
if (ext.equals("pdf")) {
int length = dataLength.getValue();
byte[] bytes = data.getValue().getByteArray(0, length);
try {
File file3 = new File(outputbase + "." + ext);
// create parent dirs when necessary
if (file3.getParentFile() != null) {
file3.getParentFile().mkdirs();
}
FileOutputStream bw = new FileOutputStream(
file3.getAbsoluteFile());
bw.write(bytes);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
String result1 = data.getValue().getString(0);
}
}
}
api.TessDeleteResultRenderer(renderer);
api.TessBaseAPIDelete(handle);
}
}
Any suggestion?

Copying data on assets folder to data folder of application throws no such file or directory error

I'm using the code below to copy the data containing files and folders with subfolders in them to data directory of my application but I get exception telling the destination location does not exist however FileOutputStream method should make the destination folders according to javadoc for this method:
Constructs a new FileOutputStream that writes to path. The file will be truncated if it exists, and created if it doesn't exist.
the code is :
private void copyFileOrDir(String path) {
AssetManager assetManager = this.getAssets();
String assets[] = null;
try {
assets = assetManager.list(path);
if (assets.length == 0) {
copyFile(path);
} else {
String fullPath = "/data/data/" + this.getPackageName() + "/" + path;
File dir = new File(fullPath);
if (!dir.exists())
dir.mkdir();
File innerDir;
for (int i = 0; i < assets.length; ++i) {
copyFileOrDir(path + "/" + assets[i]);
}
}
} catch (IOException ex) {
Log.e("tag", "I/O Exception", ex);
}
}
private void copyFile(String filename) {
AssetManager assetManager = this.getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
String newFileName = "/data/data/" + this.getPackageName() + "/" + 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) {
//getting exception here...
Log.e("mgh", e.getMessage());
}
}
logcat errors are like below for any folder :
09-06 15:14:20.981: E/mgh(19262): /data/data/ir.example.sampleapplication/pzl/ui/css/main.css: open failed: ENOENT (No such file or directory)
/*I m using this code for copy data from assets folder just try it */
public class DataBaseHelper extends SQLiteOpenHelper{
private static String DB_PATH = "/data/data/com.astrobix.numerodaily/databases/";
private static String DB_NAME = "Astrobix";
private static final String tag = "DatabaseHelperClass";
public static SQLiteDatabase myDataBase;
public final Context myContext;
public static String Table_Name="Prediction";
public static final String COL_ID="ID";
public static final String COL_HEAD="HEAD";
public static final String COL_VALUE="VALUE";
private static final String TABLE_QUESTIONS ="Prediction";
private static final String Create_Table="create table if not exists "
+Table_Name
+"("
+COL_ID
+" INTEGER primary key autoincrement , "
+COL_HEAD
+" TEXT, "
+COL_VALUE
+ " VARCHAR); ";
// public static String lastrecord;
// public static String ratio="7:7";
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//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();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
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;
/* File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();*/
}
/**
* 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("Astrobix.sqlite");
// 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();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE );
}
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(Create_Table);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (db != null)
onCreate(db);
}

Reading a text file from the assets folder in android [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Trouble with reading file from assets folder in Android
Hey I'm trying to read a file from the assets folder in android and this is what i have so far
public class TestingMusicDAO {
private static final String TAG_NAME = "MUSIC_TESTING_DAO";
private static List<Song> songs;
private ContentResolver contentResolver;
private static Context testingcontext;
private File fFile;
InputStream inputStream = null;
public TestingMusicDAO( Context context) throws IOException{
Log.d(TAG_NAME, "Setting up testing songs");
contentResolver = context.getContentResolver();
testingcontext = context;
getAllSongsFromFile();
}
public static void getAllSongsFromFile() throws IOException{
Log.d( TAG_NAME, "Tryign to Get all Songs" );
InputStream is;
is = testingcontext.getAssets().open("testing");
Log.d( TAG_NAME, "Did that work?" );
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(is));
String inputLine;
while((inputLine = bufferReader.readLine()) != null){
processLine(inputLine);
}
bufferReader.close();
}
private static void logSongs() {
for(Song song : songs)
Log.d( TAG_NAME, song.toString() );
}
public List<Song> getAllSongs() {
return songs;
}
public static void processLine(String aLine) {
Scanner scanner = new Scanner(aLine);
scanner.useDelimiter("=");
if(scanner.hasNext()){
String title = scanner.next();
String artist = scanner.next();
String album = scanner.next();
String id = scanner.next();
String albumId = scanner.next();
String trackOrder = scanner.next();
Log.d(TAG_NAME, "Title = " + title + "Artist = " + artist + "Album = " + album + "ID = " + id + "AlbumID = " + albumId);
}
else {
Log.d(TAG_NAME, "Empty or invalid line. Unable to process");
}
}
}
So I basically call the TestingMusicDAO constructor and from there I want to read each line of the file individually to be able to parse them but it keeps giving me a FileNotFoundExecption: testing. Any ideas would be great thanks!
Peter,
Assuming that the exception is coming from the is = testingcontext.getAssets().open("testing"); line, then you do not have a file named testing in the root of your assets/ folder.

Can't copy SQLite database from assets

I try to copy SQLite database from assets directory to access it later. But I fail to do it!
public class DatabaseAdapter {
private static String DB_PATH = "/data/data/com.mypackage/databases/";
private static String DB_NAME = "database.sqlite";
private static String TABLE_NAME = "content_table";
private SQLiteDatabase database = null;
private final Context context;
public DatabaseAdapter(Context context){
this.context = context;
}
private void openDatabase() throws SQLiteException{
DatabaseHelper databaseHelper = new DatabaseHelper(context, DB_NAME);
SQLiteDatabase db = null;
if(!checkDatabase()){
try{
//Tried to create db before copying, so file should exist
db = databaseHelper.getReadableDatabase();
db.close();
copyDatabase();
}catch(IOException exception){
Log.d("DatabaseAdapter", "Error copying DB: "+exception);
}
}
database = SQLiteDatabase.openDatabase(DB_PATH+DB_NAME, null, SQLiteDatabase.OPEN_READONLY);
}
private void closeDatabase(){
database.close();
}
public ArrayList<String> queryCategories(){
try{
openDatabase();
}catch(SQLiteException exc){
exc.printStackTrace();
}
//.............................
return result;
}
private boolean checkDatabase(){
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
private void copyDatabase() throws IOException{
InputStream inputStream = context.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer))>0){
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
}
}
DatabaseHelper is simple:
ublic class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name){
super(context, name, null, 1);
}
#Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
Tried everything! I tried playing with extention! But I still get an error:
Error copying DB: java.io.FileNotFoundException: /data/data/com.mypackage/databases/database.sqlite (No such file or directory)
I checked on emulator, my file is there, so I should be able to write to it!
Please, any help! It's driving me nuts!
UPD I tried to place it on SD card and it worked. But still can't get why I can't write it to app data folder.
I use this Helper and works fine:
public class DBHelper extends SQLiteOpenHelper{
private final static String DB_PATH = "/data/data/[YOUR PACKAGE HERE]/databases/";
String dbName;
Context context;
File dbFile;
public DBHelper(Context context, String dbName, CursorFactory factory,
int version) {
super(context, dbName, factory, version);
this.context = context;
this.dbName = dbName;
dbFile= new File(DB_PATH + dbName);
}
#Override
public synchronized SQLiteDatabase getWritableDatabase() {
if(!dbFile.exists()){
SQLiteDatabase db = super.getWritableDatabase();
copyDataBase(db.getPath());
}
return super.getWritableDatabase();
}
#Override
public synchronized SQLiteDatabase getReadableDatabase() {
if(!dbFile.exists()){
SQLiteDatabase db = super.getReadableDatabase();
copyDataBase(db.getPath());
}
return super.getReadableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
private void copyDataBase(String dbPath){
try{
InputStream assestDB = context.getAssets().open("databases/"+dbName);
OutputStream appDB = new FileOutputStream(dbPath,false);
byte[] buffer = new byte[1024];
int length;
while ((length = assestDB.read(buffer)) > 0) {
appDB.write(buffer, 0, length);
}
appDB.flush();
appDB.close();
assestDB.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
Take into account that the file extension of a database is .db and that my databases are into assets/databases/
I have the same problem and I have fixed it with another approach.
At the beginning, I declared the database path as everyone did:
dbPath="data/data/<my package name>/databases/data.db"
This is an exactly path, no mistake. But It' always fail when I try to open the OutPutFileStream to copy database. I don't know why. And then, I change the way to open the database as below:
dbPath = context.getDatabasePath(dbName);
OutputStream myOutput = new FileOutputStream(dbPath.getAbsolutePath());
The problem has ben solved. So surprise.
Hope this helps.
public static void copyDatabase(final Context ctx, String dbName) {
if (ctx != null) {
File f = ctx.getDatabasePath(dbName);
if (!f.exists()) {
// check databases exists
if (!f.getParentFile().exists())
f.getParentFile().mkdir();
try {
InputStream in = ctx.getAssets().open(dbName);
OutputStream out = new FileOutputStream(f.getAbsolutePath());
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
Logger.i("Database copy successed! " + f.getPath());
} catch (Exception ex) {
Logger.e(ex);
}
}
}
}
Please check the databases folder before your OutputStream.
like this,
File databaseFile = new File(context.getFilesDir().getAbsolutePath()
.replace("files", "databases"));
// check if databases folder exists, if not create it.
if (!databaseFile.exists()){
databaseFile.mkdir();
}

Categories

Resources