working with external data base in android programing with eclipse - java

i'm a beginner in java and android. now i want to work with external database (cancer.db).
i created "DataBaseHelper" class.
public class DataBaseHelper extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";
private static String DB_NAME = "myDBName";
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;
}
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) {
}
// 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.}
then i use codes below in "on create" method to create or open database:
private static String DB_PATH = "/data/data/info.myprogram/databases/";
private static String DB_NAME = "cancer.db";
DataBaseHelper myDbHelper = new DataBaseHelper();
myDbHelper = new DataBaseHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
i use these codes to get query. my table name is "shb":
SQLiteDatabase db;
Cursor cc= db.rawQuery("SELECT Name FROM shb WHERE _id=1",null);
cc.moveToFirst();
String sss=cc.getString(1);
now when i start debugging i get errors. what's the wrong code? whats my mistake? how should i get query?
and excuse me for my weak English, because it's not my mother tongue .

First create a sqlite database and create table inside it, put it in assets folder of your app.use that database by using following code. please make changes in code for your datbaseName, tableName, fieldsName and path of database etc. i have also write the code of getting list of data by passing paerticuler value.
public class MySQLiteHelper extends SQLiteOpenHelper {
public static final String TABLE_CARS = "Cars";
public static final String COL_ENAME = "ename";
public static final String COL_MODAL = "modal";
public static final String COL_ANAME = "aname";
public static final String COL_TYPES = "types";
private static final String TAG = "MSSS : DatabaseHelper";
// Your Database Name
private static final String DATABASE_NAME = "4saleCars.sqlite";
// Your Your Database Version
private static final int DATABASE_VERSION = 1;
private final Context myContext;
private SQLiteDatabase myDataBase;
// The Android's default system path of your application database. DB_PATH =
// "/data/data/YOUR_PACKAGE/databases/"
private String DB_PATH = "/data/data/net.forsalemall.android/databases/";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
try {
createDataBase();
} catch (Exception e) {
Log.e(TAG,
"DatabaseHelper_constuctor createDataBase :"
+ e.fillInStackTrace());
}
}
#Override
public void onCreate(SQLiteDatabase database) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// ***************************** My DB Handler Methods
// *****************************
/**
* Creates a empty database on the system and rewrites it with your own
* database.
**/
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
// Database already exist
openDataBase();
} 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.
myDataBase = getWritableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error createDataBase().");
}
}
}
/**
* 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 + DATABASE_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;
}
/*
* public boolean isDataBaseExist() { File dbFile = new File(DB_PATH +
* DATABASE_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 transferring bytestream.
**/
private void copyDataBase() throws IOException {
try {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DATABASE_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DATABASE_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();
} catch (IOException e) {
throw new Error("Error copyDataBase().");
}
}
public void openDataBase() throws SQLException, IOException {
try {
// Open the database
String myPath = DB_PATH + DATABASE_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
throw new Error("Error openDataBase().");
}
}
// ***************************** My DML Methods
// *****************************
public List<String> getModalList(String aname, Context context) {
List<String> list = new ArrayList<String>();
list.add(context.getResources().getString(R.string.all));
Cursor cursor;
String query;
query = "SELECT modal FROM Cars WHERE aname = '" + aname + "';";
try {
cursor = myDataBase.rawQuery(query, null);
if (cursor != null) {
while (cursor.moveToNext())
list.add(Utils.getDecodedString(cursor.getString(0)));
}
cursor.deactivate();
} catch (Exception e) {
Log.e(TAG, "getModalList Error : " + e.fillInStackTrace());
}
return list;
}
}
use this getModalList in your activity just like below
MySQLiteHelper dbHelper = new MySQLiteHelper(
AdvanceSearchActivity.this);
String aname = Utils.getEncodedString(catName);
car_modal = dbHelper.getModalList(aname,AdvanceSearchActivity.this);

Related

SQLite helper classes for each table issues

