I have created a getContentResolver().query using the follwing
uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String projection[] = { android.provider.MediaStore.Audio.Media.DATA,
android.provider.MediaStore.Audio.Media.TITLE,
android.provider.MediaStore.Audio.Media.ARTIST,
android.provider.MediaStore.Audio.Media.ALBUM,
android.provider.MediaStore.Audio.Media.COMPOSER,
android.provider.MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media._ID,
android.provider.MediaStore.Audio.Media.ALBUM_ID };
String selection1 = MediaStore.Audio.Media._ID + "=?" ;
String[] selectionArgs = new String[] {"" + 19};
cursor = this.getContentResolver().query(uri, projection,
selection1, selectionArgs, null);
songs = new ArrayList<String>();
while (cursor.moveToNext()) {
songs.add(cursor.getString(1));
This works perfectly fine for selecting single song , however when I try to select multiple songs using
String selection1 = MediaStore.Audio.Media._ID + "IN(?,?)";
String[] selectionArgs = new String[] {"" + 12,"" + 19};
This query fails .
Is there a proper way to select multiple songs , what is wrong with the above query.
please explain the changes needed to be made.
I don't see anything wrong with your query using the IN operator. I suspect the query with IN has quirks and limitations. I did not use it however. Try just using the OR operator instead.
Example:
String selection1 = MediaStore.Audio.Media._ID + "=12" + " OR " + MediaStore.Audio.Media._ID + "=19";
And of course not use selectionArgs as the parameter.
Another good try is using raw query instead, documentation # SQL rawQuery. With a raw query, you can use the IN operator, and I think it's a good idea for simplifying queries. I should use it next time.
Thanks for this question!
Related
Android getContentResolver() Using “IN” in a WHERE clause with large number of Items
I have Implemented this query success fully and It gives the required data
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String projection[] = {MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.COMPOSER,
MediaStore.Audio.Media.DURATION,
// android.provider.MediaStore.Audio.Albums.ALBUM_ART,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media._ID,};
String selection1 = MediaStore.Audio.Media.IS_MUSIC + " = 1" + " AND "
+ MediaStore.Audio.Media._ID + " IN(";
for (int i = 0; i < SongsList.size(); i++) {// songslist is an array of IDs
selection1 += "?, ";
}
selection1 = selection1.substring(0, selection1.length() - 2) + ")";
String[] selectionArgs = new String[SongsList.size()];
selectionArgs = SongsList.toArray(selectionArgs);
Cursor cursor = this.getContentResolver().query(uri, projection, selection1,
selectionArgs, null);
However when the number of Items is large the query fails,
Is there an alternative to retrieve Large number of Items with getContentResolver() without using “IN” in a WHERE clause
When using SQL, the proper way to handle a large number of IDs would be to put them into a temporary table, and join that with the media table.
But with a content provider, you do not have access to that database, so this is not possible.
Your best bet is to retrieve all rows, and then ignore any that do not have one of your IDs.
Alternatively, retrieve the rows one by one. (This probably has too much overhead.)
(If you need the filtered results as an actual Cursor object, put them into a
MatrixCursor.)
I am working on a project using Content Provider for DB.
I am able to fetch all rows using the query mentioned below.
My problem is I want to sum up a column for all rows fetched.
I am querying as :
String query = WorkTable.ENTRY_TIME + " = ?"
String projection = "new String[]{WorkoutLogTable.STEPS}";
Cursor cursor = getContentResolver()
.query(
LogProvider.WORK_LOG,
projection,
query,
new String[]{dateString},
null
);
I want the sum of WorkoutLogTable.STEPS. Projection needs string[] as parameter, so how can I sum up the STEPS value?
Edit
I used a projection:
String projection = new String[]{"sum(WorkoutLogTable.STEPS}) as total"};
But it's also not working.
Solution:
I was doing a mistake by making the whole part as string.
So I have resolved so:
String projection = new String[]{"sum(steps) as total"}; // steps is my column name and I was fetching it by WorkoutLogTable.STEPS which was wrong
Or another solution can be using Dynamic string (from cricket_007 answer)
Projection needs string[] as parameter,
Right, so why is your projection variable a String? This statement won't even compile.
String projection = "new String[]{"sum(WorkoutLogTable.STEPS}) as total"};
Maybe you meant this?
String[] projection = new String[] { "sum(" + WorkoutLogTable.STEPS + ") as total" };
You need to use an actual String[] object, not a String that has the content of "String[] { ... }"
String selection = WorkTable.ENTRY_TIME + " = ?"
String[] projection = new String[] { "sum(" + WorkoutLogTable.STEPS + ")" };
String[] selectionArgs = new String[] { dateString };
Cursor cur = getContentResolver().query(
LogProvider.WORK_LOG,
projection,
selection,
null, null);
Is this a content provider from another app? If you are writing the content provider, I would recommend that you add another URL specifically for the summary query and do your sum function in the query inside the content provider. Then just use the alternate URL when you go through the content resolver.
I'm trying to pull all the tracks for items i've stored in a "playlist", I have a set of android.provider.MediaStore.Audio.Media._ID values and I'm trying to build a query using the IN clause, the example below doesn't work...
String[] projection = { android.provider.MediaStore.Audio.Media.TITLE, android.provider.MediaStore.Audio.Media._ID,
android.provider.MediaStore.Audio.Media.ALBUM, android.provider.MediaStore.Audio.Media.ARTIST,
android.provider.MediaStore.Audio.Media.DURATION, android.provider.MediaStore.Audio.Media.DISPLAY_NAME,
android.provider.MediaStore.Audio.Media.ALBUM_ID, android.provider.MediaStore.Audio.Media.ARTIST_ID};
String whereString = android.provider.MediaStore.Audio.Media._ID + " IN (?)";
String[] selectionArgs = {"626,625"};
But, if I change the selecionArgs to
String[] selectionArgs = {"626"};
It does work
Should the IN clause work or am I going to have to build up a lot of OR statements (which I obviously don't want to do)
In case anyone else tried to do this the IN statement needs a matching number of '?', i.e. you can't have a single parameter that has a list of values, so this works...
String[] projection = { android.provider.MediaStore.Audio.Media.TITLE, android.provider.MediaStore.Audio.Media._ID,
android.provider.MediaStore.Audio.Media.ALBUM, android.provider.MediaStore.Audio.Media.ARTIST,
android.provider.MediaStore.Audio.Media.DURATION, android.provider.MediaStore.Audio.Media.DISPLAY_NAME,
android.provider.MediaStore.Audio.Media.ALBUM_ID, android.provider.MediaStore.Audio.Media.ARTIST_ID};
String whereString = android.provider.MediaStore.Audio.Media._ID + " IN (?,?)";
String[] selectionArgs = {"626","625"};
Sorry if this might be a duplicate question, I've spent the evening trying to wrap my head around this, and I can't seem to find other posts that might cast some light on this as well, so I am hoping that a few more pair of eyes might spot something.
I am having this impression from the API docs for ContactsContract.Data that when you specify certain fields, the library does some magic and performs an implicit join for you in the background.
Doesn't seem to be working for me.
import android.provider.ContactsContract.CommonDataKinds.Phone;
private Cursor getContacts()
{
// Run query
Uri uri = Phone.CONTENT_URI;
String[] projection = new String[] {
Phone.DISPLAY_NAME,
Phone.NUMBER,
Phone.CONTENT_ITEM_TYPE,
Phone.HAS_PHONE_NUMBER,
Phone.IN_VISIBLE_GROUP
};
String selection = Phone.HAS_PHONE_NUMBER + " = '1' AND " + Phone.IN_VISIBLE_GROUP + " = '1'";
String[] selectionArgs = null;
String sortOrder = Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
return getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
}
When this is run, it dies with a:
java.lang.IllegalArgumentException: Invalid column vnd.android.cursor.item/phone_v2
From the docs for ContactsContract.CommonDataKinds.Phone it clearly states that:
You can use all columns defined for ContactsContract.Data as well as the following aliases.
What am I missing?
Phone.CONTENT_ITEM_TYPE is your problem. That's not a column name, that's a constant that Data.MIME_TYPE is set to. Remove it from your projection and it should be fine.
I am working on a database with sqllite in an android app
I want to retrieve sm data using a like clause
ex:
Cursor c = myDB.query(MY_DATABASE_TABLE, null, " SongName LIKE '%"+"=?"+"%'" ,
new String[]{match_str}, null, null,"SongHit DESC");
It should give all SongName starting with match_str but its not working.Why?
This:
" SongName LIKE '%"+"=?"+"%'"
Will end up looking like this when the SQL interpreter sees it:
" SongName LIKE '%=?%'"
And that will match any SongName that contains a literal "=?" and I don't think that's anything like what you want.
A % matches any sequence of characters in an SQL LIKE, it is essentially the same as .* in a regular expression; so, if you want to match at the beginning then you don't want a leading %. Also, your ? placeholder needs to be outside the single quotes or it will be interpreted as a literal question mark rather than a placeholder.
You want something more like this:
String[] a = new String[1];
a[0] = match_str + '%';
Cursor c = myDB.rawQuery("SELECT * FROM songs WHERE SongName LIKE ?", a);
If you wanted to be really strict you'd also have to escape % and _ symbols inside match_str as well but that's left as an exercise for the reader.
Try this:
String[] args = new String[1];
args[0] = "%"+song+"%";
Cursor friendLike = db.rawQuery("SELECT * FROM songs WHERE SongName like ?", args);
No need for the equal sign and you should be able to include the ? right in the string without the need for the + operator. The where clause should just be:
"SongName LIKE '%?%'"
and if mu is too short is correct and you only want starting with...
"SongName LIKE '?%'"
hi Are you getting any exception while executing the above query. Try by removing the "=" symbol infront of the question mark in the like condition. Else try using
db.rawQuery(sql, selectionArgs)
This works perfectly for me...
"Songname LIKE ? "...
cursor = database.rawQuery(query, new String[]{"%" + searchTerm + "%"});
If you wish to use query() instead of rawQuery(), you can do it like so:
// searchString is the string to search for
final String whereClause = "MyColumnName" + " like ?";
String[] whereArgs = new String[]{"%" + searchString + "%"};
Cursor cursor = sqLiteDatabase.query("MyTableName",
null, // columns
whereClause, // selection
whereArgs, // selectionArgs
null, // groupBy
null, // having
null, // orderBy
null); // limit
a simple way is to use the concatenate operator ||
"SongName LIKE '%'||?||'%'"
so there is no need to edit the match_str.
Cursor c = myDB.query(MY_DATABASE_TABLE, null, " SongName LIKE '%'||?||'%'" ,
new String[]{match_str}, null, null,"SongHit DESC");
from https://stackoverflow.com/a/46420813/908821