I am able to get the files path from URI fetched from notification bar but I could only fetch it from URI received from Android Snackbar.
Current function used to fetch the path:
Note: This works fine for pre-Marshmallow Android versions.
private String extractContentUri(Uri uri) {
Cursor cursor = null;
try {
cursor = getContentResolver().query(uri, null, null, null, null);
Log.d("CHECK", "COUNT" + cursor.getCount());
if (cursor != null && cursor.moveToFirst()) {
Log.d("CHECK", "CURSOR !NULL");
launchedFile = cursor.getString(cursor.getColumnIndexOrThrow("_data"));
Log.d("CHECK", "==" + launchedFile);
return launchedFile;
}
} catch (IllegalArgumentException e) {
} finally {
Log.d("CHECK", "{finally} ==" + launchedFile);
if (cursor != null) {
cursor.close();
cursor = null;
}
}
return null;
}
In android M the URI obtained while accessing the from notification bar and from snackbar are different.
URI from notification bar: content://downloads/all_downloads/1449
URI from snackbar: content://downloads/my_downloads/1449
cursor = getContentResolver().query(uri, null, null, null, null);
here the cursor.getCount() is always 0 for snackbar.
You need to add Runtime permission for Android 6 and above version. Please check this for Run time permission.
Related
I am trying to get real path for Picked image in Android 10 but it's not working Iam using the folowing code its work fine in android 9
public static String getRealPathFromURI(Context context, Android.Net.Uri contentUri)
{
ICursor cursor = context.ContentResolver.Query(contentUri, null, null, null, null);
cursor.MoveToFirst();
String document_id = cursor.GetString(0);
document_id = document_id.Substring(document_id.LastIndexOf(":") + 1);
cursor.Close();
cursor = context.ContentResolver.Query(
Android.Provider.MediaStore.Images.Media.ExternalContentUri,
null, MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new string[] { document_id }, null);
cursor.MoveToFirst();
String path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data));
cursor.Close();
return path;
}
Option1
After SDK 29.0 ,DATA is deprecated . 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.
Here is a similar thread which you can refer .
Option 2
You could install the plugin Xam.Plugin.Media from nuget .
Usage
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
var path = file.Path;
For more details about the plugin you could check https://github.com/jamesmontemagno/MediaPlugin
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 get History of sbrowser? I try used "com.sec.android.app.sbrowser.browser/history" but it is not working.
final Uri uri = Uri.parse("content://com.sec.android.app.sbrowser.browser/history");
final Cursor c = getContentResolver().query(uri, null, null, null, null);
if (c!=null && c.moveToFirst()) {
do {
System.out.println(c.getString(c.getColumnIndex("URL")));
} while(c.moveToNext());
}
I had a similar issue and I found that the correct URI is
content://com.sec.android.app.sbrowser.browser/bookmarks
Check out this post Android Browser.BOOKMARKS_URI does not work on all devices. How to find out the correct uri for a given device?
The other way to get the history
Cursor mycur = managedQuery(Browser.BOOKMARKS_URI, Browser.HISTORY_PROJECTION, null,
null, null);
int count = mycur.getCount();
mycur.moveToFirst();
if(mycur.moveToFirst() && count>0)
{
while(count>0)
{
Log.e("title",mycur.getString(Browser.HISTORY_PROJECTION_URL_INDEX));
mycur.moveToNext();
}
}
You can check below also some other answers
Get browser history and search result in android
I'm trying to retrieve the metadata from a video file (title, language, artist) using the method MediaStore.Video.query(). However, the method is always returning null. The code is bellow:
String[] columns = {
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.TITLE,
MediaStore.Video.VideoColumns.ARTIST
};
Cursor cursor = MediaStore.Video.query(getApplicationContext().getContentResolver(), videoUri,columns);
if (cursor != null) {
cursor.moveToNext();
}
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE));
Any suggestion about how to return video metadata using android?
==Update
As I searched in many places, I tried one solution using CursorLoader. However, the method loadInBackground() from CursorLoader is also returning null. The code is showed bellow:
String[] columns = {
MediaStore.Video.VideoColumns.TITLE
};
Uri videoUri = Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4");
CursorLoader loader = new CursorLoader(getBaseContext(), videoUri, columns, null, null, null);
Cursor cursor = loader.loadInBackground();
cursor.moveToFirst();
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE));
Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4") is not an Uri for MediaStore. It would try to find a ContentProvider for authority mnt which does not exist.
MediaStore can handle only content://media/... Uris which you should get exclusively via MediaStore, not by using Uri.parse().
In your case use the following for example
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] columns = {
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.TITLE,
MediaStore.Video.VideoColumns.ARTIST
};
String selection = MediaStore.Video.VideoColumns.DATA + "=?";
String selectionArgs[] = { "/mnt/sdcard/Movies/landscapes.mp4" };
Cursor cursor = context.getContentResolver().query(uri, columns, selection, selectionArgs, null);
The MediaStore.Video.VideoColumns.DATA field holds the path to the videos and you search for a certain video this way. At least for now, future versions of Android may change that.
Your second example is using CursorLoader the wrong way. If you call loader.loadInBackground() yourself, you load the data in foreground. See e.g. http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/
The next thing you do is
Cursor cursor = getCursor();
cursor.moveToFirst();
String title = cursor.getString(/* some index */);
This will lead to a CursorIndexOutOfBoundsException if your cursor has 0 rows and cursor.moveToFirst() failed because there is no first row. The cursor stays before the first row (at -1) and that index does not exist. That would mean in your case that the file was not found in the database.
To prevent that use the return value of moveToFirst - it will only be true if there is a first row.
Cursor cursor = getCursor(); // from somewhere
if (cursor.moveToFirst()) {
String title = cursor.getString(/* some index */);
}
A more complete example including checks for null and closing the cursor in all cases
Cursor cursor = getCursor(); // from somewhere
String title = "not found";
if (cursor != null) {
if (cursor.moveToFirst()) {
title = cursor.getString(/* some index */);
}
cursor.close();
}
I guess the file you try to find is either not indexed in the database (rebooting forces the indexer to run again) or the path is wrong.
Or the path you use is actually a symlink in which case MediaStore might use a different path.
Use this to get rid of symlinks
String path = "/mnt/sdcard/Movies/landscapes.mp4";
try {
path = new File(path).getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
Yes, I tested now and it is throwing IndexOutOfBoundsException. When I'm using cursor.getColumnCount() it returns 1
cursor.getColumnCount() is the column count, not the row count. It should always be the same as the number of columns you requested in columns. You need to check cursor.getCount() if you want to check the row count.
Try dumping all the videos known to MediaStore into logcat in case it does not show as expected.
public static void dumpVideos(Context context) {
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns.DATA };
Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
int vidsCount = 0;
if (c != null) {
vidsCount = c.getCount();
while (c.moveToNext()) {
Log.d("VIDEO", c.getString(0));
}
c.close();
}
Log.d("VIDEO", "Total count of videos: " + vidsCount);
}
I updated your code, it works, just check it
public static void dumpVideos(Context context) {
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns.DATA };
Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
int vidsCount = 0;
if (c != null) {
c.moveToFirst();
vidsCount = c.getCount();
do {
Log.d("VIDEO", c.getString(0));
}while (c.moveToNext());
c.close();
}
Log.d("VIDEO", "Total count of videos: " + vidsCount);
}
I want to get the group id of each contact in my android application.I have initial query like this
Cursor cursor = cr.query(Phone.CONTENT_URI,
new String[] {
Phone.CONTACT_ID}, null, null, null);
And what i do is get details of each which related to this CONTACT_ID.I have manage to get phone number,names,addresses and emails so far but still couldn't manage to get the group id of the contact.
P.S i found a question asked before here but the class android.provider.Contacts.GroupMembership is deprecated.
thanks.
Try this:
final String selection = "mimetype_id = (select _id from mimetypes where mimetype = \"" +
vnd.android.cursor.item / group_membership + "\")";
Cursor cursor = getContentResolver().query(Data.CONTENT_URI,
new String[]{Phone.CONTACT_ID}, selection, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
do {
Log.i("Details", "Contact IDs" + cursor.getLong(cursor.getColumnIndex(Phone.CONTACT_ID)));
} while (cursor.moveToNext());
}
} finally {
if (cursor != null) {
cursor.close();
}
}