I am using an SQLite db in my android application and I setup helper classes for each table in the db. There are many tables and these classes just handle all the crud methods for each table. I followed example #6 here
I'm having an issue when there are multiple instances of the helper classes instantiated. The database is only available when one helper class is instantiated at a time.
public class ProjectsHelper {
SQLiteDatabase db;
DataBaseHelper dbHelper;
private String TABLE_NAME = "Projects";
public ProjectsHelper(Context context){
if(dbHelper == null){
dbHelper = new DataBaseHelper(context);
}
}
public void open() throws SQLException {
try {
if(!isOpen()){
db = dbHelper.getWritableDatabase();
}
} catch (Exception e){
e.printStackTrace();
}
}
private boolean isOpen(){
return db != null && db.isOpen();
}
public void close() {
if(isOpen()){
dbHelper.close();
db.close();
dbHelper = null;
db = null;
}
}
public long insert(Project obj){
ContentValues values = new ContentValues();
values.put("ProjName", obj.getProjName().trim());
if(!Utilities.empty(obj.getProjDesc())){
values.put("ProjDesc", obj.getProjDesc().trim());
}
if(!Utilities.empty(obj.getProjNumber())){
values.put("ProjNum", obj.getProjNumber().trim());
}
values.put("ServerID", obj.getServerID());
values.put("GUID", obj.getGUID());
values.put("ModDate", obj.getModDate());
long id = db.insert(TABLE_NAME, null, values);
return id;
}
}
public class DataBaseHelper extends SQLiteOpenHelper {
//The Android's default system path of your application database.
public static String DB_PATH = "/data/data/com.siscoders.arscompnentinspector/databases/";
public static String DB_NAME = "ARSInspection.db";
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;
try {
createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
//openDataBase();
}catch(SQLException sqle){
throw sqle;
}
}
/**
* 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);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
#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) {
}
}

Android SQLiteException: cannot rollback - no transaction is active [duplicate]

my app experiences a crash when the sqlite database is updated the first time. Reloading the app, it works fine from then on. I'm guessing this has to do with the onUpgrade function then. I can't seem to locate where the problem is, any advice very appreciated. Thanks in advance.
DatabaseHelper:
public class DatabaseHelper extends SQLiteOpenHelper {
private static String DB_PATH = "/data/data/jp.atomicideas.ne/databases/";
private static String DB_NAME = "dataset";
public static final int DB_VERSION = 2;
private SQLiteDatabase myDataBase;
private final Context myContext;
public static final String EXPRESSION_TABLE = "expression";
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access
* the assets and resources.
*
* #param context
*/
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.myContext = context;
}
/**
* Creates an empty database on the system and rewrites with database from app
* #throws IOException
*/
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
// if the database already exists, do nothing
if(dbExist){
Log.v("DB Exists", "db exists");
// by calling this method here, onUpgrade will be called on a writeable db, if version number is bumped
this.getWritableDatabase();
}
dbExist = checkDataBase();
// if the database doesn't exist, copy the application's database to be used
if(!dbExist) {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exists to avoid re-copying the file
* #return true only if it exists, falls if it doesnt
*/
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 not exist yet
}
if(checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies database from the local assets folder to the system folder
* #throws IOException
*/
private void copyDataBase() throws IOException {
// Open the app database file as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the empty temporary database to be replaced
String outFileName = DB_PATH + DB_NAME;
// Open the empty database file as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes from the input file 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();
}
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) {
Toast.makeText(myContext, "onUpgrade called!", Toast.LENGTH_LONG).show();
if (oldVersion < newVersion) {
Log.v("Database Upgrade", "Database version higher, upgrading");
myContext.deleteDatabase(DB_NAME);
}
}
}
And here is the LogCat output:
06-28 20:52:07.638: V/DB Exists(26580): db exists
06-28 20:52:07.658: V/Database Upgrade(26580): Database version higher, upgrading
06-28 20:52:07.658: I/Database(26580): sqlite returned: error code = 1802, msg = statement aborts at 3: [PRAGMA user_version = 2]
06-28 20:52:07.658: E/Database(26580): Failure 10 (disk I/O error) on 0x33a3f0 when executing 'PRAGMA user_version = 2'
06-28 20:52:07.658: I/Database(26580): sqlite returned: error code = 1, msg = statement aborts at 2: [ROLLBACK;] cannot rollback - no transaction is active
06-28 20:52:07.658: E/Database(26580): Failure 1 (cannot rollback - no transaction is active) on 0x33a3f0 when executing 'ROLLBACK;'
06-28 20:52:07.658: D/Database(26580): exception during rollback, maybe the DB previously performed an auto-rollback
06-28 20:52:07.668: D/AndroidRuntime(26580): Shutting down VM
06-28 20:52:07.668: W/dalvikvm(26580): threadid=1: thread exiting with uncaught exception (group=0x2aac8578)
AND
06-28 20:52:07.678: E/AndroidRuntime(26580): Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error: PRAGMA user_version = 2
You don't need to delete the database, just copy over it using the method you've alady defined (copyDataBase), like this:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Toast.makeText(myContext, "onUpgrade called!", Toast.LENGTH_LONG).show();
if (oldVersion < newVersion) {
Log.v("Database Upgrade", "Database version higher, upgrading");
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error upgrading database");
}
}
}

How should my onUpgrade() method look like?

