Not able to fetch data from Sqlite Database
Asked Answered
H

3

6

I want to fetch data from SQLITE database and display it in a LIST.

My database name is AppDB.db and table name is Scrip which contains 3 columns _id(primary key) and symbol&company_name which are text.

I want to fetch only 2nd and 3rd column. I have copied database in Assets folder.

I get force close when I execute following code but I don't know what might be the reason. Please help..

I'm absolute beginner to Android, so any help appreciated...

Contents:

1.) DataAttach.java

2.) DbManager.java

3.) LogCat

4.) .xml in brief

5.) AVD Problem

6.) Snapshot of database


1.) DataAttach.java

public class DataAttach extends Activity {
    private DbManager dbM;
    private Cursor c;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            dbM = new DbManager(this);
            dbM.createDataBase();
            dbM.openDB();

            try {
                c = dbM.fetchAllData();
            } catch (Exception e) {
                throw new Error("\n\nERROR Fetchin data\n\n");
            }

            if (c != null) {
                SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                        this,
                        android.R.layout.simple_list_item_1,
                        c,
                        new String[] { c.getString(c.getColumnIndex("_id")),
                                c.getString(c.getColumnIndex("symbol")),
                                c.getString(c.getColumnIndex("company_name")) },
                        new int[] { R.id._id, R.id.symbol, R.id.company_name });
                ListView list = (ListView) findViewById(R.id.MainLayout);
                list.setAdapter(adapter);
            }
        }

        catch (Exception e) {
            throw new Error("\n\nERROR DB failure\n\n");
        }

        finally {
            c.close();
            dbM.close();
        }
    }
}     

2.) DbManager.java

public class DbManager extends SQLiteOpenHelper {

    private static final String KEY_ROWID = "_id";
    private static final String KEY_SYMBOL = "symbol";
    private static final String KEY_COMPANY_NAME = "company_name";

    private static final String DATABASE_NAME = "AppDB";
    private static final String DATABASE_PATH = "/data/data/com.dbexample/databases/";
    private static final Integer DATABASE_VERSION = 3;
    private static final String DATABASE_TABLE = "Scrip";
    // private static final String TAG = "DbManager";
    private final Context ctx;
    private SQLiteDatabase mDb;

    public DbManager(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.ctx = context;
    }

