What Is Use of Cursor in Android Development

What is use of Cursor in Android Development?

Cursor is the Interface which represents a 2 dimensional table of any database. When you try to retrieve some data using SELECT statement, then the database will first create a CURSOR object and return its reference to you.

The pointer of this returned reference is pointing to the 0th location which is otherwise called as before first location of the Cursor, so when you want to retrive data from the cursor, you have to first move to the first record so we have to use moveToFirst

When you invokes moveToFirst() method on the Cursor, it takes the cursor pointer to the first location. Now you can access the data present in the first record

How does Cursor work in android

A Cursor object is returned from a query on a SQLite database.
It will return all rows that the query returns.

Say you have a table called names in your database database configured as such:

_id     _name
1 Space Ghost
2 Zorak
3 Moltar
4 Brak

If you want to get all data from this table and use it, you would do
something like this:

public HashMap<Integer, String> getNames(){

HashMap<Integer, String> data = new HashMap<Integer, String>();

try{
SQLiteOpenHelper helper = new MyOpenDbHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
String selectQuery = "SELECT * FROM names";
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.moveToFirst()){ //make sure you got results, and move to first row
do{
int mID = cursor.getInt(0); //column 0 for the current row
String mName = cursor.getString(1); //column 1 for the current row
data.put(mID, mName);

} while (cursor.moveToNext()); //move to next row in the query result

}

} catch (Exception ex) {
Log.e("MyApp", ex.getMessage());
} finally
{
if (cursor != null) {
cursor.close();

}
if (db != null) {
db.close();
}

}

return data;
}

Usually you will create your own class to extend SQLiteOpenHelper, as such:

public class MyOpenDbHelper extends SQLiteOpenHelper {
//........
}

Is Cursor is class or interface in Android?

As you say, Cursor is an interface and db.query(); returns a class that implements the Cursor interface. That is, db.query(); returns the implementation of a Cursor.

When you use the Cursor interface, you don't have to worry about the concrete implementation, you only know that it has methods such as getCount() and close() that you can use and that are implemented by the concrete implementation returned by db.query();.

In other words, Cursor defines the contract that any implementation must honor.

From the documentation:

There are a number of situations in software engineering when it is
important for disparate groups of programmers to agree to a "contract"
that spells out how their software interacts. Each group should be
able to write their code without any knowledge of how the other
group's code is written. Generally speaking, interfaces are such
contracts.

Android SQL Cursor

The function getRec() returns a Cursor and you can call it like:

Cursor c = getRec("John");

Then you must check if the cursor contains any rows and if it does you can extract the value of the 1st row:

String rec;
if (c.moveToFirst()) rec = c.getString(0);
c.close();

You can check the value of the variable rec:

  • if it is null then 'John' was not found in the table
  • if it is not null then the variable rec contains the value of the column rec of the table.

I assume that you expect only 1 row as the result of your query.

If you expect more than 1 rows then use a loop that collects all the recs returned in a list:

ArrayList<String> list = new ArrayList();
while (c.moveToNext()) {
list.add(c.getString(0));
}
c.close();

What's the best way to iterate an Android Cursor?

The simplest way is this:

while (cursor.moveToNext()) {
...
}

The cursor starts before the first result row, so on the first iteration this moves to the first result if it exists. If the cursor is empty, or the last row has already been processed, then the loop exits neatly.

Of course, don't forget to close the cursor once you're done with it, preferably in a finally clause.

Cursor cursor = db.rawQuery(...);
try {
while (cursor.moveToNext()) {
...
}
} finally {
cursor.close();
}

If you target API 19+, you can use try-with-resources.

try (Cursor cursor = db.rawQuery(...)) {
while (cursor.moveToNext()) {
...
}
}

Android Studio SQLite Cursor

Your issue is a common mis-conception about the onCreate method. That is instead of being invoked every time the Database Helper is instantiated, it is only invoked once when the database is created.

The easy fix when developing and when the underlying data does not need to be preserved is to delete the database (delete the App's data or uninstall the App), thus as the database will then be recreated the changed DB structure will be applied.

If the onUpgrade method will drop the table and then invoke the onCreate method increasing the database version number can also fix the issue.

adding values in cursor data

You probably missed the Hour column from database :

change:

if(data.getCount() == 0){
Toast.makeText(this, "There are no contents in this list!",Toast.LENGTH_LONG).show();
}else{
while(data.moveToNext()){
theList.add(data.getString(2));
ListAdapter listAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,theList);
listalarm.setAdapter(listAdapter);
}
}

to:

  if(data.getCount() == 0){
Toast.makeText(this, "There are no contents in this list!",Toast.LENGTH_LONG).show();
}else{
while(data.moveToNext()){
theList.add(data.getString(0) + ":" + data.getString(2));

}
ListAdapter listAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,theList);
listalarm.setAdapter(listAdapter);
}

Passing a cursor to an activity?

I personally don't know of any simple ways to do this. It might be easier just to make the query again in the destination activity.



Related Topics



Leave a reply



Submit