NullPointerException while opening database through a fragment - android

I am trying to populate the ListFragment from one of the columns in my Database.
For that i am trying to use
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
db.open();
db = new NotesDatabase(getActivity());
c = db.getAllRows();
getActivity().startManagingCursor(c);
String[] fromField = new String[] { NotesDatabase.KEY_TITLE };
int[] toView = new int[] { R.id.item_title };
SimpleCursorAdapter myCAdapter = new SimpleCursorAdapter(getActivity(),
R.layout.list_item, c, fromField, toView, 0);
setListAdapter(myCAdapter);
}
but i dont know why i am getting a NullPointerException on db.open(); and c = db.getAllRows();
db.open()
public NotesDatabase open() {
db = myDBHelper.getWritableDatabase();
return this;
}
db.getAllRows();
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null,
null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
DBHelper
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
or if there is a better a better way to populate the list view of fragment from a database?
Thanks in Advance :)

db.open();
db = new NotesDatabase(getActivity());
c = db.getAllRows();
Open the database
Create the database
Get all the rows.
Logically speaking. create it first. then open. then get all the rows. So swithc line 1 and lone 2.
Another thing is that , I assume your getting NPE at myDBHelper, because you never created that helper.

aren't you doing it reverse?
db.open();
db = new NotesDatabase(getActivity());

Just initialise your databasehelper before opening it:
db = new DatabaseHelper(this);

You are doing the db.open before the new so it doesn't exist yet, you are trying to open a null db.

Related

Null Pointer Exception while fetching cursor object

