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
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();
}
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();
}
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.
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) {
}
}
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;
}