CursorIndexOutOfBoundsException while getting VideoUri content from File - java

I'm trying to share a video(to social media) in an app I'm building. I'm using intents for which I need a Uri to parse. I'm trying to select items on a simple file manager (List activity) and then share them on long press. Thus I require the following code to get the Uri of the video for using it in the intents.
ContentResolver contentResolver = ctx.getContentResolver();
String videoUriStr = null;
long videoId = -1;
Uri videosUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns._ID };
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = contentResolver.query(videosUri, projection,
MediaStore.Video.VideoColumns.DATA + " =?",
new String[] { fileToShare }, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
if (videoId != -1)
videoUriStr = videosUri.toString() + "/" + videoId;
{
return videoUriStr;
}
UPDATE
The first few items on the ListActivity File manager file will share properly. But the latest videos show the error.
Error: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0

your cursor has 0 rows. So, the line cursor.getLong(columnIndex); throws CursorIndexOutOfBoundsException. please check for null and check whether any rows exist or not.
If there is no rows cursor.moveToFirst() will return false.
Cursor cursor = contentResolver.query(videosUri, projection,
MediaStore.Video.VideoColumns.DATA + " =?",
new String[] { fileToShare }, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
if (videoId != -1)
{
videoUriStr = videosUri.toString() + "/" + videoId;
}
}
}
return videoUriStr;
The MediaStore.Video.VideoColumns.DATA field holds the path for the video file. So, if you are using uri (content://mnt/sdcard/Videos/test.mp4) to fetch the file change it to file path (/mnt/sdcard/Videos/test.mp4).

Use while loop to check is cursor have data or not :
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
Replace with this code :
while (cursor.moveToNext()){
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();

Error: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
means your cursor has no data.
use check for cursor emptyness:
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();

This scenario does not depend on phone to phone. The problem is that your cursor has no data.
You can use cursor.moveToFirst() which returns false if the cursor is empty, or use cursor.getCount() to know the number of rows in the cursor.
e.g
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();
or
if (cursor.getCount() > 0) {
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
}
cursor.close();

first of all you need to check the size of the cursor.
if(cursor.size()>0)
{
// do here
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
cursor.close();
if (videoId != -1)
videoUriStr = videosUri.toString() + "/" + videoId;
{
return videoUriStr;
}
}

I was able to get my problem solved but I still don't understand why I faced that problem with the old code. Thanks for all the help.
public static Uri getVideoContentUriFromFilePath(Context context, File fileToShare) {
String filePath = fileToShare.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Video.Media._ID },
MediaStore.Video.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
return Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "" + id);
} else {
if (fileToShare.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}

Related

Cannot bind argument at index 2 because the index is out of range. The statement has 1 parameters?

I have an array string named "likedAlbums_name"
That array String contains a list of names. I would like to pass the list of names into the whereVal of the cursor.
When I have 1 name in the "likedAlbums_name" array string, everything works fine. But if I have more than 1 name, it crash.
How to I fix that?
Thank you!!!
code:
likedAlbums_name = database.getLikedAlbums(); // returns a list of names
Code:
public void getSongsInAlbum() {
String[] projections = {
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ARTIST,
MediaStore.Audio.Albums.NUMBER_OF_SONGS,
MediaStore.Audio.Albums.ALBUM_ART};
String where = MediaStore.Audio.Media.ALBUM + "=?";
String[] whereVal = likedAlbums_name;
String orderBy = MediaStore.Audio.Media.ALBUM;
ContentResolver contentResolver = getActivity().getContentResolver();
Cursor cursor = contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, projections, where, whereVal, orderBy);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
newAlbum newAlbum = new newAlbum();
newAlbum.albumName = cursor.getString(0);
newAlbum.artist_Name = cursor.getString(1);
newAlbum.number_of_songs_in_album = cursor.getInt(2);
album_list.add(newAlbum);
} while (cursor.moveToNext());
}
cursor.close();
}
}

android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 when convert uri to path

When I try to convert a uri to a path to use to upload an image to an apis, this function returns
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
if( cursor != null && cursor.moveToFirst() ){
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
}
return path;
}
You should check whether you found something with your query or not.
Do someting like this:
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor.moveToFirst() && cursor.getCount() >= 1) {
// rest of your code
// don't forget to check also for your next query
}

