0

My app creates a database the moment it runs, and stores some basic data in it. However, when I try to run the app on the device, I am getting "Unable to open database" error, while it is working and is fully functional on the emulator.

my main activity is

import android.app.Activity;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;

public class MainActivity extends Activity
{

@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.i("sarhad","Initializing data");
    DatabaseHelper db = new DatabaseHelper(this);
    Cursor cursor;
    ListView listSongs;
    SimpleCursorAdapter adapter;
    final String[] FROM = { db.KEY_SONGNAME, db.KEY_ARTISTNAME, db.KEY_LABELNAME };
    final int[] TO = { R.id.textViewSONG, R.id.textViewARTIST, R.id.textViewLABEL };    

    try
    {
        db.openDataBase();

    } catch (SQLException sqle)
    {
        throw sqle;
    }


    listSongs = (ListView) findViewById(R.id.listSongsView);

    db.getWritableDatabase();

    Log.i("tag","Initializing query");
    String queryStr = "SELECT * FROM songs";

    Log.i("tag","before : cursor = db.getSongs(queryStr);");
    cursor = db.getSongs(queryStr);
    Log.i("tag","after : cursor = db.getSongs(queryStr);");

     startManagingCursor(cursor);

     adapter = new SimpleCursorAdapter(this, R.layout.row, cursor, FROM,TO);
     listSongs.setAdapter(adapter);
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

}

and my databasehelper class is

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper
{
static final int DATABASE_VERSION = 1;

public static String DB_PATH = "";

// Database Name
static final String DATABASE_NAME = "songsDB";

// Contacts table name
static final String TABLE_SONGS = "songs";

// Contacts Table Columns names
static final String KEY_ID = "_id";
static final String KEY_SONGNAME = "songname";
static final String KEY_ARTISTNAME = "artistname";
static final String KEY_LABELNAME = "labelname";

private SQLiteDatabase db = null;
private final Context myContext = null;

private static DatabaseHelper mDBConnection;

//////////////////////////////////////////////////////////////////////////////////

public DatabaseHelper(Context context)
{
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    DB_PATH = "/data/data/" + context.getApplicationContext().getPackageName() + "/databases/";
}

//////////////////////////////////////////////////////////////////////////////////

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db)
{
    String CREATE_SONGS_TABLE = "CREATE TABLE " + TABLE_SONGS + "("
            + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_SONGNAME
            + " TEXT," + KEY_ARTISTNAME + " TEXT," + KEY_LABELNAME
            + " TEXT);";
    db.execSQL(CREATE_SONGS_TABLE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_SONGS);
    onCreate(db);
}

//////////////////////////////////////////////////////////////////////////////////


void addSong(String song, String singer, String label)
{
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_SONGNAME, song);
    values.put(KEY_ARTISTNAME, singer);
    values.put(KEY_LABELNAME, label);

    db.insert(TABLE_SONGS, null, values);
    db.close(); 
}

public Cursor getSongs(String queryStr)
{
    return db.rawQuery(queryStr, null);

}

///////////////////////////////////////////////////////////////////////

public SQLiteDatabase openDataBase() throws SQLException
{
    String myPath = DB_PATH + DATABASE_NAME;
    db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    return db;
}

/**
 * Close the database if exist
 */
@Override
public synchronized void close()
{
    if (db != null)
        db.close();
    super.close();
}

}

Dan Jurgen
  • 927
  • 1
  • 8
  • 13
  • You should give more information on your targeted platform and the language that you are using. – CM Kanode Dec 04 '12 at 15:45
  • @CMKanode. I posted the code. Please have a look. I am working on API 10. – Dan Jurgen Dec 04 '12 at 15:47
  • You may find it helpfull: http://stackoverflow.com/questions/9109438/how-to-use-an-existing-database-with-an-android-application/9109728#9109728 – Yaqub Ahmad Dec 04 '12 at 15:51
  • Thanks for your replies. however the issue was not there. I now solved the issue. while calling : DatabaseHelper db = new DatabaseHelper(this); yes, you are allocating space for the db that will be created, however, the db will not be in the PATH until you apply a query on it. in my case I applied a add query (method in my helper class) and it was only after that when my DB was found in the path and I was able to access it. have this in mind while errors like this, always try to apply a dummy query on it at first if things dont work. – Dan Jurgen Dec 04 '12 at 16:37

1 Answers1

2

I think you messed up the path and the real device won't let you put a file in that location, while the emulator will. Try removing the path entirely and letting the system figure out where to put the database. Once you know it works like that, then you can go back and modify the path if you need to.

Khantahr
  • 8,156
  • 4
  • 37
  • 60
  • Indeed, one should not presume to know what the path of the application's private directory will be. The guess might be right on most devices today, but perhaps not on all or always. However this might or might not be the cause of the failure seen here. – Chris Stratton Dec 04 '12 at 16:05
  • Thanks for your replies. however the issue was not there. I now solved the issue. while calling : DatabaseHelper db = new DatabaseHelper(this); yes, you are allocating space for the db that will be created, however, the db will not be in the PATH until you apply a query on it. in my case I applied a add query (method in my helper class) and it was only after that when my DB was found in the path and I was able to access it. have this in mind while errors like this, always try to apply a dummy query on it at first if things dont work. – Dan Jurgen Dec 04 '12 at 16:31
  • I must ask why you're defining a path anyway. You can use the `getReadableDatabase` and `getWriteableDatabase` methods in the `SQLiteOpenHelper` class to open databases and not worry about path or name at all. Avoids many potential errors and device specific problems. If you must define the path, I'd suggest using [`getFilesDir()`](http://developer.android.com/reference/android/content/Context.html#getFilesDir()) instead of hard coding it to ensure that it will work and also that it will get cleaned up when the user uninstalls your app. – Khantahr Dec 04 '12 at 17:48