You can see my database helper class below. I use prepopulated sqlite database imported in assets folder. Whenever I add a table to my existing database, I get no such table error if my app is already installed on my phone. I guess my onUpgrade() method is now so good. It works, don't get me wrong, when I change some data to existing tables, I increase db version and it gets updated. But if I add a table I get error.
public class DataBaseHelper extends SQLiteOpenHelper
{
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "/data/data/rs.androidaplikacije.themostcompleteiqtest/databases/";
private static String DB_NAME ="pitanja.sqlite";// Database name
private static SQLiteDatabase mDataBase;
private final Context mContext;
private static final int DATABASE_VERSION = 3;
public DataBaseHelper(Context mojContext)
{
super(mojContext, DB_NAME, null, 3);// 1 it's Database Version
DB_PATH = mojContext.getApplicationInfo().dataDir + "/databases/";
this.mContext = mojContext;
}
public void createDataBase() throws IOException
{
//If database not exists copy it from the assets
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
/**
* 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
*/
public 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;
}
/*Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
*/
//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase arg0) {
}
#Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
try {
// delete existing?
// Copy the db from assests
copyDataBase();
Log.e(TAG, "database updated");
} catch (IOException mIOException) {
Log.e(TAG, mIOException.toString());
try {
throw mIOException;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
There's 2 ways to do onUpgrade, depending on your app.
1)Drop all your old tables, then run onCreate. THis basically wipes out all your old data and starts over. Its a good technique if you can regenerate the old data somehow, or just don't care about it.
2)Carefully maintain a diff of your schema between each released version, and write SQL statements to make the proper changes between them- add new tables, alter existing tables to add/remove columns, etc. This is time consuming and fragile, so use this only if you need to keep data between those versions.

Android application force closing on device

On the Emulator the app runs fine. On the device the moment im trying to copy my database over the application's database and execute a query the app force closes. Any idea why this could be happening? Do i have to request any kind of permissions or something in manifest for it to run?
Database.Java
public class Database extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/gr.BHC.www/databases/";
//Name of the Database to be created.
private static String DB_NAME = "BHCLibrary3.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 Database(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{
//First we check if the database already exists, Method declared later
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exists
}else{
//By calling this method an empty database will be created into the default system path
//of your application so we are going to be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase(); //Method declared later
} 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;
boolean checkdb = false;
try{
String myPath = DB_PATH + DB_NAME;
File dbfile = new File(myPath);
//checkdb = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READWRITE);
checkdb = dbfile.exists();
}
catch(SQLiteException e){
System.out.println("Database doesn't exist");
}
return checkdb;
}
/**
* 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 transferring byte stream.
* */
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();
}
//Opening the Database
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
//Finally overriding a few methods as required
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
//First we check if the database already exists, Method declared later
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exists
}else{
//By calling this method an empty database will be created into the default system path
//of your application so we are going to be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase(); //Method declared later
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
And Results.java (The activity i run my query)
public class SearchResults extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.searchresults);
Database myDbHelper = new Database(null);
myDbHelper = new Database(this);
}
// Get the intent, verify the action and get the query
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
SQLiteDatabase myDb = myDbHelper.getReadableDatabase();
//Executing our query against the server using rawQuery and getting the cursor
String select="SELECT DISTINCT b._ISBN as _id, b.BookTitle, b.Edition, b.Year, b.Pages, b.Rating, c.Category, p.Publisher, w.LastName" +
" FROM" +
" Books b" +
" JOIN Categories_Books cb ON cb._Books_ISBN = _id" +
" JOIN Categories c ON c._CategoryID = cb._Categories_CategoryID" +
" JOIN Publishers p ON p._PublisherID = b.PublisherID" +
" JOIN Writers_Books wb ON wb._Books_ISBN = _id" +
" JOIN Writers w ON w._WriterID = wb._Writers_WriterID" +
" WHERE b.BookTitle LIKE '%" + query +"%'" +
" OR c.Category LIKE '%" + query +"%'" +
" OR p.Publisher LIKE '%" + query +"%'" +
" OR w.LastName LIKE '%" + query +"%'" +
" OR _id LIKE '%" + query +"%'" +
" GROUP BY b.BookTitle";
Cursor c = myDb.rawQuery(select, null);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books.BookTitle", "Publishers.Publisher" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
//Getting results into our listview
try
{
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
}
catch( Exception e)
{
}
}
}
Help would be appreciated.
EDIT: The error im getting is : java.lang.runtimeexception: Unable to start activity Componentinfo(gr.BHC.www/gr.BHC.www.SearchResults} and then various exceptions saying table books etc dont exist.
EDIT2: I saw the exception im getting usually related with content providers but i still cant figure out why i'd get that.
I think I solved the problem. I made some changes on your codes and now it is working. Here are the codes:
SearchResults.java
public class SearchResults extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.searchresults);
DbManager myDbHelper = new DbManager(null);
myDbHelper = new DbManager(this);
// Get the intent, verify the action and get the query
myDbHelper.createNewDatabase();
try {
myDbHelper.open();
Log.d("Search Results", "database opened");
} catch (SQLException sqle) {
throw sqle;
}
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
// Executing our query against the server using rawQuery and getting the
// cursor
String select = "SELECT DISTINCT b._ISBN as _id, b.BookTitle, b.Edition, b.Year, b.Pages, b.Rating, c.Category, p.Publisher, w.LastName"
+ " FROM"
+ " Books b"
+ " JOIN Categories_Books cb ON cb._Books_ISBN = _id"
+ " JOIN Categories c ON c._CategoryID = cb._Categories_CategoryID"
+ " JOIN Publishers p ON p._PublisherID = b.PublisherID"
+ " JOIN Writers_Books wb ON wb._Books_ISBN = _id"
+ " JOIN Writers w ON w._WriterID = wb._Writers_WriterID"
+ " WHERE b.BookTitle LIKE '%"
+ query
+ "%'"
+ " OR c.Category LIKE '%"
+ query
+ "%'"
+ " OR p.Publisher LIKE '%"
+ query
+ "%'"
+ " OR w.LastName LIKE '%"
+ query
+ "%'"
+ " OR _id LIKE '%"
+ query
+ "%'"
+ " GROUP BY b.BookTitle";
Cursor c = myDbHelper.rawQ(select);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books.BookTitle",
"Publishers.Publisher" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
// Getting results into our listview
try {
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
} catch (Exception e) {
}
}
}
And your new database helper, DbManager:
DbManager.java
public class DbManager extends SQLiteOpenHelper {
private static final String DB_NAME = "BHCLibrary3.sqlite";
private static final String DB_PATH = "/data/data/gr.BHC.www/databases/";
private static final Integer DB_VERSION = 1;
private static final String TAG = "DbManager";
private final Context context;
private SQLiteDatabase db;
private DbManager dbManager;
public DbManager(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE 'notes' (_id integer primary key autoincrement, title text not null);");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public DbManager open() {
dbManager = new DbManager(context);
db = dbManager.getWritableDatabase();
return this;
}
public void createNewDatabase() {
InputStream assetsDB = null;
try {
assetsDB = context.getAssets().open(DB_NAME);
OutputStream dbOut = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
Log.i(TAG, "New database created...");
} catch (IOException e) {
Log.e(TAG, "Could not create new database...");
e.printStackTrace();
}
}
public Cursor rawQ(String select) {
return db.rawQuery(select, null);
}
}
Looks like the size of your database exceeds one MB. In that case you need to store it in the assets folder as .jpg and then copy it over. This is because Android places a restriction on the size of the text assets.

