App crashes if SQLite cursor has no results - android

I have an app that uses a cursor to run an SQlite query.
public Cursor totaltrips(){
Cursor cursor = database.rawQuery("SELECT * AS TTotal FROM " + DatabaseHelper.TABLE_NAME, null);
return cursor;
}
The results are stored to an Arraylist with a maximum of 5 values. If there are no records in the database the app crashes. If I have one or more database entries it works fine. Does anyone know how I can stop it from crashing when there are no database entries?
// get column value
if (Distance.moveToNext())
result = String.valueOf(Distance.getDouble(Distance.getColumnIndex("myTotal")));
tnmView.setText(result);
List<String> distancearray = new ArrayList<String>();
Cursor cursor = dbManager.totaldistance();
do{
distancearray.add(cursor.getString(1));
}while ((cursor.moveToNext()));
ttrips = cursor.getCount();
Log.i("Graph", "TTRIPS = " + ttrips);
// Be sure here to have at least the 5 desired elements into the list
while(distancearray.size() < 5){
distancearray.add("0");
}
The app crashes with the error
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
On the line
do{
distancearray.add(cursor.getString(1));
}while ((cursor.moveToNext()));

Check if cursor actually has results, try something like this for example:
int numResults = cursor.getCount();
if (numResults > 0) {
do {
distancearray.add(cursor.getString(1));
} while ((cursor.moveToNext()));
}

Replace
do{
distancearray.add(cursor.getString(1));
}while ((cursor.moveToNext()));
with
if (cursor != null) {
while (cursor.moveToNext()) {
distancearray.add(cursor.getString(1));
}
cursor.close();
}

Check if cursor is null and has more than one value.Close cursor after uses.
if(cursor!=null&&cursor.getCount()>0){
cursor.moveToFirst();
while(cursor.hasNext()){
//do stuff here
}
cursor.close();
}

Related

Android cursor no step more than 1 record

My query return 198 registers but cursor only read one register.
Why?
The mCount property of Cursor show 198.
This code:
public ArrayList<EnderecoOficina> retornarListaEnderecoOficina(String sCampo,
String sWhere) {
ArrayList<EnderecoOficina> lista = new ArrayList<EnderecoOficina>();
String query = String.format("SELECT %s FROM %s WHERE %s",
sCampo,
MyDBConstants.TABLE_OFICINAS,
sWhere);
SQLiteDatabase db = dbHandler.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
int i = 0;
if (cursor != null && cursor.moveToFirst()){
EnderecoOficina item = new EnderecoOficina(i++,
cursor.getString(0),
cursor.getString(1),
cursor.getString(2));
lista.add(item);
} while (cursor.moveToNext());
cursor.close();
db.close();
return lista;
}
image link (my points not allow attach image here).
I think you're confusing while syntax.
while (cursor.moveToNext());
Will loop without doing anything until the Cursor is empty. I think you wanted a do/while as explained by CommonsWare answer.
In my opinion, this is an unnecessary complicated way to do it. A lot of people don't know how to use Android Cursor. I've seen all kinds of complicated ways to do it (checking for null, moving to first, moving to index...), but this is the simplest way:
try {
// Loop while there are records on the Cursor
while (cursor.moveToNext()) {
EnderecoOficina item = new EnderecoOficina(i++,
cursor.getString(0),
cursor.getString(1),
cursor.getString(2));
lista.add(item);
}
} finally {
// Make sure the cursor is closed no matter what
cursor.close();
}
There's no need to check for null, Android Cursor API never returns a null cursor. You also need to close the Cursor once you've finished with it.

App crashed with cursor getInt

