When I select an image from the gallery, I grab the intent Uri via the parameter that is passed by the onActivityResult. When doing: new File(String_Uri_given_to_me) and do File.Exists(), gives me null...
What I can do?
It seems you may try:
new File(Uri_given_to_you.getpath())
It may be okay.
If answer above doesn't solve your problem use this code
private final synchronized String getPath(Uri uri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, proj,
null, null, null);
if (cursor.moveToFirst()) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
I was having a hard time with this issue. I was not able to get some images Path (Even using Maxim Efivmov code) and finally decided to use Google's documentation on this topic. https://developer.android.com/guide/topics/providers/document-provider.html
This piece of code worked to get the bitmap
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
You can use this bitmap to display it in an Image View.
Related
What might the cause of getColumnIndexOrThrow that would throw an exception of
java.lang.IllegalArgumentException: column '_data' does not exist. Available columns: []
yet if you rename the file and retry again, it works?
private static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String[] projection = {
MediaStore.Files.FileColumns.DATA
};
try {
cursor = context.getContentResolver().query(
uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int cindex = cursor.getColumnIndexOrThrow(projection[0]);
return cursor.getString(cindex);
}
}
catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
the original file comes in the intent of
content://com.sec.android.app.myfiles.FileProvider/device_storage/Download/myfile.pdf
yet the renamed file comes in as
content://0#media/external/file/588
This MediaStore.Files.FileColumns.DATA is deprecated and column '_data' doesn't exist anymore.
As Android Developer stated
This constant was deprecated in API level 29.
Apps may not have filesystem permissions to directly access this path.
Instead of trying
to open this path directly, apps should use
ContentResolver#openFileDescriptor(Uri, String) to gain access.
How To use openFileDescriptor?
i try to bring examples of 2 different widely use files in across application
Image Files
if(uri==null)return;
ContentResolver contentResolver = getActivity().getContentResolver();
if(contentResolver==null)return;
ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri,"rw");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
if(fileDescriptor==null)return;
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
There are a lot of examples of how to handle bitmap
Non-Image Files
if(uri==null)return;
ContentResolver contentResolver = getActivity().getContentResolver();
if(contentResolver==null)return;
ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri,"rw");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
if(fileDescriptor==null)return;
FileInputStream fileInputStream = new FileInputStream(fileDescriptor);
FileOutputStream fileOutputStream = new FileOutputStream(fileDescriptor);
parcelFileDescriptor.close();
There are a lot of examples of how to handle FileInputStream and FileOutputStream
Conclusion
There is no sense trying to get absolute Path although it isn't necessary unless raising security & privacy issues.Indeed, Relative path is enough for working with files and there are Abstract Representation implementations between kernel Mode and User Mode that can Map Relative Path to Absolute Path and User doesn't need to know.
openFileDescriptor is very fast and compatible to all android versions
I want thumbnail from a video at any specific position. I am using ThumbnailUtils in order to get thumbnail from video uri and assigning to bitmap but I am getting null value on bitmap.
Any reasons how this is happening and how do I fix this?
selectedVideoUri = data.getData();
bitmap = ThumbnailUtils.createVideoThumbnail(getRealPathFromURI(videoUri),
MediaStore.Images.Thumbnails.MINI_KIND);
public String getRealPathFromURI(Uri contentUri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
if(cursor.moveToFirst()){;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
You can use Glide to load thumb directly to imageview
Glide.with(activity).load(videoPath).into(imageview);
First Load Video List with its path in Your array list using below method
private void loadData(String currentAppPath) {
hiddenpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + currentAppPath);
String[] fileName = hiddenpath.list();
try{
for(String f : fileName){
if(HelpperMethods.isVideo(f)){
videoFiles.add(hiddenpath.getAbsolutePath()+"/"+f);
}
}
new Loader().loadImages(Environment.getExternalStorageState());
}catch (Exception e){
}
}
You need Loader().loadImages method so i declare this method in separate class file. see below code
public class Loader {
String[] imagieFiles;
public void loadImages(String path){
Log.e("path",path);
System.out.println(path);
} }
Then after You can use below Code to Get Video Thumbnail. By default Each Video Store two size Thumbnail.
1) MINI -- MediaStore.Images.Thumbnails.MINI_KIND and
2) MICRO -- MediaStore.Images.Thumbnails.MICRO_KIND
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(filePath,
MediaStore.Images.Thumbnails.MINI_KIND);
BitmapDrawable bitmapDrawable = new BitmapDrawable(thumb);
contentViewHolder.videoView.setImageBitmap(thumb);
This is supported by Android natively using MediaPlayer SeekTo method
If you just want to show the video placeholder to display then you can use below code:
video_view.setVideoPath(videoPath);
video_view.seekTo(3000); // in milliseconds i.e. 3 seconds
ThumbnailUtils returns null when file or video is corrupted.
but I wanted to only use Uri and this is a good solution to do this:
val mmr = MediaMetadataRetriever()
mmr.setDataSource(videoUri)
val thummbnailBitmap = mmr.frameAtTime
imageView.setImageBitmap(thummbnailBitmap)
When I get bitmap for mp4 file with: ThumbnailUtils.createVideoThumbnail(mediaFile.getAbsolutePath(), MediaStore.Video.Thumbnails.MINI_KIND); return null
Try this, May be you media file path was wrong. Use below method you will get exact path. Its working for me
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(getPath(outputFileUri),
MediaStore.Images.Thumbnails.MINI_KIND);
photo_Img.setImageBitmap(thumb);
/**
* Get file path
*/
public static String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I think you must set requires permission in AndroidManifest <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
File file = new File(filepath);
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(file.getAbsolutePath(), MediaStore.Video.Thumbnails.FULL_SCREEN_KIND);
From android docs:
public static Bitmap createVideoThumbnail (String filePath, int kind)
Create a video thumbnail for a video. May return null if the video is corrupt or the format is not supported.
Hence, I guess you need to re-check the mp4 file.
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 writing an app that can be sent a photo URI from the "Share via" menu in Android.
The kind of URI you get is content://media/external/images/media/556 however ExifInterface wants a standard file name. So how do I read the exif data (I just want orientation) of that file? Here's my (non-working) code:
Uri uri = (Uri)extras.getParcelable(Intent.EXTRA_STREAM);
ContentResolver cr = getContentResolver();
InputStream is = cr.openInputStream(uri);
Bitmap bm = BitmapFactory.decodeStream(is);
// This line doesn't work:
ExifInterface exif = new ExifInterface(uri.toString());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Any help (other than "you have to write your own ExifInterface class") is appreciated!
I found the answer randomly in the Facebook Android SDK examples. I haven't tested it, but it looks like it should work. Here's the code:
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
int result = -1;
if (null != cursor) {
if (cursor.moveToFirst()) {
result = cursor.getInt(0);
}
cursor.close();
}
return result;
}
You can get an ExifInterface using a filename string or InputStream, by doing importing the support ExifInterface in your build.gradle file:
compile 'com.android.support:exifinterface:26.1.0'
then:
private getExifInterfaceFromUri(Uri uri) throws IOException{
FileInputStream fi = new FileInputStream(uri.getPath());
return new ExifInterface(stream);
}
Remember that in Android there are multiple Uri types and you may need to use a Content Resolver and other approaches to get the real path from an Uri.