I have registered my app to receive files (of any type, not just images) from other apps following this post.
I have implemented the solution that was answered but I cannot find a way to retrieve the "file name" of the data stream.
As an example from an Uri like:
content://downloads/all_downloads/5
I can get the stream out but I don't know anything about the name of the original file generating it.
Is there a way to retrieve it?
In MOST cases this will solve your problem:
Uri intentData = intent.getData();
if (intentData != null) {
String filePath;
if("content".equals(intent.getScheme()))
{
filePath = getFilePathFromContentUri(intentData);
}
else
{
filePath = intentData.getPath();
}
}
private String getFilePathFromContentUri(Uri selectedUri) {
String filePath;
String[] filePathColumn = {MediaColumns.DATA};
Cursor cursor = getContentResolver().query(selectedUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
return filePath;
}
Is there a way to retrieve it?
Generally, no, because there may not be a name, in part because there may not be a file. You may be able to get an InputStream on the contents, but that does not mean that there is a file behind the InputStream.
There may be some specific hacks for some specific providers (e.g., MediaStore) to try to determine the file name associated with some data Uri, though such hacks may not be reliable.
onCreate()
Intent intent1 = getIntent();
String action = intent1.getAction();
String type = intent1.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
this.handleSend(intent1);
}
void handleSend(Intent intent) {
try {
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
imageShare.setImageURI(imageUri);
} catch (Exception e) {
e.printStackTrace();
}
}
Related
I am selecting an image of the gallery from my app,
using
ACTION_GET_CONTENT
Now I want the path of this image:
But i get it like this:
content://com.android.providers.media.documents/document/image%3A5793
How can i get the path?
I tried this to get path:
Uri uri = data.getData();
Log.e("Path is: "+uri);
The answer is don't try and get the path because in Android 10 and later you won't be able to get it or use it.
You can get a FileDescriptor or input/output Stream that can be used in most methods that need to access the file contents.
See https://developer.android.com/training/data-storage/ for more details, since it is a picture then using Media store is probably best.
Try this :
Uri uri = data.getData();
String picturePath = getPath( getActivity( ).getApplicationContext( ), uri);
Log.e("Picture Path", picturePath);
public static String getPath( Context context, Uri uri ) {
String result = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver( ).query( uri, proj, null, null, null );
if(cursor != null){
if ( cursor.moveToFirst( ) ) {
int column_index = cursor.getColumnIndexOrThrow( proj[0] );
result = cursor.getString( column_index );
}
cursor.close( );
}
if(result == null) {
result = "Not found";
}
return result;
}
In my app the user can select files and open them in the appropriate app (using an ACTION_VIEW intent).
I need to do some work on the data before giving it to the other app. So I'm using a streaming solution : I implemented a ContentProvider that implements openTypedAssetFile and writeDataToPipe (this method fills the output ParcelFileDescriptor created by openPipeHelper).
This works : I can open .pdf files, .txt files etc. The streaming seems correct.
I can open images usings 3-party apps.
However when I open an image using the Gallery, it doesn't work (Gallery shows a black screen), and I get the following exception :
fail to open myfile.jpg
UriImage(21890): java.io.FileNotFoundException: Not a whole file
I had a look at the Gallery source (here) and I could see that the exception is thrown here :
try {
if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) {
InputStream is = mApplication.getContentResolver()
.openInputStream(mUri);
mRotation = Exif.getOrientation(is);
Utils.closeSilently(is);
}
**mFileDescriptor = mApplication.getContentResolver()
.openFileDescriptor(mUri, "r");**
if (jc.isCancelled()) return STATE_INIT;
return STATE_DOWNLOADED;
} catch (FileNotFoundException e) {
Log.w(TAG, "fail to open: " + mUri, e);
return STATE_ERROR;
}
However, once in the Gallery app, if I select "Set as wallpaper", then I can see my image, it is then well streamed. So the problem appears when Gallery opens.
After a deeper look (in the ContentResolver code etc.) I couldn't understand why it behaves this way. It seems that Gallery does not support streaming files. Is that right ?
Do you have any idea ?
Thanks a lot.
String scheme = mUri.getScheme();
ContentResolver contentResolver = getContentResolver();
// If we are sent file://something or
// content://org.openintents.filemanager/mimetype/something...
if (scheme.equals("file")
|| (scheme.equals("content") && fileUri
.getEncodedAuthority().equals(
"org.openintents.filemanager"))) {
// Get the path
filePath = fileUri.getPath();
// Trim the path if necessary
// openintents filemanager returns
// content://org.openintents.filemanager/mimetype//mnt/sdcard/xxxx.jpg
if (filePath.startsWith("/mimetype/")) {
String trimmedFilePath = filePath
.substring("/mimetype/".length());
filePath = trimmedFilePath.substring(trimmedFilePath
.indexOf("/"));
}
} else if (scheme.equals("content")) {
// If we are given another content:// URI, look it up in the
// media provider
filePath = getFilePathFromContentUri(fileUri,
contentResolver);
} else {
Log.e("filePath--------->>>>>", filePath + "");
}
and
private String getFilePathFromContentUri(Uri selectedVideoUri,
ContentResolver contentResolver) {
String filePathString;
String[] filePathColumn = { MediaColumns.DATA };
Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn,
null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePathString = cursor.getString(columnIndex);
cursor.close();
return filePathString;
}
and now use this filepath ..
try {
if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) {
InputStream is = mApplication.getContentResolver()
.openInputStream(filePath); // ** change is here
mRotation = Exif.getOrientation(is);
Utils.closeSilently(is);
}
** mFileDescriptor = mApplication.getContentResolver()
.openFileDescriptor(filePath, "r"); **
if (jc.isCancelled()) return STATE_INIT;
return STATE_DOWNLOADED;
} catch (FileNotFoundException e) {
Log.w(TAG, "fail to open: " + mUri, e);
return STATE_ERROR;
}
this is work for me
When I pick the default ringtone, I get a Uri with path content://settings/system/ringtone. So there is no path ending with integer, as in returning a usual rintone (for example, content://media/internal/audio/media/38).
How can I now get a resource id from this default ringtone? Any parsing is impossible since there is no any integer identification.
If your check the setting db, you will find the content save to setting db is media uri. That means below uri actually is a map to media uri.
From:
content://settings/system/ringtone
To:
content://media/internal/audio/media/38
So you need to write a converter to do it:
public Uri uriMap(Uri uri) {
Uri mediaUri = uri;
if(uri.getAuthority().equals(Settings.AUTHORITY)) {
Cursor c = null;
try {
c = getContentResolver().query(uri,new String[]{
Settings.NameValueTable.VALUE},null,null,null);
if(c != null && c.moveToFirst()) {
String val = c.getString(0);
mediaUri = Uri.parse(val);
}
} catch (Exception e) {
}finally {
c.close();
}
}
Log.e(TAG,"" + uri + "->" + mediaUri);
return mediaUri;
}
I'm using the Android's DownloadManager class. It returns Uri with content:// scheme after clicking on the "downloaded file" notification. I have a method which is now only able to open files using file Uris (with "file" scheme). What is the easiest way to get the File file from the content Uri. Any examples are welcome.
public PlsReader(URI path) {
File file = new File(path);
}
Use Context#getContentResolver().openInputStream(uri) to get an InputStream from a Uri.
Or use Context#getContentResolver().openFileDescriptor() to get a ParcelFileDescriptor. Then use ParcelFileDescriptor#getFileDescriptor() to get a FileDescriptor.
try this
1st method to get is below
Uri.getPath();
this will give u whole absolute path of any file
and 2nd method is below
Strinf absolutepath = getRealPathFromURI(this,URI);
and method getRealPathFromURI is here
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();
}
}
}
then pass this absolutepath string to your file like this
public PlsReader(String absolutepath ) {
File file = new File(absolutepath );
}
best of luck dude :)
I'm trying to write a simple activity which does the following:
A user holds down on an image viewed in the Android Browser and then presses "Share image" and chooses my Activity to handle it. I want to be able to open the image file from within my activity.
The file path ends up being: /data/data/com.android.browser/app_sharedimage/SOME_FILE_NAME.jpg
and calling "File()" on the path results in a permission error:
java.io.FileNotFoundException: /data/data/com.android.browser/app_sharedimage/SOME_FILE_NAME.jpg (Permission denied")
How can I open this image file? Is there some permission I need to put in the manifest?
Here's the relevant code:
if (Intent.ACTION_SEND.equals(intent.getAction())) {
if (extras.containsKey(Intent.EXTRA_STREAM)) {
Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
String scheme = uri.getScheme();
if (scheme.equals("content")) {
String mimeType = intent.getType();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(uri, null, null,
null, null);
cursor.moveToFirst();
String filePath = cursor.getString(cursor
.getColumnIndexOrThrow(Images.Media.DATA));
...
...
new FileBody(new File(filePath))
...
AFAIK you wont be able to access private files of any other applications unless your phone is rooted. So I think you wont be able open the image.
I can display (I suppose this is what you mean by opening) an image from the browser on a HTC Desire and it is not rooted.
I use the URI just like you from the extras in the Intent. Then I get an InputStream and create a Drawable from it, which can be displayed in an ImageView.
The URI I get is:
content://htcbrowser/share_image/data/data/com.android.browser/app_sharedimage/logo3w.png?image/png
if (intent.getType() != null && intent.getType().indexOf("image/") != -1) {
Bundle extras = intent.getExtras();
if (extras.containsKey(Intent.EXTRA_STREAM)) {
Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
try {
InputStream is = getContentResolver().openInputStream(uri);
Drawable myDrawable = Drawable.createFromStream(is, "srcName");
iv.setImageDrawable(myDrawable);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}