I want to get number of rows inside a table using a SELECT COUNT(*) as nb query. Then when I want to get the result by using cursor.getInt(0) then the app crashed ! So I replaced my code with this :
public int getParcelleCount() {
String countQuery = "SELECT * FROM " + T_PARCELLE;
Cursor cursor = bd.rawQuery(countQuery, null);
int nb = 0;
if (cursor != null) {
nb = cursor.getCount();
}
cursor.close();
return nb;
}
And it works ! So why is the first option wrong ?
Your previous code did not work because you were trying to get values without moving to first. You have check for not null that was correct. But it was throwing Cursor Index Out Of Bounds Exception(You can search on internet). So you have to move cursor to first and then try to get values.
Try below code.
String countQuery = "SELECT COUNT(*) AS NB FROM " + T_PARCELLE;
Cursor cursor = bd.rawQuery(countQuery, null);
int nb = 0;
if (cursor.moveToFirst()) {
do
{
nb = cursor.getInt(0);
}while(cursor.moveToNext());
}
cursor.close();
return nb;

how to fix the error android.database.cursorindexoutofboundsexception?

Anyone? please help me to figure this out. I'm getting an android.database.cursorindexoutofboundsexception error and I don't why. I'm sure that I name my columns correct but still I got it. What I am trying to do is just to get the companycode of the given company name.
Here my code my DatabaseAdapter
public Cursor getCompanyCode(String company)
{
Cursor c = dbSqlite.query(Constants.DATABASE_TABLE_COMPANY,
new String[] { Constants.DATABASE_COLUMN_ID,
Constants.COMPANY_CODE,Constants.COMPANY_NAME},
Constants.COMPANY_CODE+" = ?",
new String[]{company}, null, null, null);
if (c != null)
{
c.moveToFirst();
}
return c;
}
and here another code to get company code of the given company
Cursor companyCode = databaseAdapter.getCompanyCode(company);
code = companyCode.getString(companyCode.getColumnIndex(Constants.COMPANY_CODE));
and here is my logcat.
06-04 12:54:48.085: E/AndroidRuntime(27134): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.uni.customercare/com.uni.customercare.ViewSummaryActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
Try this approach:
define this method in your database helper class which extends SQLiteOpenHelper. Use an instance of the class to call this method.
public HashMap<String, String> getCompanyDetails(){
HashMap<String,String> company= new HashMap<String,String>();
String selectQuery = "SELECT * FROM " + TABLE_COMPANY; //Change this query accordingly.
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
cursor.moveToFirst();
if(cursor.getCount() > 0){
company.put(KEY_COMP_ID, cursor.getString(0));
company.put(KEY_COMP_CODE, cursor.getString(1));
company.put(KEY_COMP_NAME, cursor.getString(2));
}
cursor.close();
db.close();
return company;
}
Simple way to work with cursor companyCode..
companyCode.moveToFirst();
while( !companyCode.isAfterLast() ) {
//do something with companyCode..
//.....
companyCode.moveToNext();
}
companyCode.close()

How to check if a cursor is empty? [duplicate]

