I have a problem. I want to make file uploader app. I'm using Intent.ACTION_GET_CONTENT to pick any file from my device. I am receiving the file in onActivityResult like that:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CHOOSER:
if (resultCode == RESULT_OK) {
final Uri uri = data.getData();
File file = FileUtils.getFile(uri);
String fileName = file.getName();
String filePath = file.getPath();
int fileSize = Integer.parseInt(String.valueOf(file.length()/1024));
tvName.setText(fileName);
tvPath.setText(filePath);
tvSize.setText(String.valueOf(fileSize) + "kB");
}
}
}
I want to show user information about picked file. In general everything is fine, but when I choose Image from gallery then:
The file name shows no format - it's a number (probably reference to file in memory). When I pick Image via installed file explore I get sth like imagename.png etc, but picked from gallery is like "195493"
File.length created from data picked from gallery is 0.
Is there any way to access real image name and size after picking image from Gallery via intent?
Just input URI from the intent and get the size of any file
uri = data.getData();
Cursor returnCursor = getContentResolver().query(uri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
Log.e("TAG", "Name:" + returnCursor.getString(nameIndex));
Log.e("TAG","Size: "+Long.toString(returnCursor.getLong(sizeIndex)));
I think this will help you.
When picking images from the gallery, you don't get a reference to the actual file but to a row in the database. You have to retrieve the actual file path with a Cursor like in this answer.
Related
I am trying to get the path of the video file for a video thumbnail. I'm not sure why it is still coming as null after I modified based on some solutions here. The version of android is 6.0.1.
The user clicks the floating action button and summons a gallery of videos.
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.addNote);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO);
}
});
When the user selects a desired video from the gallery, the video goes to the activity which it'll be sorted out.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
Log.d(TAG, "Uri: " + uri);
Log.d(TAG, "Uri authority: " + uri.getAuthority());
String filemanagerstring = uri.getPath();
Log.d(TAG, "filemanagerstring: " + filemanagerstring);
String selectedImagePath = getPath(uri);
Log.d(TAG, "selectedImagePath: " + selectedImagePath);
}
}
The method to get the path of the video file.
public String getPath(Uri uri) {
Cursor cursor = this.getContentResolver().query(uri, null, null, null, null);
int idx = 0;
//Source not from device capture or selection
if (cursor == null) {
return uri.getPath();
} else {
cursor.moveToFirst();
idx = cursor.getColumnIndex(MediaStore.Video.VideoColumns.DATA);
if (idx == -1) {
Log.d(TAG, "uri path: " + path);
return uri.getPath();
}
}
String path = cursor.getString(idx);
Log.d(TAG, "path: " + path);
cursor.close();
return path;
}
Results: I got the null (-1) and got the uri's path, that's not the correct path. I need the full path of the video file.
Uri: content://com.android.providers.media.documents/document/video%3A6174
Uri authority: com.android.providers.media.documents
filemanagerstring: /document/video:6174
**uri path: 16842794**
selectedImagePath: /document/video:6174
and summons a gallery of videos
No, it does not. It allows the user to choose from any activity that supports ACTION_GET_CONTENT for a MIME type of video/*. The Uri that you get back can be from anything, not necessarily a "gallery" app, and not necessarily one that points to a file. The Uri could point to:
A file on external storage, one that you might be able to read directly
A file on removable storage, which you cannot access
A file on internal storage of some other app
The contents of a BLOB column in a database
Something that has to be decrypted on the fly
Something that does not yet exist on the device and needs to be downloaded
And so on
The method to get the path of the video file
The only values you can get back from that query(), reliably, are the OpenableColumns, for the size and "display name" of the content.
You need to either:
Use a thumbnail engine that accepts a content Uri as a parameter, or
Use ContentResolver and openInputStream() to get an InputStream on the content, then use some thumbnail engine that accepts an InputStream as a parameter, or
Use ContentResolver and openInputStream() to get an InputStream on the content, then use that stream to make your own file that contains a copy of the bytes from the content, so you can use your own file with some thumbnail engine that requires a file, or
Do not use ACTION_GET_CONTENT, but instead render your own "chooser" UI by asking the MediaStore for all videos, as you can get thumbnails of those videos from MediaStore (see this sample app)
I can't get my ImageViews to update from either URI or file path - they just don't show an image
Intent to capture image:
Intent photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(photo, 1);
On ActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
Uri imageUri = data.getData();
filePath = getRealPathFromURI(this, imageUri);
}
GetRealPathFromURI class:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
It then inserts 'filePath' from onActivityResult in to a db
Retrieving from db and updating ImageViews
imgfilepath[y] = cursorc.getString(cursorc.getColumnIndex("IMAGE"));
imgFile[y] = new File(imgfilepath[y]);
Uri uri = Uri.fromFile(imgFile[y]);
String path = uri.getPath();
mImage.setImageURI(uri);
I've tried so many different ways to setImageBitmap etc which haven't worked (I can't remember all of them) - Can anyone see why this is not showing the image?
The image is in emulated storage and not the SD card.
EDIT:
I've added EXTRA_OUTPUT tag but I can't see the image in DDMS anywhere & the camera does not exit after taking the picture/accepting the image
Intent photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
root.mkdirs();
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
final File sdImageMainDirectory = new File(root, fname);
mImageUri = Uri.fromFile(sdImageMainDirectory);
photo.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(photo, 1);
Uri imageUri = data.getData();
ACTION_IMAGE_CAPTURE does not return a Uri.
The image is in emulated storage
Perhaps that one camera app does, in which case that camera app has a bug, to go along with the return-a-Uri bug.
There are thousands of Android device models. These ship with hundreds of different camera apps pre-installed, and there are hundreds more available from the Play Store and elsewhere. Many will have ACTION_IMAGE_CAPTURE implementations. Most should follow the documented protocol. None should save the image for your request, because you did not tell the camera app where to save the image.
Either:
Provide a location, via EXTRA_OUTPUT, for the camera app to save the image to, then load the image from that location, or
Use data.getExtra("data") to get a Bitmap that represents a thumbnail-sized image, if you do not provide EXTRA_OUTPUT
I am dealing with Pick gallery images and show them in app also save their Path for some references in future.
I was able to Pick those images from gallery which are stored on device like in some folder like Downloads by this code:
Intent intent = new Intent (Intent.ActionPick, Android.Provider.MediaStore.Images.Media.ExternalContentUri);
intent.SetType ("image/*");
StartActivityForResult (Intent.CreateChooser (intent, "Select photo"), 0);
and in Result:
public override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult (requestCode, resultCode, data);
case 0:
string FilePath = GetPathToImage (data.Data);
}
private string GetPathToImage(Android.Net.Uri uri)
{
string path = null;
string[] projection = new[] { Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data };
using (ICursor cursor = this.Activity.ManagedQuery(uri, projection, null, null, null))
{
if (cursor != null)
{
int columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
cursor.MoveToFirst();
path = cursor.GetString(columnIndex);
}
else
{
return uri.Path;
}
}
}
My question is : I am able to get paths of images those are placed in some local folder in gallery, but for folders like Picasa/Autobackup I am not able to get Path.
Note:For local images path starts from content://
For Other com.android....like that.
So, Is there any workaround to get paths of those images.
I don't want to do like this to just display image:
final InputStream is = getContentResolver().openInputStream(imageUri);
I need a Path.
If there is no solution, then How can we skip those images being displayed while Picking from Gallery/Photos.
PS: Known Issue
Any Suggestion is appreciated.
Thanks
I am having the following: From my first activity, I am taking an image from the camera and then a new activity opens, where the iage should be previewed and uploaded to the server as a FILE argument in httpPOST request.
In my first activity I am using this code:
public void onClick(View v) {
String fileName = "temp.jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE,fileName);
mCapturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent,RESULT_LOAD_IMAGE_FROM_CAMERA);
}
and onMyActivityResult I have:
if (requestCode == RESULT_LOAD_IMAGE_FROM_CAMERA
&& resultCode == RESULT_OK && null != data) {
System.out.println("Photo selected from the camera");
String[] projection = {MediaStore.Images.Media.DATA};
//Uri selectedImage = data.getData();
Cursor cursor = getContentResolver().query(mCapturedImageURI, projection, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
//int columnIndex = cursor.getColumnIndex(projection[0]);
//file path of captured image
picturePath = cursor.getString(columnIndex);
//file path of captured image
File f = new File(picturePath);
String filename = f.getName();
Toast.makeText(CommunityMain.this, "Your Path:"+picturePath, 2000).show();
Toast.makeText(CommunityMain.this, "Your Filename:"+filename, 2000).show();
cursor.close();
Intent myIntent = new Intent(CommunityMain.this,PhotoPostActivity.class);
startActivity(myIntent);
The image is saved in the gallery and I do see the picturePath.
When my photoPost activity opens I do have:
f = new File(CommunityMain.picturePath);
System.out.println("Picture path:"+CommunityMain.picturePath);
ImageButton image = (ImageButton) findViewById(R.id.photo1);
image.setImageBitmap(BitmapFactory
.decodeFile(CommunityMain.picturePath));
The picture path is the same, but my ImageButton is not set.
I do get this:
12-08 17:37:22.670: E/BitmapFactory(13357): Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/1386524213331.jpg: open failed: ENOENT (No such file or directory)
but the path is the same with the toast message. What am I missing?
I need to be able also to get the file f since I need that for my HttpPost request.
EDIT: the problem lies in the picturePath. The one I get is different with how the image is being saved?
I see a number like the one above, and the actual path inside the photo has something like IMG_2313.jpg for example.
You should use a different technique. Try to provide the camera with a file url you want the image to be written in like here : https://stackoverflow.com/a/16392587/693752. Next, read that file instead of reading what's provided by the camera.
How do I take a photo and save it to a specific folder. I know it saves to the sdcard/DCIM/etc
But I don't want it there, I want it to be stored in a folder in /sdcard/Camera
I have made the directory with the following :
String destPath = Android.OS.Environment.ExternalStorageDirectory + "/Camera";
Then I launch the camera intent and try point the save file to the path I made.
Intent launchCamera = new Intent(Android.Provider.MediaStore.ActionImageCapture);
launchCamera.PutExtra(MediaStore.ExtraOutput, destPath);
This isn't working. Images still get saved to /sdcard/dcim/etc
Ideas?
From what I gathered when I developed an application using Monodroid is that the camera is very buggy and does not do what you want it to most of the time. This includes specifying the destination where images capture are to be saved.
To my knowledge these issues aren't specific to Monodroid and do occur with the java android sdk.
A work around to this issue that you may want to look at is capturing the image without specifying a destination, then in the OnActivityResult method retrieve the latest image saved to the gallery. Once you get the latest image you can then move it to your preferred destination.
Here is some example code from within OnActivityResult.
Retrieve the filename of the captured image
Android.Net.Uri targetUri = data.Data;
String origin = "";
String [] proj = { MediaStore.MediaColumns.Data.ToString (), BaseColumns.Id };
var qry = ManagedQuery (MediaStore.Images.Media.ExternalContentUri, proj, null, null, "date_added DESC");
qry.MoveToFirst ();
origin = qry.GetString (qry.GetColumnIndexOrThrow (MediaStore.MediaColumns.Data.ToString ()));
Move the image to your desired destination
System.IO.File.Move (origin, "yourdestinationfilenamehere");
I'd like to add to lanks's solution.
Let's say you use the following code to take a picture
var uri = ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri,
new ContentValues());
var intent = new Intent(MediaStore.ActionImageCapture);
intent.PutExtra(MediaStore.ExtraOutput, uri);
StartActivityForResult(intent, ACTIVITY_RESULT_PICTURE_TAKEN);
pictureUri = uri;
Where the ACTIVITY_RESULT_PICTURE_TAKEN is just a simple value you can use in the
OnActivityResult to check which activity was completed.
Your OnActivityResult could look something like this:
protected override void OnActivityResult(int requestCode,
Result resultCode, Intent data)
{
if (resultCode == Result.Ok && requestCode == ACTIVITY_RESULT_PICTURE_TAKEN)
{
string picturePath = GetRealPathFromURI(pictureUri);
//Do something with the file
}
}
The Uri you got earlier is something specific to android and needs to be translated.
It looks like "//content://media/external/media/11917" which is not a
valid path.
Which is exactly what the GetRealPathFromURI function does:
public string GetRealPathFromURI(Android.Net.Uri contentUri)
{
var mediaStoreImagesMediaData = "_data";
string[] projection = { mediaStoreImagesMediaData };
Android.Database.ICursor cursor = this.ManagedQuery(contentUri, projection,
null, null, null);
int columnIndex = cursor.GetColumnIndexOrThrow(mediaStoreImagesMediaData);
cursor.MoveToFirst();
return cursor.GetString(columnIndex);
}
Once you've got the real path, you can move it to wherever you want as lanks suggested.