I am going on with my surfaceview camera activty in that i want to get the MimeTye file from Uri of local path while calling the gallery can get the MimeType from Content Uri but while loading from camera can't get the MimeType for that tried to convert the localpath from file to Content Uri for that tried with below:
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
// Uri baseUri = Uri.parse(stringUri);
return Uri.withAppendedPath(uploadImageURI, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
follwed the link :http://android-er.blogspot.in/2011/04/convert-uri-to-real-path-format.html but the issue didn't fixed.
How to solve this is there any other solution to fix the issue.Is there please help me friends
if you have URI then you can get mimetype like
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
or try
// url = file path or whatever suitable URL you want.
public static String getMimeType(String url)
{
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
type = mime.getMimeTypeFromExtension(extension);
}
return type;
}
For more details see these Answers
Related
To support Android 11 storage, I have implemented Scoped Storage - MediaStore API successfully. However, I ended up with one scenario which I am not sure how to resolve. Scenario is, When the Application is launched for the first time, we have created the Folder under Documents folder and able to read and write files into this folder without creating any duplicate folders. However, If I do Clear Data and re-login the Application, I am not able to fetch the folder which is already created and each time it is creating a new folder with duplicate name - Suffix as (2), (3) etc..,
Please find my code which I tired and also find the screenshots.
File folder = null;
String folderName = "Duration";
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
Uri contentUri = MediaStore.Files.getContentUri("external");
String filePath = FileUtils.readFileExternalStorage(contentUri,context,folderName).getPath();
if (!TextUtils.isEmpty(filePath) && FileUtils.isFileExisting(filePath)) {
folder = new File(filePath);
} else {
Uri uri = FileUtils.createFileExternalStorage(contentUri,context,folderName),Environment.DIRECTORY_DOCUMENTS);
Commons.print("URI "+uri.getPath());
folder = new File(FileUtils.getPath(context,uri));
}
if (!folder.exists()) {
folder.mkdirs();
}
} else {
folder = getStorageDir(folderName);
bmodel.deleteFiles(getStorageDir(folderName) + "/", filename);
}
File file = new File(folder, filename );
if(file.exists()) {
file.delete();
}
if (SynchronizationHelper.bcpJSONData != null) {
FileOutputStream outputStream;
try {
Commons.print("FilePath " + file.getPath());
outputStream = new FileOutputStream(file);//context.openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(SynchronizationHelper.bcpJSONData.getBytes());
outputStream.close();
outputStream = null;
SynchronizationHelper.bcpJSONData = null;
} catch (Exception e) {
e.printStackTrace();
}
}
This is FileUtils class:
#RequiresApi(api = Build.VERSION_CODES.Q)
public static File readFileExternalStorage(Uri contentUri, Context context, String filename) {
final String selection = MediaStore.Files.FileColumns.DISPLAY_NAME + "=?";
final String[] selectionArgs = new String[] {filename};
return new File(getDataColumn(context,contentUri,selection,selectionArgs));
}
#RequiresApi(api = Build.VERSION_CODES.Q)
public static Uri createFileExternalStorage(Uri contentUri, Context context, String filename, String folder) {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename);
values.put(MediaStore.MediaColumns.RELATIVE_PATH, folder);
return context.getContentResolver().insert(contentUri, values);
}
public static String getDataColumn(Context context, Uri uri,
String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };
try {
cursor = context.getContentResolver().query(uri, projection,
selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return "";
}
#TargetApi(Build.VERSION_CODES.KITKAT)
#SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {
// check here to KITKAT or new version
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };
return getDataColumn(context, contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return "";
}
On every instance after clearing data of the application, this method getDataColumn() is returning "" empty and on Debugging I found that the Cursor inside the try block, is not fetching anything out of it.
Well, You should consider 2 things first.
1. Don't create the folder if it already exists
2. Load media from the folder with different code
So, here is a little help.
1. Check the existence of the directory.
if (!file.exists()) {
createFolder();
}
Then
2. Load media differently
private ArrayList<Media> loadMedia(String directory_name) {
mediaList = new ArrayList<>();
String selection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
selection = MediaStore.MediaColumns.RELATIVE_PATH + " LIKE ? ";
} else {
selection = MediaStore.Images.Media.DATA + " LIKE ? ";
}
String[] selectionArgs = new String[]{directory_name};
Cursor cursor = getContentResolver().query(
MediaStore.Files.getContentUri("external"),
null,
selection,
selectionArgs,
MediaStore.Video.Media.DATE_TAKEN + " DESC");
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
do {
int imageCol = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
long id = cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID));
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
long date = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
String pathId = cursor.getString(imageCol);
Uri uri = Uri.parse(pathId);
Uri contentUri;
if (uri.toString().endsWith(".mp4")) {
contentUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);
} else {
contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
}
Media media = new Media();
media.setPath(path);
media.setMediaStoreUri(contentUri);
media.setUri(uri);
media.setAlbumName(new File(path).getParent());
mediaList.add(media);
}
while (cursor.moveToNext());
cursor.close();
}
}
return mediaList;
}
This code is working perfectly in all of the devices including Android 10 and above. Give it a try.
All the best!
Before SDK 29 this is the correct way to find the Uri but now it won't work anymore for sdk greater than 28. Let's assume I save the BITMAP using scoped-storage like:
#RequiresApi(api = Build.VERSION_CODES.Q)
#NonNull
private Uri saveBitmap(#NonNull final Context context, #NonNull final Bitmap bitmap,
#NonNull final Bitmap.CompressFormat format, #NonNull final String mimeType,
#NonNull final String displayName, #Nullable final String subFolder) throws IOException {
String relativeLocation = Environment.DIRECTORY_PICTURES;
if (!TextUtils.isEmpty(subFolder)) {
relativeLocation += File.separator + subFolder;
}
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
final ContentResolver resolver = context.getContentResolver();
OutputStream stream = null;
Uri uri = null;
try {
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
uri = resolver.insert(contentUri, contentValues);
if (uri == null) {
throw new IOException("Failed to create new MediaStore record.");
}
stream = resolver.openOutputStream(uri);
if (stream == null) {
throw new IOException("Failed to get output stream.");
}
if (!bitmap.compress(format, 95, stream)) {
throw new IOException("Failed to save bitmap.");
}
return uri;
} catch (IOException e) {
if (uri != null) {
// Don't leave an orphan entry in the MediaStore
resolver.delete(uri, null, null);
}
throw e;
} finally {
if (stream != null) {
stream.close();
}
}
}
This code works for SDK <= 28. But, How to get URI using fileName which is saved in the external storage for SDK version 29 and above?
private String getFilePathUri(String enteredFileName) {
String file_uri_string = Environment.getExternalStorageDirectory() + "/"
+ AppConstants.APP_FOLDER + "/" + enteredFileName + ".jpg";
AppUtils.showLog(TAG, file_uri_string + "");
return file_uri_string;
}
Android 10 and above: Here the uri gives the file_id based you the given displayName.
/**
* Returns the Uri which can be used to delete/work with images in the photo gallery.
* #param displayName Path to IMAGE on SD card
* #return Uri in the format of... content://media/external/images/media/[NUMBER]
*/
private Uri getUriFromPath(String displayName) {
long photoId;
Uri photoUri = MediaStore.Images.Media.getContentUri("external");
String[] projection = {MediaStore.Images.ImageColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = getContentResolver().query(photoUri, projection, MediaStore.Images.ImageColumns.DISPLAY_NAME + " LIKE ?", new String[] { displayName }, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
photoId = cursor.getLong(columnIndex);
cursor.close();
return Uri.parse(photoUri.toString() + "/" + photoId);
}
When I'm going select a file from all downloads folder and then getting file path from uri using content provider getting following permission denied issue below
Permission Denial: reading com.android.providers.downloads.DownloadProvider uri content://downloads/all_downloads/1092 from pid=31615, uid=10228 requires android.permission.ACCESS_ALL_DOWNLOADS, or grantUriPermission()
using following code
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/my_downloads",
"content://downloads/all_downloads"
};
final String id = DocumentsContract.getDocumentId(uri);
String path = null;
for (String uriPath : contentUriPrefixesToTry) {
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse(uriPath), Long.valueOf(id));
String lastPathSagment = uri.getLastPathSegment();
InputStream inputStream = context.getContentResolver().openInputStream(uri);
File file = new File(context.getCacheDir().getAbsolutePath() + "/" + lastPathSagment);
writeFile(inputStream, file);
path = file.getAbsolutePath();
if (path != null) {
return path;
}
}
I had the above issue, but found a solution. I was using ACTION_GET_CONTENT to pick a file from external storage, but it does not work in Android 7 and above. Someone guided me to use ACTION_OPEN_DOCUMENT to pick a file, and now it's working fine for me.
Intent PDF Picker:
if (Build.VERSION.SDK_INT <19) {
Intent pdfIntent = new Intent(Intent.ACTION_GET_CONTENT);
pdfIntent.setType("application/pdf");
startActivityForResult(pdfIntent, PICK_PDF);
} else {
Intent pdfIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
pdfIntent.setType("application/pdf");
pdfIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(pdfIntent, PICK_PDF);
}
Code to get File Path:
if (isDownloadsDocument(uri)) {
String fileName = getFilePath(context, uri);
if (fileName != null) {
return String.format("%s/Download/%s", Environment.getExternalStorageDirectory().toString(), fileName);
}
String id = DocumentsContract.getDocumentId(uri);
if (id.startsWith("raw:")) {
id = id.replaceFirst("raw:", "");
File file = new File(id);
if (file.exists())
return id;
}
}
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
Methods used in above code:
public static String getFilePath(Context context, Uri uri) {
Cursor cursor = null;
final String[] projection = { MediaStore.MediaColumns.DISPLAY_NAME };
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
return cursor.getString(index);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
Your code is 'trying' to access that directory to see if it exists, and even open an inputstream to get the supposed File. If the directory doesn't exist Android will be displeased with you and tell you that you're not allowed to access that dir.
No need to request permission as the dir does not exist.
I am trying to make an android camera app with image gallery. The images captured are saved to a private directory: Android/data/com.example.newcamera/files/pictures.
Whenever I am using INTERNAL_CONTENT_URI or, EXTERNAL_CONTENT_URI as Uri, The app is bringing all the public pictures of my phone but not the one in the private directory. But I need only those with private directory. How can I get it? Please help me. My code snippet is as follows:
Thanks in advance.
protected String doInBackground(String... args) {
String xml = "";
String path = null;
String album = null;
String timestamp = null;
String countPhoto = null;
Uri uriInternal = MediaStore.Images.Media.INTERNAL_CONTENT_URI;
Uri uriExternal = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri myUri = Uri.fromFile(new File(getApplicationContext().getFilesDir().getAbsolutePath()));
String[] projection = { MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.MediaColumns.DATE_MODIFIED };
Cursor cursorExternal = getContentResolver().query(uriExternal, projection, "_data IS NOT NULL) GROUP BY (bucket_display_name",
null, null);
Cursor cursorInternal = getContentResolver().query(uriInternal, projection, "_data IS NOT NULL) GROUP BY (bucket_display_name",
null, null);
Cursor myCursor = getContentResolver().query(myUri, projection, "_data IS NOT NULL) GROUP BY (bucket_display_name",
null, null);
Cursor cursor = new MergeCursor(new Cursor[]{cursorExternal, cursorInternal, myCursor});
while (cursor.moveToNext()) {
path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA));
album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
timestamp = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED));
countPhoto = Function.getCount(getApplicationContext(), album);
albumList.add(Function.mappingInbox(album, path, timestamp, Function.converToTime(timestamp), countPhoto));
}
cursor.close();
Collections.sort(albumList, new MapComparator(Function.KEY_TIMESTAMP, "dsc")); // Arranging photo album by timestamp decending
return xml;
}
You can fetch your files from particular folder by:
File folder = new File(Environment.getExternalStorageDirectory().toString() + "/Folder Name/");
folder.mkdirs();
File[] allFiles = folder.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png"));
}
});
You can convert file path to Uri by Uri.fromFile(YOUR FILE)
i am getting below type of uri:
/mnt/sdcard/Pictures/WW/ww_1360248819300.jpg
how to convert above type of URI to below URI:
content://media/external/images/media/12
please help
Thanks
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}