This question already has answers here:
How To Test If Cursor Is Empty in a SQLiteDatabase Query
(6 answers)
Closed 2 years ago.
When I'm trying to get the phone numbers from the contact list of the phone. The problem is, when I'm running the app while the contact list in the phone is empty, the app is stopped. I checked it and this is because the cursor is empty.
How can I check if the cursor is empty or if there are any contacts in the contact list of the phone?
ArrayList<String> lstPhoneNumber = new ArrayList<String>();
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
lstPhoneNumber = new ArrayList<String>();
phones.moveToFirst();
// The problematic Line:
lstPhoneNumber.add(phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER)));
while (phones.moveToNext()) {
lstPhoneNumber.add(phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
phones.close();
The general pattern to test for a "valid" cursor is
((cursor != null) && (cursor.getCount() > 0))
The Contacts Provider doesn't return null, but other content providers might do so if they encounter some sort of data error. A content provider should handle Exceptions, set the cursor to zero, and log the Exception, but there's no guarantee.
Use cursor.getCount() == 0. If true, the cursor is empty
I added in a projection so you are only getting the column you need.
String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };
ArrayList<String> lstPhoneNumber = new ArrayList<String>();
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
if (phones == null)
return; // can't do anything with a null cursor.
try {
while (phones.moveToNext()) {
lstPhoneNumber.add(phones.getString(0));
}
} finally {
phones.close();
}
public boolean isCursorEmpty(Cursor cursor){
return !cursor.moveToFirst() || cursor.getCount() == 0;
}
Try this one. The problem of your code is that it will execute add regardless of the length of the cursor. I enclose the phones.moveToFirst() in if statement since it will return false if cursor is empty or has no record set.
if(phones.moveToFirst()){
do{
lstPhoneNumber.add(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}while(phones.moveToNext())
} else {
//do something else
}
System.out.println("count "+ cursor.getCount());
This will show value of cursor in logcat
cursor.moveToFirst();
if (cursor.isBeforeFirst()) //means empty result set
; //do your stuff when cursor is empty
isBeforeFirst() after a moveToFirst() works well also.
According to the Cursor documentation:
isBeforeFirst():
Returns whether the cursor is pointing to the position before the first row.

Skip deleted/empty rows sqlite

I am populating AChartEngine from sqlite database and I need all of the data to be displayed. The problem I'm having is when I delete a record the graph series stops populating at the deleted record. I need to find a way to skip over deleted/empty records and continue populating my graph. I need it to do it the same way listview skips over deleted records and keeps on displaying all rows. I am very new to a lot of this and am having a very difficult time with this. I have tried to write if statements in order to skip deleted/empty rows but nothing seems to work. Thank you for helping!
in my graphing activity:
for (int i = 1; !c.isAfterLast(); i++) {
String value1 = db.getValue1(i);
String value2 = db.getValue2(i);
c.moveToNext();
double x7 = Double.parseDouble(value1);
double y7 = Double.parseDouble(value2);
myseries.add(x7, y7);
}
I am getting error: CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
If I surround with try and catch it will populate rows up until the deleted record.
"EDIT"
in my sqlite database:
public String getValue1(long l) {
String[] columns = new String[]{ EMP_DEPT };
Cursor c = db.query(EMP_TABLE, columns, EMP_ID + "=" + l, null, null, null, null);
if (c != null){
c.moveToFirst();
String value1 = c.getString(0);
return value1;
}
return null;
}
public String getValue2(long l) {
String[] columns = new String[]{ EMP_DATE1 };
Cursor c = db.query(EMP_TABLE, columns, EMP_ID + "=" + l, null, null, null, null);
if (c != null){
c.moveToFirst();
String value2 = c.getString(0);
return value2;
}
return null;
}
Your issue is that your safety net for commands on rows that don't exist is to use if (c != null){ and then perform your commands inside that block, but a Cursor request from a query will never come up null, it will instead result in a cursor object with no rows.
A more appropriate solution to use this as your safety net instead if (c.moveToFirst()){ Because the method itself returns a boolean for if the method actually carried itself out in the first place - true if it moved and false if not (which occurs when there's no rows to move into). another check, if you wish, would be to see how many rows the cursor has with c.getCount().
Additionally, you should combine your methods so that you don't make redundant queries to the database:
public String[] getValues(long l) {
String[] results = new String[2];
String[] columns = new String[]{ EMP_DEPT, EMP_DATE1 };
Cursor c = db.query(EMP_TABLE, columns, EMP_ID + "=" + l, null, null, null, null);
if (c.moveToFirst()) {
results[0] = c.getString(0);
results[1] = c.getString(1);
} else {
Log.d("GET_VALUES", "No results formed from this query!");
}
return results;
}
You should use a single query to get all values at once:
SELECT Date1 FROM MyTable WHERE id BETWEEN 1 AND 12345
or:
db.query(EMP_TABLE, columns, EMP_ID + " BETWEEN 1 AND " + ..., ...);
Then missing values will just not show up when you iterate over the cursor.

Categories

Resources