    /*
     * Creates a empty database on the system and rewrites it with your own
     * database.
     */
    public void createDataBase() {

        if (checkDataBase()) {
            // 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 can overwrite
             * that database with our database.
             */
            this.getReadableDatabase();

            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("\n\nERROR copying database\n\n");
            }
        }
    }

    /*
     * Check if the database already exist to avoid re-copying the file each
     * time you open the application.
     */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DATABASE_PATH + DATABASE_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {
            throw new Error("\n\nERROR database does't exist yet\n\n");
        }

        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /*
     * Copies your DB from your local assets-folder to the just created empty DB
     * in the system folder, from where it can be accessed and handled.
     */
    private void copyDataBase() throws IOException {
        /* Open your local db as the input stream */
        InputStream myInput = ctx.getAssets().open(DATABASE_NAME);

        /* 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 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();
    }

    public void openDB() throws SQLException {
        String myPath = DATABASE_PATH + DATABASE_NAME;
        mDb = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    }

    @Override
    public void close() {
        mDb.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

    public Cursor fetchAllData() {
        return mDb.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_SYMBOL,
                KEY_COMPANY_NAME }, null, null, null, null, null);

        // return mDb.rawQuery("select _id,symbol,company_name from Scrip",
        // new String[] { KEY_ROWID,KEY_SYMBOL, KEY_COMPANY_NAME });
    }
}                                

3.) LOG CAT

sqlite3_open_v2("/data/data/com.dbexample/databases/AppDB", &handle, 1, NULL) failed

Failed to open the database. closing it.
    
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file
    
at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
    
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1017)              

4.) Main.xml

It contains RelativeLayout having 3 TextViews within RelativeLayout.


5.) I ALWAYS GET THIS ERROR

Even after reopening the eclipse, restarting the system, recreating the AVD, trying, kill_server and start_server, I get this message.

Failed to install DataAttach.apk on device 'emulator-5554': device not found
com.android.ddmlib.InstallException: device not found
Launch canceled!            

6.) SCREENSHOT of DB :

Screenshot

WHOLE DOC EDITED TO LATEST CODE AND ACC. TO YOUR SUGGESTIONS, but still app doesn't work.

Halhalafian answered 25/11, 2011 at 11:47 Comment(5)
SimpleCursorAdapter always need _id.so try fetching _id too in your cursor.Hellenistic
@Hiral - tried, but same prob :(Halhalafian
But then problem might something else too including this one..bcz you will always need _id to be passes to SimpleCursorAdapter.Hellenistic
agreed. Tried closing unclosed cursor. but that too didn't worked. btw, Thnx !!Halhalafian
WHOLE DOC EDITED TO LATEST CODE AND ACC. TO YOUR SUGGESTIONS, but still app doesn't work.Halhalafian
E
3

I don't know what you are trying to do with this function. You're trying to read a .db file and say the DB is created. First time when you try to run there won't be a .db file in the database path. That is why the 'No such File or Directory' error is thrown.

11-25 12:06:13.398: E/Netd(31): Unable to bind netlink socket: No such file or directory

In the DBManager Constructor call the SQLiteOpenHelper's getReadableDatabase() which will create a db if there is not one. SQLiteOpenHelper

 public void createNewDatabase() {
                InputStream assetsDB = null;
                try {
                    assetsDB = context.getAssets().open(DATABASE_NAME);
                    OutputStream dbOut = new FileOutputStream(DATABASE_PATH
                            + DATABASE_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...");
                }
            }
Embree answered 25/11, 2011 at 12:17 Comment(13)
ya. Try calling getReadableDatabase() method in the constructor. Hoping it will workEmbree
ya have it in the constructor. anyway ur open method is non static method. So for sure u will create an object to call it. Having the statement in the constructor will be goodEmbree
I should have mentioned this in the previous comment itself. U dont need the open method at all. Just have the getReadableDatabase() in the constructor which will create a db if it s not thre. open it if already there. Use that instance to do all ur db related functionsEmbree
Hope u have tried adb -devices command in command prompt? Is it able to find the emulator-5554. If it is able to find, try installing the apk manually through command prompt.Embree
got it.It's adb install DataAttach.apk but as soon as I get device not found exception, my device list(by using adb devices command) becomes empty and it fails to install the apkHalhalafian
Interesting but only thing which I can think of is to kill the process adb.exe in Task Manager and then try it.. If it doesn't work then some expert should help us.Embree
Did u try killing the abd process?Embree
Close all ur emulators and command prompt where u gave adb commands. After doing this if u find any adb.exe process running terminate it. Dont run the app and do it. It will then give forceful terminationEmbree
done exactly the same i.e. Closed all emulators and command prompt where i give adb commands. After doing this i found an adb.exe process running, so i terminated it. wat next?Halhalafian
after i do above steps, it shows [2011-11-29 15:28:51 - DeviceMonitor]Adb connection Error:An existing connection was forcibly closed by the remote host [2011-11-29 15:28:52 - DeviceMonitor]Connection attempts: 1 till 11. and then i check task manager, there is adb.exe againHalhalafian
#7411795 #2794456 Look at these linksEmbree
can u mail me at [email protected]. We will chat it outEmbree
The foolish mistake I done is to create /data/data/com.dbexample/databases/ directory manually and placing my DB in it. Actually I was supposed to copy my database straight into assets folder.Halhalafian
R
2

SimpleCursorAdapter needs _id field in the Cursor you pass to it. So try to change your query like this:

return mDb.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_SYMBOL, KEY_COMPANY_NAME }, null, null, null, null, null);

Also you are getting:

android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

Make sure you call close() on all Cursor objects you use when you are done with them.

Ricard answered 25/11, 2011 at 12:1 Comment(2)
after closing the cursor and passing ID, it still gives the same prob. Thanks anyways !Halhalafian
WHOLE DOC EDITED TO LATEST CODE AND ACC. TO YOUR SUGGESTIONS, but still app doesn't work.Halhalafian
H
2

I think,you need to set the layout file as:

SimpleCursorAdapter sca=new SimpleCursorAdapter(context, android.R.layout.simple_list_item_1, c, from, to);

Because you are passing R.layout.main which is giving you error in reloading same layout file.

I am not sure,but this might be the problem. Also add _id in your cursor passed to adapter.

Hellenistic answered 25/11, 2011 at 12:17 Comment(2)
WHOLE DOC EDITED TO LATEST CODE AND ACC. TO YOUR SUGGESTIONS, but still app doesn't work.Halhalafian
@GAMA: sorry...i have no idea then! :(Hellenistic

© 2022 - 2024 — McMap. All rights reserved.