Android sqlite creating database error

i am newbie with android sqlite database. now i just try to create my custom database manager and i got the error at oncreate() function. I already spent 3 days to figure it out but unfortunately i am still stuck in it. Any brilliant idea would be appreciate.
public class DBManager extends SQLiteOpenHelper {
private SQLiteDatabase db;
private static Context myContext;
public static final String DB_NAME = "goldenland.db";
public static final String TB_CAT = "tbl_categories";
public static final String TB_ARTICLE = "tbl_articles";
public static final String TB_SUBCAT = "tbl_subcategories";
public static final String TB_SCHEDULE = "tbl_schedule";
public static final String TB_CONTENT = "tbl_contents";
public static final String TB_CITY = "tbl_cities";
public static final String name = "name";
public static String DB_PATH = "/data/data/com.gokiri.goldenland/databases/";
public DBManager(Context context) {
super(context, DB_NAME, null, 1);
DBManager.myContext = context;
}
public void createDataBase() throws IOException {
boolean dbExit = checkDataBase();
if (dbExit) {
System.out.println("Testing");
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDb = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLException e) {
}
if (checkDb != null) {
checkDb.close();
}
return checkDb != null ? true : false;
}
public void copyDataBase() throws IOException {
InputStream myInput = myContext.getAssets().open("goldenland_2.sqlite");
String outFileName = DB_PATH + DB_NAME;
OutputStream 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();
}
public void openDatabase() throws SQLiteException {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
A few things might be wrong. Does your database really exist in res/assets? Are you writing to the correct directory? Stepping through with the debugger would go a long way toward diagnosing the problem.
You might get a sanity check by having copyDatabase take a String argument, which would be this.getReadableDatabase().getPath(). You might even try writing that out to the log to see if you're writing to the correct database directory.
Few things to check.
1. in method checkDataBase open the database in OPEN_READONLY mode.
2. this is very important check that the size of the database is less than 1 mb. Android version previous to 3.0 don't allow file copy of more than 1 mb.
Update:
You will need to split the database file into parts of 1Mb each, copy all parts one by one and join them together again. refer to following link
unless you didnt put up all your code, it seems to me that you are missing somethings. I used this tutorial and had no problems
http://www.devx.com/wireless/Article/40842/1954
hope that helps

Categories