I am getting null pointer exception while fetching the data from the SQLite table.
I am getting the null pointer exception when fetching the data using cursor like below Cursor c= db.fetchAllData();
Please have a look at the below precise code, and suggest me some ideas...
display_transaction.class
public class display_transaction extends Activity {
DisplayTestDBHelper db;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_listview);
displayListView();
}
public void displayListView() {
Cursor c= db.fetchAllData();
String[] columns={db.KEY_ID,db.KEY_DESCRIPTION,db.KEY_AMOUNT};
int[] id=new int[]{R.id.textView1,R.id.textView2};
SimpleCursorAdapter s=new SimpleCursorAdapter(this,R.layout.listviewlayout,c,columns,id,0);
ListView l=(ListView) findViewById(R.id.listview1);
l.setAdapter(s);
}
}
DisplayTestDBHelper.class
public Cursor fetchAllData() {
String TABLE_NAME="transaction_table";
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCursor = db.query(TABLE_NAME, new String[] {KEY_ID, KEY_DESCRIPTION, KEY_AMOUNT}, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
Please help me to resolve the above issue...
Thanks in advance!!!!
You didn't initialize db.
Depending on how you've implemented the helper's constructor, use something like
db = new DisplayTestDBHelper(this);
to init it, passing the activity this for a Context.
You haven't initialized db.
You need to do something like:
db = new DisplayTestDBHelper(this);

retrivininbg single column from the Sqlite database to display it in listview

This is my cursor in database handler class for displaying single coloumn in a list view
public String getAllStringValues() {
ArrayList<String> yourStringValues = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor result = db.query(true, TABLE_PATIENT_GENERAL,
new String[] { KEY_PATIENT_NAME }, null, null, null, null,
null, null);
if (result.moveToFirst()) {
do {
yourStringValues.add(result.getString(result
.getColumnIndex(KEY_PATIENT_NAME)));
} while (result.moveToNext());
} else {
return null;
}
return KEY_PATIENT_NAME;
}
as I m fresher in android please tell me the exact flow and code thanks.

Android IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase [duplicate]

This question already has an answer here:
attempt to re-open an already-closed object: SQLiteDatabase
(1 answer)
Closed 8 years ago.
I know there are several questions like this one, but all of them seem to have a different approach to solve the problem and none have solved mine.
I have my main activity working just fine, loading the db and populating the listview. Then I call a second activity and the problem shows up when I try to load the listview.
I have tried using start/stop managingcursor(cursor) even though it is deprecated, but it didn't fix the problem. Also I tried cloasing the cursor and db in my main activity before firing the next one but that didn't help either.
Both classes extend from ListActivity and follow the same sequence:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Open db in writing mode
MySQLiteHelper.init(this);
MySQLiteHelper tpdbh =
new MySQLiteHelper(this, "DB", null, 1);
SQLiteDatabase db = tpdbh.getWritableDatabase();
checkLocationAndDownloadData(); //this fires a Asynctask that calls method parseNearbyBranches shown bellow
//I load the data to the ListView in the postExecute method of the asynctask by calling:
/*
Cursor cursor = MysSQLiteHelper.getBranchesNames();
adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String branch_id = cursor.getString(cursor.getColumnIndexOrThrow("branch_id"));
cursor.close();
openNextActivity(Integer.parseInt(branch_id));
}
});
}
//In another file:
private void parseNearbyBranches(JSONObject jo) throws JSONException
{
if ( jo.has(jsonTitle) &&
jo.has("company_id") &&
jo.has("id")
) {
String branch = jo.getString(jsonTitle);
MySQLiteHelper tpdbh = MySQLiteHelper.instance;
SQLiteDatabase db = tpdbh.getWritableDatabase();
db.execSQL("INSERT INTO Branches (branch_id, name, company_id) " +
"VALUES ('" +jo.getInt("id")+"', '" + branch +"', '" +jo.getInt("company_id")+"' )");
db.close(); //no difference is I comment or uncomment this line
}
}
In MySQLiteHelper.java:
public static Cursor getBranchesNames() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id", "branch_id", "name", "company_id" };
Cursor c = getReadDb().query(branchesTable, columns, null, null, null, null,
null);
return c;
}
My other activity does basically the same:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_branch_surveys);
//Read branch data from DB
int companyID = -1;
MySQLiteHelper.init(this);
String [] columns = new String [] {"company_id"};
String [] args = {Integer.toString(branchID)};
Cursor c = MySQLiteHelper.getReadDb().query(MySQLiteHelper.branchesTable, columns, "branch_id=?", args, null, null, null); //THIS QUERY WORKS JUST FINE
if (c.moveToFirst())
companyID = Integer.parseInt(c.getString(0));
c.close();
if( companyID != -1)
{
new DownloadTask().execute(Integer.toString(companyID) );
//where the Async task calls something just like NearByBranches shown above(but with different objects of course)
//And the postExecute sets the listView:
/* cursor = MySQLiteHelper.getAll();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
}
}
}
In MySQLiteHelper.java:
public static Cursor getAll() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id","title", "points" };
//********IT IS IN THIS LINE WHERE I GET THE ERROR:********************
Cursor c = getReadDb().query(theTable, columns, null, null, null, null,
null);
return c;
}
public static SQLiteDatabase getReadDb() {
if (null == db) {
db = instance.getReadableDatabase();
}
return db;
}
I hope you can help me out. Thanks!
I just tried commenting the db.close in the similar method of parseNeabyBranches and the problem was solved. Yet I dont get the same error having db.close() in parseNearbyBranches(), can you explain me why?
In parseNearbyBranches() you create a separate SQLiteDatabase object with:
SQLiteDatabase db = tpdbh.getWritableDatabase();
Since this is a different object than the one returned by getReadDb(), you can (and should) close it. The basic rule is each time you call getWritableDatabase() and getReadableDatable() you must have a matching close() statement.

how to avoid "close() was never explicitly called on database in SQLiteDatabase" [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android error - close() was never explicitly called on database
I have a problem in my android app.
I have a singleton implemented which has a method with the following code:
public Cursor getFooCursor(Context context)
{
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");
return c;
}
when i use this, i sometimes get the error: SQLiteDatabase: close() was never explicitly called on database
how to avoid this? the problem is, i can not simply make a db.close() befor i return c, because then its empty.
The approach I use is to pass an instance of the db to a class that returns the cursor:
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
public Cursor getFooCursor(Context context, SQLiteDatabase db ) {
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null,
null, "Test DESC");
return c;
}
db.close();
Clients should open the database, then use this method to fetch the cursor, then close both the cursor and the database when they are finished. I would recommend not using a singleton here. Instead do something like this:
public class FooDB
{
private SQLiteDatabase db = null;
private void open() throws SQLiteException
{
if (db != null)
{
throw new SQLiteException("Database already opened");
}
// Create our open helper
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
try
{
// Try to actually get the database objects
db = m_openHelper.getWritableDatabase();
}
catch (Exception e)
{
e.printStackTrace();
}
if (db == null)
{
throw new SQLiteException("Failed to open database");
}
}
private void close() throws SQLiteException
{
if (db != null)
{
db.close();
db = null;
}
}
public Cursor getFooCursor(Context context)
{
if(db == null)
throw new SQLiteException("Database not open");
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");
return c;
}
}

List View Problem

I am trying to fetch rows from the database and make a list view from it.
This is by Query method inside the DbAdapter
public Cursor readInbox(long toId) throws SQLException {
return db.query(TABLE_MAILS, new String[] { ID, KEY_FROM, KEY_TO,
KEY_SUB, KEY_BODY, KEY_DATETIME, KEY_READ }, KEY_TO + "="
+ toId, null, null, null, null, null);
}
This is the code i am trying to write. but its giving error
public class InboxActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inbox);
DBAdapter db = new DBAdapter(InboxActivity.this);
db.open();
long userID = Long.parseLong(MessagingApplication.getUserID());
Cursor inbox = db.readInbox(userID);
startManagingCursor(inbox);
String[] Id = new String[] { DBAdapter.ID };
SimpleCursorAdapter inboxmail = new SimpleCursorAdapter(this, R.layout.list_view, db, Id, null);
setListAdapter(inboxmail);
db.close();
}
}
the Error:
The constructor SimpleCursorAdapter(InboxActivity, int, DBAdapter, String[], null) is undefined
This is a simple compilation error.
Have a look at the public constructors at http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html :
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
You're providing DBAdapter where you should be providing a Cursor. Most likely you should be passing the inbox variable instead of DBAdapter

Categories

Resources