How to only delete one row when there are two matches with android Contentresolver

In my Music-Player, a Playlist may contain two identical songs (the user adds the same song two times).
Let's say the song which is 2 times in the Playlist has the id 7664.
When removing this song from the Playlist, ContentResolver.delete(URI_OF_PLAYLIST, "audio_id=7664", null); removes both matches.
So how do I only delete one match?
Thanks in advance!
This is how I do it in my app New Playlist Manager:
step 1: create an array with audio Ids
step 2: whilst looping around this, use the .lastindex() function to determine if it exists elsewhere. (otherwise the value should be the same as position)
step 3: if found, remove from audio Ids array by setting it to null (you do not want to change its size) and remove from playlist
step 4: reorder the playorder
public void dedupe_playlist(Context context, long playlist_id) {
Cursor cursor = plist.getPlaylistTracks(context, playlist_id);
ArrayList<String> audio_ids = new ArrayList<>();
// build up the array with audio_id's
int i = 0;
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String audio_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.AUDIO_ID));
audio_ids.add(audio_id);
}
i = 0;
int duplicates = i;
boolean success = false;
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String audio_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.AUDIO_ID));
duplicates = audio_ids.lastIndexOf(audio_id);
if (duplicates > i) {
success = true;
cursor.moveToPosition(duplicates);
int _id = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Playlists.Members._ID));
removePlaylistTrack(context, playlist_id, _id);
audio_ids.set(duplicates, null);
cursor.moveToPosition(i - 1); // move back to test again
} else {
i++;
}
}
if (success) {
renumber_playorder(context, playlist_id);
}
try {
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void removePlaylistTrack(Context context, long selectedplaylist,
int _id) {
ContentResolver resolver = context.getContentResolver();
Uri newuri = MediaStore.Audio.Playlists.Members.getContentUri(
"external", selectedplaylist);
try {
resolver.delete(newuri, MediaStore.Audio.Playlists.Members._ID + " = " + _id, null);
} catch (Exception e) {
e.printStackTrace();
}
}
To reorder a playlist:
public void renumber_playorder(Context context, long playlist_id) {
Cursor cursor = getPlaylistTracks(context, playlist_id);
Uri newuri = MediaStore.Audio.Playlists.Members.getContentUri(
"external", playlist_id);
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
int i = 0;
if (cursor != null && cursor.moveToFirst()) {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String _id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Playlists.Members._ID));
String[] selection = {_id};
values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, i);
resolver.update(newuri, values, MediaStore.Audio.Playlists.Members._ID + " =? ", selection);
i++;
}
cursor.close();
}
}

String array throws index out of bounds exception

Im making an android app and this part is where a cursor will go through a database and store the 'title' section of the table into a string array. This is then called in another class and is used to dynamically show buttons based on the entries. The code for putting the titles into an array is as follows:
public String[] getTitles()
{
SQLiteDatabase db =getReadableDatabase();
int numRows = (int) DatabaseUtils.queryNumEntries(db, SPORTS_TABLE_NAME);
String title;
String[] titleArray = new String[100];
String sql = "SELECT Title FROM Sports;";
Cursor cursor = db.rawQuery(sql, null);
int i = 1;
while (cursor.moveToNext()) {
if(cursor != null && cursor.moveToFirst()) {
title = cursor.getString(0);
titleArray[i] = title;
i++;
}
if(cursor != null)
db.close();
}
cursor.close();
return titleArray;
}
Then it is called with the following code:
int i = 1;
String[] titlesArray = db.getTitles();
for(String titles: titlesArray){
Button btn = new Button(this);
btn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
btn.setId(i);
btn.setText(titlesArray[i]);
ll.addView(btn);
i++;
}
Been looking for a while and think it needs a fresh pair of eyes.. any ideas?
what if your query returns more than 100 rows? If think it would be safer to use something like
String sql = "SELECT Title FROM Sports;";
Cursor cursor = db.rawQuery(sql, null);
if (cursor == null)
return;
String[] titleArray = new String[cursor.getCount()];
while (cursor.moveToNext()) {
title = cursor.getString(0);
titleArray[i] = title;
i++;
}
of, better, a Collection.
String sql = "SELECT Title FROM Sports;";
Cursor cursor = db.rawQuery(sql, null);
if (cursor == null)
return;
ArrayList<String> titleArrayList = new ArrayList<String>();
while (cursor.moveToNext()) {
title = cursor.getString(0);
titleArrayList.add(title);
}

