44

What should I do to get my content provider to return the _count column with the count of records? The documentation says it is automatic, but maybe it's only taking about some built-in content provider. Running a query to the database seems not to return it.

RandomMooCow
  • 734
  • 9
  • 23
Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622

4 Answers4

127

If you are using contentProvider then you have to do it like count(*) AS count.

If you use cursor.getCount(), that would not be as efficient as the above approach. With cursor.getCount() you are fetching all the records just to get counts. The entire code should look like following -

 Cursor countCursor = getContentResolver().query(CONTENT_URI,
                new String[] {"count(*) AS count"},
                null,
                null,
                null);

        countCursor.moveToFirst();
        int count = countCursor.getInt(0);

The reason why this works is because android needs a column name to be defined.

Rahul Sharma
  • 2,867
  • 2
  • 27
  • 40
saurabh
  • 2,389
  • 3
  • 22
  • 37
16

If you are using ContentProvider.query() a Cursor is returned. Call Cursor.getCount() to get a count of records in the returned cursor.

Shahzeb
  • 3,696
  • 4
  • 28
  • 47
Will
  • 19,789
  • 10
  • 43
  • 45
  • 38
    The problem with this is that it actually performs a query and allocates memory for the records, etc. There is a better way to get count as-if the SQL statement "SELECT COUNT(*) FROM TABLE" ... I will keep looking for this alternate answer. – mobibob Dec 16 '10 at 20:25
  • 8
    You can get the count without fetching all the records. See the answer below from me.. – saurabh May 24 '12 at 07:31
  • This won't let a provider support the _count column: SqliteQueryBuilder will throw an exception if you don't filter out the "_count" column from the projection. – Dan Hulme Jun 21 '13 at 20:56
  • With cursor.getCount() you can not assure that it returns the real number of items returned. There are much better ways: 1- If you are using Content Providers, you can do a query and use the Column (_COUNT) included in BaseColumns for your projection 2- To do a rawQuery using SELECT COUNT(*) – cesards Nov 06 '13 at 15:34
  • @mobibob : a/ there is no guarantee that your contentprovider is backed by a sql datababase b/ a cursor is especially made to not allocate the memory for all the records. – njzk2 Nov 06 '13 at 15:42
  • @m3n0R : `With cursor.getCount() you can not assure that it returns the real number of items returned`. what ? – njzk2 Nov 06 '13 at 15:42
  • cursor.getCount() iterates all the cursor data, so it's a big problem of efficiency. Moreover, if you're working with a huge amount of data, it's probably the iterator gets crazy and return random number of rows... – cesards Nov 06 '13 at 16:58
  • @njzk2 very good point about the SQL backing -- but I am quite certain that the cursor's getCount does perform the query to get the count. I recall that was my problem that led me to find this question. (A long time ago:) – mobibob Nov 08 '13 at 01:29
  • @m3n0R : disagree, and totally disagree. unless you have source to back that argument ? I really don't see how getCount could return a random number without a very explicit notice in the documentation, at least. – njzk2 Nov 08 '13 at 14:58
  • @njzk2 have you tryied to work with huge amount of data? If not, do it and then check getCount() again ^^. I'm not a kind of pro, I'm just talking about my experiences :-) – cesards Nov 09 '13 at 18:33
  • depends what you mean by huge. I have used sqlite storage with 10000+ rows in a table, displaying the getCount using a contentobserver while inserting and updating rows in an underlying service without ever observing any error as to the number of rows actually present. – njzk2 Nov 11 '13 at 13:56
4

I had a similiar problem and found this worked for me. In the example below I wanted to get the count of images from the MediaStore provider.

        final String[] imageCountProjection = new String[] {
                "count(" + MediaStore.Images.ImageColumns._ID + ")",
        };

        Cursor countCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                imageCountProjection,
                null,
                null,
                null);

        countCursor.moveToFirst();
        int existingImageCount = countCursor.getInt(0);
Frank Leigh
  • 5,262
  • 1
  • 15
  • 18
1

With cursor.getCount() you can not assure that it returns the real number of items returned. There are much better ways:

1- If you are using Content Providers, you can do a query and use the Column (_COUNT) included in BaseColumns for your projection

@Override
public Cursor query(SQLiteDatabase db, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    ...

    projection = new String[] {
        ContentContract.NotificationCursor.NotificationColumns._COUNT,
    };

    ...

    Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder);
    return cursor;
}

2- To do a rawQuery using SELECT COUNT(*) as @saurabh says in his response.

Rahul Sharma
  • 2,867
  • 2
  • 27
  • 40
cesards
  • 15,882
  • 11
  • 70
  • 65