Cursor cursor = contentResolver.query(uri, null, null, null, null);
cursor.moveToFirst();
String filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaColumns.DATA));
Unlike other folders like Camera, Screenshots, Foursquare etc.., The
Pictures from Picasa folder have less no.of columns, of which _data is not
there
and Hence I get the Exception:
java.lang.IllegalArgumentException: column'_data' does not exist
There is a column named picasa_id and a Constant in android:
MediaStore.Images.Media.PICASA_ID
Will that help in getting the correct image path?
Also if I had to download the image from the folder and save in my-app-images folder and then get the actual path. How will I even know that the image URI is from Picasa?
Related
I am new to android development. I came across with a tutorial which enables me to upload images to PHP server using retrofit. However I cannot figure out the way to upload other file types. I just need to get the absolute file path (files like PDF and DOCS) by modifying the code mentioned below. I want to use MediaStore as the option as my entire project has already been set up.
/*
* This method is fetching the absolute path of the image file
* if you want to upload other kind of files like .pdf, .docx
* you need to make changes on this method only
* Rest part will be the same
* */
private String getRealPathFromURI(Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
CursorLoader loader = new CursorLoader(this, contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String result = cursor.getString(column_index);
cursor.close();
return result;
}
use multipart feature of retrofit. refer this tutorial in case you are new to android retrofit multiparttutorial remember if you will going to have uploading and downloading operation then you must should have separate directory of different file which helps you to manage it.
I am using CursorLoader to get the media files from storage. It's working fine for internal and external storage except for the directory and sub-directory of sdcard/android/data/
for example, it fails to detect
sdcard/android/data/com.package.name/files/myFile.mp3
My code
String selection = MediaStore.Files.FileColumns.DATA;
mCursorLoader = new CursorLoader(getContext(),
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
null,
selection,
null,
null);
I'm using the FileProvider pattern for creating content:// uri to files, with the
FileProvider.getUriForFile(this, "com.myapp.provider", file)
function. I have the manifest, provider_paths and everything set the standard way, It creates an uri like content://com.myapp.provider/external_files/music/mysong.mp3.
My issue is that if I try getting the real file path in another app, it doesn't work as the _data column doesn't exist (to be specific the error in logs is E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 0 columns.). For fetching the real path I'm using the also pretty much standard function
final String column = MediaStore.Files.FileColumns.DATA;
final String[] projection = { column };
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
If I use a different app for sharing the same file it generates an uri like content://com.otherapp.provider/external_files/music/mysong.mp3, from which I can already retrieve the real file path. Any ideas what do I have to do to make sure that my app properly inserts the given uri to ContentResolver? Manual contentResolver.insert(...) functions are not allowed. I've tried different versions of provider_paths.xml and granting all possible read/write permissions to the given uri, but I could never retrieve the real path.
The uri itself generated by me works fine as I can read the file or play the song, my issue is just that I cannot retrieve the real file path that I need.
Thanks
My issue is that if I try getting the real file path in another app
The other app should not be trying to do this.
For fetching the real path I'm using the also pretty much standard function
That works for very few Uri values.
If I use a different app for sharing the same file it generates an uri like content://com.otherapp.provider/external_files/music/mysong.mp3, from which I can already retrieve the real file path.
That is not guaranteed.
Any ideas what do I have to do to make sure that my app properly inserts the given uri to ContentResolver?
You don't. You fix the client app, which should not be attempting to get a "real file path" from a Uri.
my issue is just that I cannot retrieve the real file path that I need.
Instead, for a Uri with a content scheme:
Step #1: Get a ContentResolver, by calling getContentResolver() on some Context (e.g., an activity)
Step #2: Call openInputStream() on the ContentResolver, passing in your Uri, to get an InputStream on that content
Step #3: Consume the content via that InputStream
If you are using some third-party library that can only work with files, copy the data from that InputStream to some FileOutputStream, then use the resulting file with that library.
This way, no matter where the content is coming from (a file that you could access, a file that you cannot access, a BLOB column in a database, etc.), you will have code that works.
See also:
Getting the Absolute File Path from Content URI for searched images
onActivityResult's intent.getPath() doesn't give me the correct filename
Android - Get real path of a .txt file selected from the file explorer
I used below query to load all pictures or video from sd card and it works accordingly. But when I add some video or pictures manually into sd card at different folder then its not loading after query. Please suggest me regarding same.
final String[] columns = { MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID};
final String orderBy = MediaStore.Video.Media.DATE_TAKEN;
Uri videosuri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
Cursor imagecursor = getContentResolver().query(videosuri, columns, null, null, orderBy);
if (imagecursor != null && imagecursor.getCount() > 0) {
while (imagecursor.moveToNext()) {
int video_id=imagecursor.getInt(imagecursor.getColumnIndex(MediaStore.Video.Media._ID));
int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Video.Media.DATA);
String path=imagecursor.getString(dataColumnIndex);
}
}
When you "add some video or pictures manually into sd card at different folder", the MediaStore has to be updated in order for them to be available to your query, as well as to other apps that use the MediaStore backend.
Adding them via MTP or apps like Gallery will invoke the MediaScanner (or some similar process) to add them to the MediaStore, but adding them via adb push or in your own code requires you to explicitly do so afterward.
In your code, after writing an image or video file to the SDCard, you can pass the path and MIME type of the file to the MediaScanner by implementing the MediaScannerConnectionClient interface in a class, instantiating it, then calling scan(). The MediaScanner will then open the file, collect/generate metadata, and add the file to the MediaStore
See android - dynamically add pictures to gallery widget for an example class using this approach.
I am trying to display a list of albums (of music mp3s stored on the sd-card) along with the album art for each album. The album art is stored in the mp3s tag (it is not a separate image on the SD card)
I can get the album details fine using:
String[] projection = new String[] { Albums._ID, Albums.ALBUM, Albums.ARTIST, Albums.ALBUM_ART, Albums.NUMBER_OF_SONGS };
String rowsToReturn = null;
String[] selectionWhere = null;
String sortOrder = Media.ALBUM + " ASC";
Cursor cursor = contentResolver.query(Albums.EXTERNAL_CONTENT_URI, projection, rowsToReturn, selectionWhere, sortOrder);
String albumArtUri = cursor.getString(cursor.getColumnIndex(Albums.ALBUM_ART));
The URI is correct, but when I try to set the URi to the src of an ImageView, I get a silent error being thrown "resolveUri failed on bad bitmap uri".
imageview.setImageURI(Uri.parse(albumArtUri));
This only happens for some albums. Some are fine and display the album art correctly.
I took a look at the URI path and checked on the SD card for the thumbnail images and found them here: /mnt/sdcard/Android/data/com.android.providers.media/albumthumbs/
I found images that work and images that dont, so the image does exist, but just cannot be read correctly. I even tried copying the images off the sd card and adding .png extension to the files - the ones that show up on the phone work, but the ones that don't are 'corrupt'
Finally I copied the mp3 files themselves back to the PC and inspected the album art embedded in the tags and they all show correctly.
It's almost as if the thumbnails that the Android system is creating form the tags are invalid or corrupt, but this can't be right.
Or maybe I need to read them differently?
i think the issue could be with Media scanning. Delete the cache folder and open the music player app.It will create album cache again for all the songs. See if this helps.