Own Database in Assets Folder on Android Eclipse Project - java

I have a big problem in my android application. I'm develop for the first time an android application with a sqlite database but i have problems that i cant solve.
I have my sqlite database on assets folder of eclipse project with name saldb.sqlite
I have the following class to manage Database with Singletone pattern:
package sal.app.logic;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseManager extends SQLiteOpenHelper{
private static DataBaseManager dbManagerInstance = null;
private Context salContext;
private SQLiteDatabase salDatabase;
private static String DB_PATH = "/data/data/sal.app/databases/";
private static String DB_NAME = "saldb.sqlite";
private DataBaseManager(Context c)
{
super(c, DB_NAME, null, 1);
//this.salContext = c;
}
public static DataBaseManager getSalDatabase(Context c)
{
if (dbManagerInstance == null)
{
dbManagerInstance = new DataBaseManager(c);
}
return dbManagerInstance;
}
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");
}
}
}
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;
}
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = salContext.getAssets().open(DB_NAME);
// Path to the just created empty db
//String outFileName = DB_PATH + DB_NAME;
String outFileName = "/data/data/sal.app/databases/saldb.sqlite";
//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;
salDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
#Override
public synchronized void close() {
if(salDatabase != null)
salDatabase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
//db.execSQL("Insert Into Question(_id,level,text,idTopic) Values (1,1,'asa',0)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
public Question getOneQuestion()
{
//list of Versioni, search result with query text
Question quest = new Question();
try
{
//open database to query
openDataBase();
//salDatabase.execSQL("Insert Into Question(_id,level,text,idTopic) Values (1,1,'asa',0)");
//Cursor cursor = salDatabase.rawQuery("SELECT text, idTopic, level from Question WHERE level=2", null);
Cursor cursor = salDatabase.rawQuery("SELECT * from Question", null);
/*Cursor cursor = salDatabase.query("Question",
new String[] { "text","idTopic","level"},
"level=2",
null ,
null,
null,
"RANDOM() LIMIT 1");*/
//Cursor c = db.rawQuery(select, null); */
//mapped all rows to data object
if (cursor.moveToFirst())
{
System.out.println(cursor.getString(2));
do
{
Cursor cursor2 = salDatabase.rawQuery("SELECT * from Topic WHERE _id=0", null);
cursor2.moveToFirst();
Topic t = new Topic(cursor2.getString(1));
quest = new Question(cursor.getString(2),t,(int)cursor.getShort(1));
break;
} while (cursor.moveToNext());
}
//close cursor
cursor.close();
}
catch(Exception ex)
{
System.out.println("DatabaseHelper.search()- : ex " + ex.getClass() +", "+ ex.getMessage());
}
//
return quest;
}
/*public ArrayList<Answer> getAnswersOfQuestion(Questin q)
{
}*/
}
But in first time that i run my application i have de following erros:
05-29 23:55:45.684: D/ddm-heap(221): Got feature list request
05-29 23:55:46.295: D/dalvikvm(221): GC freed 519 objects / 45792 bytes in 109ms
05-29 23:55:46.544: E/Database(221): sqlite3_open_v2("/data/data/sal.app/databases/saldb.sqlite", &handle, 1, NULL) failed
05-29 23:55:46.594: D/AndroidRuntime(221): Shutting down VM
05-29 23:55:46.604: W/dalvikvm(221): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
05-29 23:55:46.604: E/AndroidRuntime(221): Uncaught handler: thread main exiting due to uncaught exception
in my main Activity im doing this:
public class SALActivity extends Activity {
Button back;
Button choiceA;
static int choice = 0;
DataBaseManager db;
//Button choiceB;
//Button choiceC;
//Button choiceD;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.gamemenu);
//db= new DataBaseManager(this);
db=DataBaseManager.getSalDatabase(this);
try {
db.createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//db=DataBaseManager.getSalDatabase(this);
Question q = db.getOneQuestion();
//back = (Button) findViewById(R.id.gaveup_button);
choiceA = (Button) findViewById(R.id.choice_a_button);
choiceA.setTextColor(0xffffffff);
//choiceA.setText("A: Académica");
choiceA.setText(q.getQuestionText());
choiceA.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
//choiceA.setText(10);
//choiceB = (Button) findViewById(R.id.choice_b_button);
//choiceC = (Button) findViewById(R.id.choice_c_button);
//choiceD = (Button) findViewById(R.id.choice_d_button);
//Intent v = new Intent(this, SALActivity.class);
//this.startActivity(v);
}
}
In the second time that i run app, error dont occur, database are in the correct path but only have the table android_metadata
I also could say that if i put the correct dataBase on /data/data/sal.app/databases/ the entire program just works...
The error is in the copyDatabase.