Change contact picture programmatically

I have a picture, that is stored into the android phone. I want to be able to change the picture of a contact.
What I've done so far is launch the contact picker, have the user select a contact, and then I get the URI of the selected contact. From this contact, I can get the associated rawContact and I use this code.
Uri rawContactPhotoUri = Uri.withAppendedPath(
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
try {
AssetFileDescriptor fd =
getContentResolver().openAssetFileDescriptor(rawContactPhotoUri, "rw");
OutputStream os = fd.createOutputStream();
os.write(photo);
os.close();
fd.close();
} catch (IOException e) {
// Handle error cases.
}
The problem is, the AssetFIleDescriptor is always empty (when I call length on it, we always get -1).
I'm not asking for the entire solution, just some leads to follow that can help me to get that working. I cannot seem to find this problem already on StackOverflow, so any help would be appreciated.
EDIT
It's always when we ask for question that we find the solution.
I want to share it for other
So I gave up on android link and find another one :
http://wptrafficanalyzer.in/blog/programatically-adding-contacts-with-photo-using-contacts-provider-in-android-example/
The picture picker return the Uri of the selected contact, so with this you can get the Contact._ID of it :
// This is onActivityResult
final Uri uri = data.getData();
final Cursor cursor1 = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
final long contactId = cursor1.getLong(cursor1.getColumnIndex(Contacts._ID);
cursor1.close();
Then I had to get the RawContactId :
final Cursor cursor2 = getContentResolver().query(RawContacts.CONTENT_URI, null, RawContacts.Contact_ID + "=?", new String[] {String.valueOf(contactId)}, null);
cursor2.moveToFirst();
final long rawContactId = cursor2.getLong(cursor2.getColumnIndex(RawContacts._ID));
cursor2.close();
Then I had to get the Data._ID of the RawContacts (same way as above).
Then I used the ContentProviderOperations :
final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(Data._ID, dataId),
.withValue(Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, byteArrayOfThePicture);
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
And this is working like charm. Hope it helps
String contactId = "10001"; // change it as your IDs
if (mBitmap != null) {
// Picture
try {
ByteArrayOutputStream image = new ByteArrayOutputStream();
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, image);
Uri rawContactUri = null;
Cursor rawContactCursor = managedQuery(
ContactsContract.RawContacts.CONTENT_URI,
new String[] {
ContactsContract.RawContacts._ID
},
ContactsContract.RawContacts.CONTACT_ID + " = " + contactId,
null,
null);
if (!rawContactCursor.isAfterLast()) {
rawContactCursor.moveToFirst();
rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendPath("" + rawContactCursor.getLong(0)).build();
}
rawContactCursor.close();
ContentValues values = new ContentValues();
int photoRow = -1;
String where111 = ContactsContract.Data.RAW_CONTACT_ID + " == " +
ContentUris.parseId(rawContactUri) + " AND " + ContactsContract.Data.MIMETYPE + "=='" +
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = managedQuery(
ContactsContract.Data.CONTENT_URI,
null,
where111,
null,
null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoRow = cursor.getInt(idIdx);
}
cursor.close();
values.put(ContactsContract.Data.RAW_CONTACT_ID,
ContentUris.parseId(rawContactUri));
values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
if (photoRow >= 0) {
getContentResolver().update(
ContactsContract.Data.CONTENT_URI,
values,
ContactsContract.Data._ID + " = " + photoRow, null);
} else {
getContentResolver().insert(
ContactsContract.Data.CONTENT_URI,
values);
}
} catch (Exception e) {
Log.e("!_##Image_Exception", e + "");
}
}
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.e("#####UPLOADERR", e + "");
}

Categories

Resources