Android SQLit Search: NullPointerException? - android

I need to perform a search operation into my SQLite DB.
In my Activity, I have EditText for entering the keyword and a search Button. Once the user clicks the button, the EditText text will be stored in the keyword and sent to a search(String keyword) method in the DBHelper class.
I have this code in my SearchActivityfor onCreate() and onClick():
//SearchActivity class extends ListActivity and implements OnClickListener
Button search;
DataBaseHelper myDbHelper;
SimpleCursorAdapter ca;
ListView lv;
EditText txt;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_layout);
txt = (EditText) findViewById(R.id.search_term);
search = (Button) findViewById(R.id.search_button);
search.setOnClickListener(this);
}
public void onClick(View v) {
try {
myDbHelper.openDataBase();
} catch (SQLException sqle) {}
try {
String keyword= txt.getText().toString();
Cursor cursor = myDbHelper.search(keyword); //A method in my DB
cursor.moveToFirst();
String[] columns = {cursor.getColumnName(1)};
int[] columnsLayouts = {R.id.item_title};
ca = new SimpleCursorAdapter(this.getBaseContext(), R.layout.items_layout, cursor,columns , columnsLayouts);
lv = getListView();
lv.setAdapter(ca);
} catch(Exception e){}
}
However, I got NullPointerException in the LogCat!! I couldn't find where the error is.
Anyone can help ?

The description to the NullPointerException could be a little more informative. But it is very likely that the NullPointerException occurs here:
1: Cursor cursor = myDbHelper.search(keyword); //A method in my DB
2: cursor.moveToFirst();
3: String[] columns = {cursor.getColumnName(1)};
or here:
1: try {
2: myDbHelper.openDataBase();
3: } catch (SQLException sqle) {}
Either in the first part in line 1: or 2: or in the second part in line 2:
You should always check if objects which rely on the existence of data are not null. So you should check if cursor is null. Another thing could be that you never initialize myDbHelper.

Related

getString method in android does not work

This is our main class to get information from the database. We are trying to get the values of the "name" column in the "barcode" database that we have created. Right now, we are not able to get the desired value but values as "a, b, c, d, ..." (such as; it returns "a" when we ask for the 1st one, it return "b" when we ask for the second one in the "name" column) value with the cursor.getString method
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DataBaseHelper myDbHelper = new DataBaseHelper(this);
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;
}
Cursor cursor = myDbHelper.getAllAccounts();
String[] values = new String[6];
int i=0;
//take into the array from the database
while(cursor.moveToNext()){
values[i]= cursor.getString(cursor.getColumnIndex("name"));
i++;
}
cursor.close();
//Write to textview
TextView youtextview = (TextView) findViewById(R.id.textView1);
youtextview .setText(values[2]);
}
}
You are not dealing with the cursor in the right way (also you should not do DB calls in the main UI thread which is what you are doing right now). See: http://developer.android.com/reference/android/database/Cursor.html
static final COL_NAME = "name";
Cursor cursor = myDbHelper.getAllAccounts();
cursor.moveToFirst();
int maxCursorIndex = cursor.getCount();
for(int cursorIndex=0;cursorIndex<maxCursorIndex;cursorIndex+=1){
values[cursorIndex] = cursor.getString(cursor.getColumnIndex(COL_NAME);
}
cursor.close();

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.

android calendar event issues with android 2.3

I am presenting user with the add calendar event screen with the below mentioned code.
For example the following will prompt the user if an event should be created with certain details.
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setData(CalendarContract.Events.CONTENT_URI);
startActivity(intent);
This part is working fine with Android 4.0 and above but not working on android 2.3....?
I want this to work on all android OS between 2.3 till 4.1.
you can use this also if you it to do with some other way :
mCursor = getContentResolver().query(
CalendarContract.Events.CONTENT_URI, COLS, null, null, null);
its a contentProvider for calender .
public class Main extends Activity implements OnClickListener{
private Cursor mCursor = null;
private static final String[] COLS = new String[]
{ CalendarContract.Events.TITLE, CalendarContract.Events.DTSTART};
}
Now we need to override the on create method. Pay special attention to how we populate the database cursor. This is where we need our previously defined COLS constant. You’ll note also that after the database cursor is initialized and the click handler callbacks are set, we go ahead and manually invoke the on click handler. This shortcut allows us to initially fill out our UI without having to repeat code.
Main.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mCursor = getContentResolver().query(
CalendarContract.Events.CONTENT_URI, COLS, null, null, null);
mCursor.moveToFirst();
Button b = (Button)findViewById(R.id.next);
b.setOnClickListener(this);
b = (Button)findViewById(R.id.previous);
b.setOnClickListener(this);
onClick(findViewById(R.id.previous));
}
In our callback, we will manipulate the cursor to the correct entry in the database and update the UI.
#Override
public void onClick(View v) {
TextView tv = (TextView)findViewById(R.id.data);
String title = "N/A";
Long start = 0L;
switch(v.getId()) {
case R.id.next:
if(!mCursor.isLast()) mCursor.moveToNext();
break;
case R.id.previous:
if(!mCursor.isFirst()) mCursor.moveToPrevious();
break;
}
Format df = DateFormat.getDateFormat(this);
Format tf = DateFormat.getTimeFormat(this);
try {
title = mCursor.getString(0);
start = mCursor.getLong(1);
} catch (Exception e) {
//ignore
}
tv.setText(title+" on "+df.format(start)+" at "+tf.format(start));
}

