I want to get all types of documents pdf,xml,doc except video and image and audio files.
And display list with name, size, date, and location.
ContentResolver cr = context.getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
// every column, although that is huge waste, you probably need
// BaseColumns.DATA (the path) only.
String[] projection = null;
// exclude media files, they would be here also.
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;
String[] selectionArgs = null; // there is no ? in selection so null here
String sortOrder = null; // unordered
Cursor allNonMediaFiles = cr.query(uri, projection, selection, selectionArgs, sortOrder);
I am using this code for getting documents from mobile is it work? And how to get the document details like uri, date, and name. thanks advance.
Try this one:
File path;
ArrayList<String> pdf_paths=new ArrayList<String>();
ArrayList<String> pdf_names=new ArrayList<String>();
path = new File(Environment.getExternalStorageDirectory() + "");
searchFolderRecursive1(path);
private static void searchFolderRecursive1(File folder)
{
if (file.isFile())
{
//.pdf files
if(file.getName().contains(".pdf"))
{
file.getPath();
pdf_names.add(file.getName());
pdf_paths.add(file.getPath());
Log.e("pdf_paths", ""+pdf_names);
}
else if(file.getName().contains(".doc"))
{
file.getPath();
pdf_names.add(file.getName());
pdf_paths.add(file.getPath());
}
}
}
String ext =FilenameUtils.getExtension(mediSore.getString(mediSore.getColumnIndex(MediaStore.Files.FileColumns.DATA)));
if(ext.equals("pdf") || ext.equals("txt")|| ext.equals("docx") ||
ext.equals("xlsx") ||
ext.equals("csv")||
ext.equals("ods")||
ext.equals("odt")
) {
Array.add(
mediSore.getString(mediSore.getColumnIndex(MediaStore.Files.FileColumns.DATA)) + " -- " +
mediSore.getString(mediSore.getColumnIndex(MediaStore.Files.FileColumns.TITLE)) + "---" +
mediSore.getString(mediSore.getColumnIndex(MediaStore.Files.FileColumns.DISPLAY_NAME))
);
Heading
Related
I have a custom folder in the Pictures directory, like this Pictures/MyFolder. It has images in MyFolder. Here is how to share the images using ContentResolver on MyFolder only. Or is any alternative ways to share the image. It is on android 11.
I queried images using the following snippets
String[] projection = new String[]{
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN};
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
Cursor cur = context.getContentResolver().query(images,
projection, // Which
// columns
// to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
orderBy + " DESC" // Ordering
);
int bucketColumn = cur.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN);
do {
bucket = cur.getString(bucketColumn);
if (bucket.equals(context.getString(R.string.app_name))) {
date = cur.getString(dateColumn);
imagePath = listImageByFolder.get(bucket);
if (imagePath == null) {
imagePath = new ArrayList<String>();
}
imagePath.add(cur.getString(cur.getColumnIndex(MediaStore.Images.Media.DATA)));
Uri x = Uri.withAppendedPath(MediaStore.Images.Media.INTERNAL_CONTENT_URI, String.valueOf(cur.getString(cur.getColumnIndex(MediaStore.Images.Media.DATA))));
listImageByFolder.put(bucket, imagePath);
} ;
} while (cur.moveToNext());
While I try to share the image, Getting android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/WhatsTouch/1628090801008.jpg exposed beyond app through ClipData.Item.getUri() exception. Is any way to correct it or is any alternative way?
I just need the path of folders that contain at least one file that ends with eg. .mp4 or .jpg . I already checked this thread: Android: how to get all folders with photos? but it's too slow for my use case. Is there a faster way to do that?
So I finally found a solution which is way faster than the mentioned above. I got all directories with images within ~100-150ms (around 3k files). In the example below all image files stored either on the internal or external storage gets checked and the parent directory is added to the array list. I excluded .gif and .giff files.
This method also works with videos therefore a few steps are required:
change queryUri to MediaStore.Video.Media.EXTERNAL_CONTENT_URI
change projection to MediaStore.Video.Media.DATA
change 'image/%' in includeImages to 'video/%'
delete + excludeGif from selection
public static ArrayList<String> getImageDirectories(Context mContext) {
ArrayList<String> directories = new ArrayList<>();
ContentResolver contentResolver = mContext.getContentResolver();
Uri queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = new String[]{
MediaStore.Images.Media.DATA
};
String includeImages = MediaStore.Images.Media.MIME_TYPE + " LIKE 'image/%' ";
String excludeGif = " AND " + MediaStore.Images.Media.MIME_TYPE + " != 'image/gif' " + " AND " + MediaStore.Images.Media.MIME_TYPE + " != 'image/giff' ";
String selection = includeImages + excludeGif;
Cursor cursor = contentResolver.query(queryUri, projection, selection, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
String photoUri = cursor.getString(cursor.getColumnIndex(projection[0]));
if(!directories.contains(new File(photoUri).getParent())){
directories.add(new File(photoUri).getParent());
}
} while (cursor.moveToNext());
}
return directories;
}
We are trying to fetch the path of a file that is saved in SD Card, to pass on to a utility. However when we use the URI to open a cursor, only two columns are being fetched, the path (_data column) is missing. Please let me know how to fetch the path. The query works fine for any file that is in internal storage.
Scheme is "content".
Code snippet
cursor = context.getContentResolver().query(uri, null, null, null, null);
if (null != cursor && cursor.moveToFirst())
{
int testcolCount = cursor.getColumnCount();
for (int i = 0; i < testcolCount; i++)
{
String colName = cursor.getColumnName(i);
String colValue = cursor.getString(i);
System.out.println("" + i + ": " + colName + ":" + colValue + "\n");
}
//This prints only two columns, _display_name and _size
}
Don't try and get the path at all, with Android 10 and above file paths outside of your App's private directories are useless because you won't have permission to access them.
See https://developer.android.com/training/data-storage#scoped-storage
Use the contentResolver to get a FileDescriptor to pass on to the Utility
Note From https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#DATA
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.
try this code i am using this function to get real path from uri:
private String getRealPathFromURI(Context mContext, Uri contentURI) {
String result = null;
Cursor cursor = null;
try {
String[] proj = {MediaStore.Video.Media.DATA};
ContentResolver mContentResolver = mContext.getContentResolver();
String mime = mContentResolver.getType(contentURI);
cursor = mContentResolver.query(contentURI, proj, null, null, null);
if (cursor == null) {
return null;
} else {
cursor.moveToFirst();
int column_index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
if (column_index > -1)
result = cursor.getString(column_index);
cursor.close();
}
} catch (Exception e) {
return null;
} finally {
if (cursor != null)
cursor.close();
}
return result;
}
it will return a string which is real path of your file.
hope it will help you.
The default File manager was the one causing this problem - not returning "DATA" column and returning Authority as "com.lenovo.FileBrowser.FileProvider". When I used another file manager, the Authority was "media". Also got the path column using "DATA" while running the ContenResolver. Thanks to all for taking the effort to help out.
I want to create scanner that is showing only folders that have music in them. i know only how to create query for getting music from path using MediaStore
public static QueryTask buildFileQuery(String path, String[] projection)
{
// It would be better to use selectionArgs to pass path here, but there
// doesn't appear to be any way to pass the * when using it.
StringBuilder selection = new StringBuilder();
selection.append("_data GLOB ");
DatabaseUtils.appendEscapedSQLString(selection, path);
// delete the quotation mark added by the escape method
selection.deleteCharAt(selection.length() - 1);
selection.append("*' AND is_music!=0");
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
QueryTask result = new QueryTask(media, projection, selection.toString(), null, DEFAULT_SORT);
result.type = TYPE_FILE;
return result;
}
MediaStore.Audio.Media.DATA column contains filepath
Cursor c = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA},
MediaStore.Audio.Media.IS_MUSIC + "=1",
null,
MediaStore.Audio.Media.DATA
);
if (c.moveToFirst()) {
do {
Log.d("T", c.getString(0) + " -- " + c.getString(1));
} while (c.moveToNext());
}
This should output the following:
Come On -- /storage/emulated/0/Music/The Rolling Stones/More Hot Rocks Big Hits & Fazed Cookies (Disc 2)/10 Come On.mp3
...
Once you have paths you can restore folder hierarchy
my app creates new contacts with ContentProviderOperation. The problem is, I need a reference to the new contact because I need some information of it to display it in a listview and go with intent into the contact app to the contact.
The best thing would be the ID, but I´ve read that it might change during operations on the database, which won´t be helpful to me.
Now I thought, the Uri might be the best thing, because I could later retrieve the contactID or lookup key.
How do I get the Uri directly after calling applyBatch() ?
EDIT:
Here is a solution, but not really a good one.
He is putting a randomly generated token into each contact, then he makes a new query with it.
I want neither put some extra data into the contacts, nor starting a second query. But if there is no other possibility I´ll do it that way.
simply call
private String retrieveContactId(String phoneNo) {
try {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNo));
String[] projection = new String[] { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME };
String selection = null;
String[] selectionArgs = null;
String sortOrder = ContactsContract.PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ContentResolver cr = getApplicationContext().getApplicationContext().getContentResolver();
String contactId = null;
if (cr != null) {
Cursor resultCur = cr.query(uri, projection, selection, selectionArgs, sortOrder);
if (resultCur != null) {
while (resultCur.moveToNext()) {
contactId = resultCur.getString(resultCur.getColumnIndex(ContactsContract.PhoneLookup._ID));
Log.e("Info Incoming", "Contact Id : " + contactId);
return contactId;
}
resultCur.close();
}
}
} catch (Exception sfg) {
Log.e("Error", "Error in loadContactRecord : " + sfg.toString());
}
return null;
}
and for the uri
Uri contactUri = Contacts.getLookupUri(
Integer.valueOf(rawContactId), clookup);