This is my working code to copy database.
private static String DB_PATH = "/data/data/com.demo.databaseDemo/databases/";
private static String DB_NAME = "myDatabase.db";
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();
}//end of copyDataBase() method

You need to create the folder for you database and copy into the folder the first time your app runs. Here is what I do:
// Check to see if database exists, otherwise copy from assets
boolean dbExist = db.databaseExist();
if (!dbExist) {
try {
// See if there is a data directory, otherwise create it
String destPath = "/data/data/" + getActivity().getPackageName() +
"/databases/";
File f = new File(destPath);
if (!f.exists()) {
f.mkdirs();
f.createNewFile();
// Copy from assets to data directory
CopyDB(getActivity().getBaseContext().getAssets().open("myData.sqlite"),
new FileOutputStream(destPath + "/myData.sqlite"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Related

External database access, my app crashes

Yes I have searched for many solutions for days. My still persisting problem is my app crashes at start when I am trying to access an external database (created through "DB Browser for Sqlite" named "test.db").
The sole purpose is of course to prepopulate my app with some data.
I have kept the database file on assets folder in android studio. Finally I have implemented a helper class to access the database.
Here is the helper class:
public class DataBaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
private static String DATABASE_PATH = "";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
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 void createDatabase() throws IOException {
createDB();
}
private void createDB() {
boolean dbExists = checkDatabase();
if (dbExists) {
//do nothing
} else {
this.getReadableDatabase();
try {
copyDatabase();
} catch (IOException ie) {
throw new Error("Error copying database");
}
}
}
private boolean checkDatabase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DATABASE_PATH + DATABASE_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
checkDB.setLocale(Locale.getDefault());
} catch (SQLiteException e) {
throw new Error("SQLite exception");
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null;
}
private void copyDatabase() throws IOException {
InputStream myInput = null;
OutputStream myOutput = null;
String outFileName = DATABASE_PATH + DATABASE_NAME;
try{
myInput = myContext.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 run error ");
}
}
#Override
public synchronized void close() {
if(myDataBase != null){
myDataBase.close();
}
super.close();
}
}
In the Main activity I have just called the createDatabase() method of the helper class. The code being below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DataBaseHelper myDbHelper = new DataBaseHelper(this);
try{
myDbHelper.createDatabase();
}catch (IOException ioe){
throw new Error("Unable to CREATE DATABASE");
}
}
}
The logcat indicates the problem as:
AndroidRuntime: FATAL EXCEPTION: main java.lang.Error: SQLite
exception at DataBaseHelper.checkDatabase(DataBaseHelper.java:79) at
DataBaseHelper.createDB(DataBaseHelper.java:59) at
DataBaseHelper.createDatabase(DataBaseHelper.java:55) at
MainActivity.onCreate(MainActivity.java:18)
which points to my checkDatabase() method. But now I am not able to sort out the problem.
I am using Android Studio 3.0.1, DB Browser for Sqlite 3.10.1, Min API level used 17.
Please Help!
Try This
public static final String DATABASE_NAME = "abc.db";
public final static String DATABASE_PATH = "/data/data/"+ PACKAGE_NAME +
"/databases/";
public static final int DATABASE_VERSION = 1;
public void createDatabase() {
boolean dbExist1 = checkDataBase();
if (!dbExist1) {
this.getReadableDatabase();
try {
this.close();
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
// Check database already exist or not
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;
}
// Copies your database from your local assets-folder to the just created
// empty database in the system folder
public void copyDataBase() throws IOException {
String outFileName = DATABASE_PATH + DATABASE_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
InputStream myInput = mContext.getAssets().open(DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myInput.close();
myOutput.flush();
myOutput.close();
}

onUpgrade() and onCreate() method do not invoke when creating a new version of database in SQLiteOpenHelper

I am trying to create a new version of database in my android app. But although I change the version of database from previous version (2) to a new version (3) it doesn't invoke onUpgrade() and onCreate() . It just invoke three times the constructor. I do not understand why constructor invoked three times and also why onUpgrade() and onCreate() did not invoke?
I also tried with new database version code but result is same.
Here is my code.
public class DatabaseHelper extends SQLiteOpenHelper {
private static String PACKAGE_NAME;
private static String DB_PATH;
private static String DB_NAME = "mydata.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 3);
this.myContext = context;
Log.e("UPDATED3", "CONSTRUCTOR");
PACKAGE_NAME = myContext.getPackageName();
DB_PATH = "/data/data/" + PACKAGE_NAME + "/databases/";
}
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");
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
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();
}
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) {
Log.e("UPDATED3", "ONCREATE");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e("UPDATED3", "UPDATED THE DATABASE");
}
}
I use my database this(showing below) way in any activity.
DatabaseHelper databaseHelper = new DatabaseHelper(getApplicationContext());
try {
databaseHelper.createDataBase();
databaseHelper.openDataBase();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
e.printStackTrace();
}

My Activity cannot be connected with my Database

I have an activity named Awal.java and the code :
public class Awal extends Activity implements OnItemClickListener {
private Cursor kategori;
private MyDatabase db;
private List<String> ktg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new MyDatabase(this, null);
ktg = db.getKategori();
String namaKtg[] = ktg.toArray(new String[ktg.size()]);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(new ArrayAdapter<String>(this, R.layout.list, R.id.label, namaKtg));
listView.setOnItemClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
kategori.close();
db.close();
}
public void onItemClick(AdapterView<?> adapter, View v, int pos, long l) {
Intent intent = new Intent(Awal.this,Detail.class);
intent.putExtra("namaKategori", adapter.getItemAtPosition(pos).toString());
startActivity(intent);
}
}
and also databaseHelper named MyDatabase.java and here is the code :
package com.mroring.belajarperancis;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDatabase extends SQLiteOpenHelper {
// Variable declaration
private static String DB_PATH = "/data/data/com.mroring.belajarperancis/databases/";
public static String DB_NAME = "MY_DATABASE";
private final Context myContext;
private String strMypath;
public MyDatabase(Context context, String DB_NAME) {
super(context, DB_NAME, null, 1);
this.myContext = context;
try {
MyDatabase.DB_NAME = DB_NAME;
} catch (Exception e) {
e.printStackTrace();
}
}
public void createDatabase() throws IOException {
try {
// check if the database exists
boolean dbExist = checkDatabase();
if (!dbExist) {
// database is not present copy databse
this.getReadableDatabase();
try {
copyDatabse(DB_NAME);
} catch (IOException e) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 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() {
try {
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 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.
* */
public void copyDatabse(String DB_NAME) throws IOException {
try {
// Open your local db as the input stream
Input`enter code here`Stream 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 * 2];
int length;
while ((length = myInput.read(buffer)) > 0) {
try {
myOutput.write(buffer, 0, length);
} catch (Exception e) {
}
}
if (myOutput != null) {
myOutput.flush();
myOutput.close();
}
if (myInput != null)
myInput.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* This function is used to open the database
*
* #throws SQLException
*/
public void openDatabase() throws SQLException {
SQLiteDatabase checkDB = null;
// Open the database
try {
strMypath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(strMypath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (Exception e) {
e.printStackTrace();
}
if (checkDB != null) {
checkDB.close();
}
}
public List<String> getKategori() {
String query = "SELECT _id FROM kategori";
List<String> kategori = new ArrayList<String>();
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
//looping through
if (cursor.moveToFirst()) {
do {
kategori.add(cursor.getString(0)); // add id & nama
}
while (cursor.moveToNext());
}
cursor.close();
db.close();
return kategori;
}
public List<List<String>> getDetail(String namaKategori) {
String query = "select pra, ina, baca from kata,kategori where kata.id_kategori=kategori._id and kategori.nama = '"+namaKategori+"'";
List<List<String>> detail = new ArrayList<List<String>>();
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
//looping
if (cursor.moveToFirst()) {
do {
List<String> item = new ArrayList<String>();
item.add(cursor.getString(0)); //add french word
item.add(cursor.getString(1)); //add indonesian word
item.add(cursor.getString(2)); //add baca
detail.add(item);
}
while (cursor.moveToNext());
}
cursor.close();
db.close();
return detail;
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
try {
copyDatabse(DB_NAME);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
And this combination always makes errors and here are the error :
06-18 01:23:01.694: E/AndroidRuntime(17219): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mroring.belajarperancis/com.mroring.belajarperancis.Awal}: android.database.sqlite.SQLiteException: no such table: kategori: , while compiling: SELECT _id FROM kategori
06-18 01:23:01.694: E/AndroidRuntime(17219): Caused by: android.database.sqlite.SQLiteException: no such table: kategori: , while compiling: SELECT _id FROM kategori
I have a database named 'MY_DATABASE' in .../BelajarPerancis/assets/databases/MY_DATABASE and also .../BelajarPerancis/assets/MY_DATABASE (I tried to put the DB in two places).
I have tried to pull the database from DDMS, and it returns the same Database with the same contents/tables and it has table 'Kategori'.
My 'Kategori' table contains the field of '_id' and here is the proof 3 Rows returned from: select nama from kategori; (took 5ms).
You are passing database name as null in line db = new MyDatabase(this, null);
I can not see code to create 'kategori' table
and in query you are trying to get data from table name as 'kategori' String query = "SELECT _id FROM kategori"; which do not exists..
Change db = new MyDatabase(this, null); to
db = new MyDatabase(this, "SOME_DATABASE_NAME");
and then write code to create table in database.
Activity launch is not working because db.getKategori(); is called from onCreate() method and which is throwing exception.
please go through http://www.vogella.com/tutorials/AndroidSQLite/article.html
Hope this helps you !!
Are you sure that you create the database?
I say that because you're using a absolute path to get the file of the database, the best thing to do in that case is create a database as the standard of Google.
here is a good answer, of how do that:
How do I create a database in android?
You can check too the name of your table, if you use with the first letter in uppercase you must use in that way all time.
att.

Empty database being created but copying of tables from Assets not happening

I have packaged a database with my application, and I can see in my File Explorer that the databases folder along with the workoutsDatabase.sqlite file is being created. When I look at the contents of the database, though, the only table in there is the android_metadata table. I have been searching for hours and have seen many people with similar problems, however, I cannot seem to figure out the correct solution.
Can anyone spot why the tables dont seem to copy over? I have validated the workoutsDatabase.sqlite in my assets folder DOES contain the table "workout" and it does have data in it.
WorkoutsDatabaseHelper
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class WorkoutsDatabaseHelper extends SQLiteOpenHelper {
private String DATABASE_PATH = "/data/data/com.rcd.myworkouts/databases/";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "workoutsDatabase.sqlite";
private static final String TABLE_WORKOUTS = "workouts";
private static final String KEY_ID = "_id";
private static final String KEY_WORKOUT_NAME = "workout_name";
private static final String KEY_LAST_NAME = "last_name";
private static final String KEY_FIRST_NAME = "first_name";
private static final String KEY_MIDDLE_NAME = "middle_name";
private static final String KEY_DESCRIPTION = "description";
private static final String KEY_DATE_ADDED = "date_added";
private static final String KEY_WORKOUT = "workout";
private static final String KEY_MEASUREMENT = "measurement";
private static final String KEY_PHOTO = "photo";
private SQLiteDatabase myDatabase;
private final Context myContext;
public WorkoutsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
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();
SQLiteDatabase db_Read = null;
if(dbExist) {
// Do nothing - database already exist
} else {
//By calling this method an 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.
db_Read = getReadableDatabase();
db_Read.close();
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 = DATABASE_PATH + DATABASE_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch(SQLiteException e) {
// Database doesn't exist yet
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* 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 {
getWritableDatabase();
Log.d("Database", "New database is being copied to device!");
try
{
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DATABASE_NAME);
// transfer bytes from the inputfile to the
// Path to the just created empty db
String outFileName = DATABASE_PATH + DATABASE_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes form the inputfile to the output file
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();
Log.i("Database", "New database has been copied to device!");
}
catch(IOException e)
{
e.printStackTrace();
}
}
protected Boolean openDatabase() {
if(checkDatabase())
{
// Open the database
String myPath = DATABASE_PATH + DATABASE_NAME;
try
{
Log.i("Database", "Trying to Open Database!");
if(myDatabase != null)
{
if(!myDatabase.isOpen())
{
Log.i("Database", "Database is closed now opening it!");
myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
else
{
Log.i("Database", "Database is already Open!");
}
Log.i("Database", "Database is Opened successfully in OPEN_READWRITE Mode !");
return true;
}
else
{
myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
Log.i("Database", "Database is Opened successfully in OPEN_READWRITE Mode !");
return true;
}
}
catch(Exception e)
{
Log.e("Database", "Some error occured while opening Database Error:" + e.getMessage());
myDatabase = null;
return false;
}
}
else
try {
copyDatabase();
Log.d("WorkoutsDatabaseHelper.java", "Copy Database..");
} catch (IOException e) {
throw new Error("Error copying database");
}
return false;
}
#Override
public synchronized void close() {
if(myDatabase != null)
myDatabase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

no such table SQLite error could not compile

i have three classes where the flow is..
entering the entry to be searched: (from MainActivity)
try {
String input = etSearch.getText().toString();
Intent i = new Intent(this, SearchViewList.class);
i.putExtra("input", input);
Log.i("input", input + "");
startActivity(i);
} catch (Exception e) {
// TODO: handle exception
String error = e.toString();
Dialog d = new Dialog(this);
d.setTitle("Row Empty or ID not found!");
TextView tv = new TextView(this);
tv.setText(error);
d.setContentView(tv);
d.show();
break;
}
then the class SearchViewList would display the list by the searched value from the intent
Intent i = getIntent();
input = i.getStringExtra("input");
String l = input;
datasource = new DatabaseHelper(this);
datasource.openDataBase();
List<Definition> values = datasource.getSearchedDefinition(l);
// use the SimpleCursorAdapter to show the
// elements in a ListView
ArrayAdapter<Definition> adapter = new ArrayAdapter<Definition>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
ListView listView = getListView();
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
String str = ((TextView) view).getText().toString();
Log.i(str, str + "");
Intent i = new Intent(getApplicationContext(),
SearchedView.class);
i.putExtra("value", str);
startActivity(i);
}
});
then after clicking the searched entry from the list then the error commence
Intent i = getIntent();
l = i.getStringExtra("value");
TextView entry = (TextView) findViewById(R.id.tvEntry);
datasource = new DatabaseHelper(this);
datasource.openDataBase();
String dataEntry = datasource.getEntry(l);
datasource.close();
entry.setText(dataEntry);
}
here is my getEntry() method from the DatabaseHelper class
public String getEntry(String l) throws SQLException {
Cursor c = myDataBase.rawQuery(
"SELECT entry FROM defintionstbl where entry = '"
+ l + "'", null);
if (c != null) {
c.moveToFirst();
if (c.getCount() <= 0) {
return null;
}
String entry = c.getString(0);
return entry;
}
return null;
}
this next method is also from the DatabaseHelper class
public List<Definition> getSearchedDefinition(String l) throws SQLException {
List<Definition> entries = new ArrayList<Definition>();
Cursor cursor = myDataBase.rawQuery(
"SELECT entry FROM definitionstbl where entry like '" + l + "%'", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Definition entry = cursorToDefinition(cursor);
entries.add(entry);
cursor.moveToNext();
}
// make sure to close the cursor
cursor.close();
return entries;
}
private Definition cursorToDefinition(Cursor cursor) {
Definition entry = new Definition();
entry.setId(cursor.getLong(0));
entry.setEntry(cursor.getString(0));
return entry;
}
this method compile just fine but the i am getting a "no such table definitionstbl" error from the method getEntry().
additional note:
database = dictionary.sqlite
table = definitionstbl
column1 = _id
column2 = entry
column3 = definitions
here is the code for the copying of the database from an external source:
public class DatabaseHelper extends SQLiteOpenHelper {
// The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.gtxradeon.newversioncomputerdictionary/databases/";
private static String DB_NAME = "dictionary.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* #param context
*/
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;
}
/**
* 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();
}
public void openDataBase() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
#Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
create table from MainActivity
try {
myDbHelper.createDataBase();
myDbHelperTrivia.createDataBase();
Log.i("CREATING", "DATABASE CREATED");
} catch (Exception e) {
Log.i("CREATE", "Exception Caught! ", e);
}
try {
myDbHelper.openDataBase();
Log.i("OPENING", "DATABASE OPENED");
} catch (SQLException e) {
Log.i("OPEN", "Exception Caught! ", e);
}
thanks for helping guys but i just changed the getEntry method to this.. rawQuery gave alot of error but this new method is good to go..
public String getEntry(String l) throws SQLException {
String[] columns = new String[] { "_id",
"entry", "definition" };
Cursor c = myDataBase.query("definitionstbl", columns,
"entry" + "='" + l + "'", null, null, null, null);
if (c != null) {
c.moveToFirst();
if (c.getCount() <= 0) {
return null;
}
String entry = c.getString(1);
return entry;
}
return null;
}

Categories