Android - Force close if i click item on ListView

I need your help to fix my code.
My intention is if i click the item on ListView it will take me to intent action_view.
The problem is i got force close if i click the item on ListView.
I think the problem is in onItemClick method, can you give the better way to get it done.
Here's my code:
public class HotelList extends ListActivity{
hotelHelper dbHotelHelper;
protected Cursor cursor;
protected ListAdapter adapter;
ListView numberList;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.hotellist);
numberList = (ListView)findViewById(android.R.id.list);
numberList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
String selectedItem = (String) getListAdapter().getItem(position);
String query = "SELECT lat, long FROM hoteltbl WHERE name = '" + selectedItem + "'";
SQLiteDatabase dbs = dbHotelHelper.getReadableDatabase();
Cursor result = dbs.rawQuery(query, null);
result.moveToFirst();
double lat = result.getDouble(result.getColumnIndex("lat"));
double longi = result.getDouble(result.getColumnIndex("long"));
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?f=d&saddr=&daddr="+lat+","+longi));
startActivity(intent);
}
});
dbHotelHelper = new hotelHelper(this);
try{
dbHotelHelper.createDataBase();
}
catch (Exception ioe){
Log.e("err","Unable to create database");
}
view();
}
private void view() {
// TODO Auto-generated method stub
SQLiteDatabase db = dbHotelHelper.getReadableDatabase();
try{
cursor = db.rawQuery("SELECT * FROM hoteltbl", null);
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
cursor,
new String[]{"name"},
new int[] {android.R.id.text1}
);
numberList.setAdapter(adapter);
}
catch (Exception e){
Log.e("error",e.toString());
}
}
}
Inside item click
you have many ways it might cause exception,
Exception will cause your app force close
your code is not handled with exceptions
I am listing down the causes it might cause the exception, please check followings
String selectedItem = (String) getListAdapter().getItem(position);
here you might get type conversation issue, you are converting something is not supported by String
SQLiteDatabase dbs = dbHotelHelper.getReadableDatabase();
Cursor result = dbs.rawQuery(query, null);
result.moveToFirst();
double lat = result.getDouble(result.getColumnIndex("lat"));
double longi = result.getDouble(result.getColumnIndex("long"));
If dbHotelHelper.getReadableDatabase returns null or dbHotelHelper null, in this case your app will force close
In case dbs.rawQuery return null, your app will force close
if result null then you might calling moveToFirst, getDouble and getColumnIndex on null object, in this case also your app will force close
For your info
SimpleCursorAdapter constructor was deprecated in API level 11.
This option is discouraged, as it results in Cursor queries being performed on the application's UI thread and thus can cause poor responsiveness or even Application Not Responding errors. As an alternative, use LoaderManager with a CursorLoader.

rawQuery - CursorAdapter

App gets force closed when going to this activity. I actually noticed that if i remove the cursor part the activity doesn't crash. Help would be appreciated.
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);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
}catch(SQLException sqle){
throw sqle;
}
// Get the intent, verify the action and get the query
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
SQLiteDatabase myDb = myDbHelper.getReadableDatabase();
String q = "SELECT BookTitle, _ISBN FROM Books WHERE BookTitle LIKE" + query;
Cursor c = myDb.rawQuery(q, null);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books._ISBN", "Books.BookTitle" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
}
}
The Cursor requires a column called '_id' - change your query to alias your ISBN column as follows...
String q = "SELECT _ISBN as _id, BookTile FROM Books WHERE BookTitle LIKE" + query;
See my answer and explanation here column '_id' does not exist problem

Categories

Resources