/// <summary> /// List contents of folder via storage access framework (used for Android/data/) /// </summary> /// <param name="uri"></param> /// <param name="path">Optional path</param> /// <returns></returns> public List <FolderChildren> GetFolderChildren(Uri uri, string path) { string[] projection = { DocumentsContract.Document.ColumnDocumentId, DocumentsContract.Document.ColumnLastModified }; var newPath = DocumentsContract.GetTreeDocumentId(uri) + $"/{path}"; var children = DocumentsContract.BuildChildDocumentsUriUsingTree(uri, newPath); List <FolderChildren> folderChildren = new List <FolderChildren>(); //string fileSelectionQuery = null; //Bundle? queryArgs = new Bundle(); /*if (fileSelection != null) * { * var sb = new StringBuilder(); * foreach (var _ in fileSelection) * { * sb.Append("?,"); * } * * var inQuery = sb.ToString().TrimEnd(','); * fileSelectionQuery = DocumentsContract.Document.ColumnDocumentId + $" IN ({inQuery})"; * queryArgs.PutString(ContentResolver.QueryArgSqlSelection, fileSelectionQuery); * queryArgs.PutStringArray(ContentResolver.QueryArgSqlSelectionArgs, fileSelection); * }*/// https://github.com/xamarin/xamarin-android/issues/5788 if (_folderCache.ContainsKey(children !.ToString())) { return(_folderCache[children.ToString() !]);
internal static string GetPathForDocTree(Context context, Uri uri) { var docUri = DocumentsContract.BuildDocumentUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); string path = GetPath(context, docUri); return(path); }
/// <summary> /// return null if the request does not belong to requestId /// </summary> public static Uri ResolveFromActivityResult(Activity activity, Intent data) { var androidUri = data.Data; var takeFlags = data.Flags & (ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission); activity.ContentResolver.TakePersistableUriPermission(androidUri, takeFlags); var storageUri = DocumentsContract.BuildDocumentUriUsingTree(androidUri, DocumentsContract.GetTreeDocumentId(androidUri)); return(new Uri(storageUri.ToString())); }
private async Task <bool> WriteFileAsync(ContentType accessType, string filePath, string storageLocationBase, byte[] bytes) { switch (accessType) { case ContentType.DirectAccess: await File.WriteAllBytesAsync(filePath, bytes); return(true); case ContentType.StorageFramework: // check file exists var fileExistPath = this.GetPathIfFileExists(accessType, filePath, storageLocationBase); Uri contentPath; if (!fileExistPath.Exists) { var pathUri = Uri.Parse(storageLocationBase); //var treeId = DocumentsContract.GetTreeDocumentId(pathUri) + $"/{filePath}"; var treeId = DocumentsContract.GetTreeDocumentId(pathUri) + $"/{Path.GetDirectoryName(filePath)}"; var newPath = DocumentsContract.BuildDocumentUriUsingTree(pathUri, treeId); DocumentFile newFile = DocumentFile.FromTreeUri(Android.App.Application.Context, newPath); var documentFile = newFile.CreateFile("application/octet-stream", Path.GetFileName(filePath)); contentPath = documentFile.Uri; } else { var baseUriParse = Uri.Parse(storageLocationBase); contentPath = DocumentsContract.BuildDocumentUriUsingTree(baseUriParse, fileExistPath.Path); } var descriptor = AppContentResolver.OpenAssetFileDescriptor(contentPath !, "w"); if (descriptor == null) { throw new Exception($"File descriptor null, tried to open {contentPath}."); } var writeStream = descriptor.CreateOutputStream(); if (!writeStream.CanWrite) { throw new Exception("Cannot write the writeStream."); } await writeStream.WriteAsync(bytes); return(true); default: throw new ArgumentOutOfRangeException(nameof(accessType), accessType, null); } }
// Methods private (bool successful, List <AndroidFile> files) RequestFiles(Uri directoryUri) { bool successful; var collection = new List <AndroidFile>(); try { var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree( directoryUri, DocumentsContract.GetTreeDocumentId(directoryUri)); var cursor = ContentResolver.Query( childrenUri, new[] { DocumentsContract.Document.ColumnDisplayName, DocumentsContract.Document.ColumnDocumentId }, null, null, null); try { while (cursor.MoveToNext()) { (var name, var uri) = (cursor.GetString(0), DocumentsContract.BuildDocumentUriUsingTree(directoryUri, cursor.GetString(1))); if (Extensions.Any(ext => name.EndsWith(ext, StringComparison.CurrentCultureIgnoreCase))) { collection.Add(new AndroidFile { Name = name, Uri = uri }); } } successful = true; } finally { cursor.Close(); } } catch (Java.Lang.Exception e) { Log.Debug("??", e, e.Message); successful = false; } return(successful, collection); }
/// <summary> /// Updates the current directory of the uri passed as an argument and its children directories. /// And updates the instance's <see cref="Android.Support.V7.Widget.RecyclerView"/> depending /// on the contents of the children. /// </summary> /// <param name="uri">The uri of the current directory.</param> void UpdateDirectoryEntries(Android.Net.Uri uri) { var contentResolver = Activity.ContentResolver; var docUri = DocumentsContract.BuildDocumentUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); var docCursor = contentResolver.Query(docUri, new [] { DocumentsContract.Document.ColumnDisplayName, DocumentsContract.Document.ColumnMimeType }, null, null, null); try { while (docCursor.MoveToNext()) { Log.Debug(TAG, "found doc =" + docCursor.GetString(0) + ", mime=" + docCursor .GetString(1)); mCurrentDirectoryUri = uri; mCurrentDirectoryTextView.Text = docCursor.GetString(0); mCreateDirectoryButton.Enabled = true; } } finally { CloseQuietly(docCursor); } var childCursor = contentResolver.Query(childrenUri, new [] { DocumentsContract.Document.ColumnDisplayName, DocumentsContract.Document.ColumnMimeType }, null, null, null); try { List <DirectoryEntry> directoryEntries = new List <DirectoryEntry> (); while (childCursor.MoveToNext()) { Log.Debug(TAG, "found child=" + childCursor.GetString(0) + ", mime=" + childCursor .GetString(1)); DirectoryEntry entry = new DirectoryEntry(); entry.fileName = childCursor.GetString(0); entry.mimeType = childCursor.GetString(1); directoryEntries.Add(entry); } mAdapter.SetDirectoryEntries(directoryEntries); mAdapter.NotifyDataSetChanged(); } finally { CloseQuietly(childCursor); } }
/// <summary> /// Handles the result from activities called with StartActivityForResult() /// </summary> /// <param name="requestCode"></param> /// <param name="resultCode"></param> /// <param name="data"></param> protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) { try { base.OnActivityResult(requestCode, resultCode, data); if (resultCode == Result.Ok && data != null && requestCode == OPEN_DOCUMENT_TREE_ACTIVITY) { // keep track of the raw URI data returned from user selection // just in case we need it later? _userSelectedDirectory = data.Data; // keep track of the parent directory // this is used in building document URIs of the children // based on their id this._parentUri = DocumentsContract.BuildDocumentUriUsingTree( _userSelectedDirectory, DocumentsContract.GetTreeDocumentId(_userSelectedDirectory) ); // WARN: This is a little hacky, and might not be that robust // After creating the initial file strucutre at the location, // I would recommend commenting the below check/function call var dir = DocumentFile.FromTreeUri(this, _parentUri); if (dir.IsDirectory && dir.Length() == 0) { CreateTestFileStructureAtLocation(); } // persist permissions for this directory ContentResolver.TakePersistableUriPermission( _userSelectedDirectory, ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission ); data.AddFlags(ActivityFlags.GrantWriteUriPermission); data.AddFlags(ActivityFlags.GrantReadUriPermission); data.AddFlags(ActivityFlags.GrantPrefixUriPermission); data.AddFlags(ActivityFlags.GrantPersistableUriPermission); } } catch (Exception ex) { var timeElapsedTV = FindViewById <TextView>(Resource.Id.timeElapsedTV); SetTextViewOnError(timeElapsedTV, ex); } }
private bool CreateTestFileStructureAtLocation() { try { Android.Net.Uri dirUri = DocumentsContract.BuildDocumentUriUsingTree( _userSelectedDirectory, DocumentsContract.GetTreeDocumentId(_userSelectedDirectory) ); for (int i = 0; i < 10; ++i) { // create directory var newDir = DocumentsContract.CreateDocument( this.ContentResolver, dirUri, DocumentsContract.Document.MimeTypeDir, $"Directory {i + 1}" ); if (newDir == null) { throw new Exception("Unable to create directory at location!"); } for (int j = 0; j < 100; ++j) { var newFile = DocumentsContract.CreateDocument( this.ContentResolver, newDir, "text/plain", $"file{j + 1}.txt"); if (newFile == null) { throw new Exception("Unable to create file at location!"); } } } } catch (Exception ex) { // set our text view to display the error var timeElapsedTV = FindViewById <TextView>(Resource.Id.timeElapsedTV); SetTextViewOnError(timeElapsedTV, ex); } return(true); }
void UpdateDirectoryEntries(Uri uri) { directoryEntries.Clear(); var contentResolver = Activity.ContentResolver; Uri docUri = DocumentsContract.BuildDocumentUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); Uri childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); try { using (ICursor docCursor = contentResolver.Query(docUri, DIRECTORY_SELECTION, null, null, null)) { while (docCursor != null && docCursor.MoveToNext()) { currentDirectoryTextView.Text = docCursor.GetString( docCursor.GetColumnIndex(DocumentsContract.Document.ColumnDisplayName)); } } } catch { } try { using (ICursor childCursor = contentResolver.Query(childrenUri, DIRECTORY_SELECTION, null, null, null)) { while (childCursor != null && childCursor.MoveToNext()) { var entry = new DirectoryEntry(); entry.FileName = childCursor.GetString(childCursor.GetColumnIndex(DocumentsContract.Document.ColumnDisplayName)); entry.MimeType = childCursor.GetString(childCursor.GetColumnIndex(DocumentsContract.Document.ColumnMimeType)); directoryEntries.Add(entry); } } if (directoryEntries.Count == 0) { nothingInDirectoryTextView.Visibility = ViewStates.Visible; } else { nothingInDirectoryTextView.Visibility = ViewStates.Gone; } adapter.DirectoryEntries = directoryEntries; adapter.NotifyDataSetChanged(); } catch { } }
void ShowUriInfos(global::Android.Net.Uri uri, ContentResolver resolver) { System.Diagnostics.Debug.WriteLine("URI-Scheme/SchemeSpecificPart: " + uri.Scheme + "; " + uri.SchemeSpecificPart); try { System.Diagnostics.Debug.WriteLine("GetDocumentId: " + DocumentsContract.GetDocumentId(uri)); } catch (Exception ex) { } try { System.Diagnostics.Debug.WriteLine("GetTreeDocumentId: " + DocumentsContract.GetTreeDocumentId(uri)); } catch (Exception ex) { } try { System.Diagnostics.Debug.WriteLine("GetRootId: " + DocumentsContract.GetRootId(uri)); } catch (Exception ex) { } global::Android.Database.ICursor cursor = resolver.Query(uri, null, null, null, null); if (cursor != null) { while (cursor.MoveToNext()) { for (int i = 0; i < cursor.ColumnCount; i++) { string val = ""; switch (cursor.GetType(i)) { case global::Android.Database.FieldType.String: val = cursor.GetString(i); break; case global::Android.Database.FieldType.Integer: val = cursor.GetLong(i).ToString(); break; // GetInt() ist hier falsch case global::Android.Database.FieldType.Float: val = cursor.GetFloat(i).ToString(); break; case global::Android.Database.FieldType.Blob: val = "(blob)"; break; case global::Android.Database.FieldType.Null: val = "(null)"; break; } System.Diagnostics.Debug.WriteLine(string.Format("Column={0}; ColumnName={1}; ColumnType={2}: {3}", i, cursor.GetColumnName(i), cursor.GetType(i).ToString(), val)); } } } }
/// <summary> /// Called when activity started with StartActivityForResult() returns. /// </summary> /// <param name="requestCode">request code used in StartActivityForResult()</param> /// <param name="resultCode">result code</param> /// <param name="data">intent data from file picking</param> protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (resultCode == Result.Canceled) { // Notify user file picking was cancelled. OnFolderPickCancelled(); this.Finish(); } else { try { if (data?.Data == null) { throw new Exception("Folder picking returned no valid data"); } System.Diagnostics.Debug.Write(data.Data); var uri = data.Data; var docUri = DocumentsContract.BuildDocumentUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); OnFolderPicked(docUri); } catch (Exception readEx) { System.Diagnostics.Debug.Write(readEx); // Notify user file picking failed. FolderPickCancelled?.Invoke(this, readEx); } finally { this.Finish(); } } }
public static string GetDocumentName(ContentResolver resolver, Uri uri) { string name = null; if (uri.Scheme == "content") { ICursor cursor = null; try { var documentUri = DocumentsContract.BuildDocumentUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); if (documentUri == null) { throw new IOException("Cannot get document URI"); } cursor = resolver.Query(documentUri, null, null, null, null); if (cursor != null && cursor.MoveToFirst()) { var index = cursor.GetColumnIndex(DocumentsContract.Document.ColumnDisplayName); name = cursor.GetString(index); } } finally { cursor?.Close(); } } else { name = uri.LastPathSegment?.Split(':', 2).Last(); } return(name); }
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == PickImageId) { if ((resultCode == Result.Ok) && (data != null)) { // Set the filename as the completion of the Task PickImageTaskCompletionSource.SetResult(data.DataString); } else { PickImageTaskCompletionSource.SetResult(null); } } if (requestCode == SAF) { // content:/com.android.externalstorage.documents/tree/primary%3AMp var pref = this.GetSharedPreferences("pref", FileCreationMode.Private); Uri docUriTree = DocumentsContract.BuildDocumentUriUsingTree(data.Data, DocumentsContract.GetTreeDocumentId(data.Data)); var query = this.ContentResolver.Query(docUriTree, null, null, null, null); query.MoveToFirst(); var filePath = query.GetString(0); query.Close(); pref.Edit().PutString("Directory", filePath).Commit(); ContinueInit(); } }
/// <summary> /// Creates a directory under the directory represented as the uri in the argument. /// </summary> /// <param name="uri">The uri of the directory under which a new directory is created.</param> /// <param name="directoryName">The directory name of a new directory.</param> void CreateDirectory(Android.Net.Uri uri, string directoryName) { var contentResolver = Activity.ContentResolver; var docUri = DocumentsContract.BuildDocumentUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); var directoryUri = DocumentsContract .CreateDocument(contentResolver, docUri, DocumentsContract.Document.MimeTypeDir, directoryName); if (directoryUri != null) { Log.Info(TAG, string.Format( "Created directory : {0}, Document Uri : {1}, Created directory Uri : {2}", directoryName, docUri, directoryUri)); Toast.MakeText(Activity, string.Format("Created a directory [{0}]", directoryName), ToastLength.Short).Show(); } else { Log.Warn(TAG, string.Format("Failed to create a directory : {0}, Uri {1}", directoryName, docUri)); Toast.MakeText(Activity, string.Format("Failed to created a directory [{0}] : ", directoryName), ToastLength.Short).Show(); } }
/// <summary> /// Use DocumentsContract API to read the file structure at the given location iteratively /// includes children /// /// from https://stackoverflow.com/questions/41096332/issues-traversing-through-directory-hierarchy-with-android-storage-access-framew\ /// </summary> private void DocumentsContractGetFilesFromSelectedFolder() { // build the children structure of the root directory var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree( _userSelectedDirectory, DocumentsContract.GetTreeDocumentId(_userSelectedDirectory) ); // this stack is used in processing subsequent subdirectories // when we encounter one in traversing, push it on the stack to be processed // we continue until this stack is empty // // NOTE: stacks are LIFO, therefore this will produce a depth-first approach Stack <Android.Net.Uri> dirNodes = new Stack <Android.Net.Uri>(); dirNodes.Push(childrenUri); // used to keep track of how many directories we've traversed so far // this only works because we know the structure of the directory!!! int i = 0; while (dirNodes.Count != 0) { // get the next subdirectory dirNodes.TryPop(out childrenUri); // using this sub directory URI, query it for document information // the current seach finds all documents in the tree and returns the below columns: ID, Name, and Mime-type // searches can be customized using remaining three arguments (currently null which is why we return everything) var cursor = this.ContentResolver.Query( childrenUri, new string[] { DocumentsContract.Document.ColumnDocumentId, DocumentsContract.Document.ColumnDisplayName, DocumentsContract.Document.ColumnMimeType }, null, null, null ); // for each of the documents returned from our search, while (cursor.MoveToNext()) { var docId = cursor.GetString(0); var name = cursor.GetString(1); var mime = cursor.GetString(2); // only add the text files we've added // this is just for demonstration purposes if (mime == "text/plain") { // TODO: figure out a way to get directory (aka parent) name here // Add the file name to the list of files found so far _filenames.Add($"Director {i}/{name}"); } // if this is a directory, push its URI to the directory nodes stack for later processing else if (mime == DocumentsContract.Document.MimeTypeDir) { dirNodes.Push( DocumentsContract.BuildChildDocumentsUriUsingTree( _parentUri, docId)); } } ++i; // cleanup cursor cursor.Dispose(); } return; }
protected override async void OnActivityResult(int requestCode, Result resultCode, Intent intent) { base.OnActivityResult(requestCode, resultCode, intent); Log.Info("TranslateFGO", $"ActivityResult Code: {resultCode}, Result: {resultCode}, Data: {intent?.DataString}"); if (resultCode == Result.Ok && requestCode == (int)RequestCodes.FolderIntentRequestCode) { var service = new ContentManager(); var uri = intent.Data; var selectedFolder = DocumentsContract.GetTreeDocumentId(uri); if (selectedFolder == null || !selectedFolder.EndsWith("Android")) { var folderSplit = selectedFolder?.Split(":").Last(); var infoText = UIFunctions.GetResourceString("AndroidFolderNotSelected"); var errorMessage = String.Format(infoText, !string.IsNullOrEmpty(folderSplit) ? folderSplit : "none"); Toast.MakeText(this.Context, errorMessage, ToastLength.Long)?.Show(); return; } service.ClearCache(); var dataChildren = service.GetFolderChildren(uri, "data/"); // Get list of children to find FGO folders if (dataChildren.Count == 0) { var infoText = UIFunctions.GetResourceString("AndroidDataFolderEmpty"); Toast.MakeText(this.Context, infoText, ToastLength.Long)?.Show(); return; } var appNamesList = ContentManager.ValidAppNames.ToList(); bool found = false; foreach (var folder in dataChildren) { if (appNamesList.Contains(folder.Path.Split("/").Last())) { found = true; } } if (!found) { var infoText = UIFunctions.GetResourceString("NoFGOInstallationFoundToast"); Toast.MakeText(this.Context, infoText, ToastLength.Long)?.Show(); return; } // Save URL try { this.ContentResolver.TakePersistableUriPermission(uri, intent.Flags & (ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission)); } catch (Exception ex) { Log.Error("BetterFGO", $"Error thrown while persisting uri: {ex}"); var errorText = UIFunctions.GetResourceString("UnknownError"); var errorMessage = String.Format(errorText, ex.ToString()); Toast.MakeText(this.Context, errorMessage, ToastLength.Long)?.Show(); } // If we got this far, all is well var successText = UIFunctions.GetResourceString("Android11SetupSuccessful"); Toast.MakeText(this.Context, successText, ToastLength.Long)?.Show(); Log.Info("BetterFGO", $"Saving URI: {uri?.ToString()}"); Preferences.Set("StorageType", (int)ContentType.StorageFramework); Preferences.Set("StorageLocation", uri?.ToString()); MessagingCenter.Send(Xamarin.Forms.Application.Current, "return_to_main_page"); } }
public static string ToPhysicalPath(this Uri uri, Context ctx) { var isKitkat = Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat; var isDocumentUri = DocumentsContract.IsDocumentUri(ctx, uri); var isTreeUri = DocumentsContract.IsTreeUri(uri); if (isKitkat && (isDocumentUri || isTreeUri)) { var rootUri = isDocumentUri ? DocumentsContract.GetDocumentId(uri) : DocumentsContract.GetTreeDocumentId(uri); if (uri.Authority == "com.android.localstorage.documents") { return(rootUri); } if (uri.Authority == "com.android.externalstorage.documents") { var splitDocumentId = rootUri.Split(':'); var type = splitDocumentId[0]; if (string.Compare(type, "primary", StringComparison.InvariantCultureIgnoreCase) == 0) { return(Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, splitDocumentId[1])); } // Handle non-primary //! TODO: This is absolutely disgusting but android offers no easy way to obtain a path to a directory from an Uri to a directory. //! I'm not even sure this is portable. var contentUri = MediaStore.Files.GetContentUri(type); var cursor = ctx.ContentResolver.Query(contentUri, null, null, null, null); if (cursor != null && cursor.MoveToFirst()) { var path = cursor.GetString(0); cursor.Close(); return(path); } else { return("/storage/" + rootUri.Replace(':', '/')); } return(contentUri.ToPhysicalPath(ctx)); } if (uri.Authority == "com.android.providers.downloads.documents") { var contentUri = ContentUris.WithAppendedId(Uri.Parse("content://downloads/public_downloads"), long.Parse(rootUri)); return(ctx.GetDataColumn(contentUri, MediaStore.MediaColumns.Data, null, null)); } if (uri.Authority == "com.android.providers.media.documents") { var splitDocumentId = rootUri.Split(':'); var type = splitDocumentId[0]; Uri contentUri = null; if ("image" == type) { contentUri = MediaStore.Images.Media.ExternalContentUri; } else if ("video" == type) { contentUri = MediaStore.Video.Media.ExternalContentUri; } else if ("audio" == type) { contentUri = MediaStore.Audio.Media.ExternalContentUri; } return(ctx.GetDataColumn(contentUri, MediaStore.MediaColumns.Data, "_id?=", splitDocumentId[1])); } } // MediaStore and general else if (uri.Scheme == "content") { if (uri.Authority == "com.google.android.apps.photos.content") { return(uri.LastPathSegment); } return(ctx.GetDataColumn(uri, MediaStore.MediaColumns.Data, null, null)); } else if (uri.Scheme == "file") { return(uri.Path); } return(""); }
private List <Track> UpdateDirectoryEntries(Android.Net.Uri uri) { var contentResolver = Instance.ContentResolver; var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree(uri, DocumentsContract.GetTreeDocumentId(uri)); string[] projection = { MediaStore.Audio.AudioColumns.Data, MediaStore.Audio.AudioColumns.Title, MediaStore.Audio.AudioColumns.Album, MediaStore.Audio.ArtistColumns.Artist, DocumentsContract.Document.ColumnDisplayName, DocumentsContract.Document.ColumnMimeType, DocumentsContract.Document.ColumnDocumentId, }; var childCursor = contentResolver.Query(childrenUri, projection, MediaStore.Audio.AudioColumns.Data + " like ? ", new String[] { "%utm%" }, null); try { var findTracks = new List <Track>(); while (childCursor.MoveToNext()) { string path = childCursor.GetString(0); string title = childCursor.GetString(1); string album = childCursor.GetString(2); string artist = childCursor.GetString(3); string fileName = childCursor.GetString(4); string mime = childCursor.GetString(5); string docId = childCursor.GetString(6); var childUri = DocumentsContract.BuildChildDocumentsUriUsingTree(uri, docId); //var childUri = DocumentsContract.Bui(childrenUri, docId); if (mime.Contains("audio")) { var file = new Java.IO.File(childUri.Path); var split = file.Path.Split(":"); path = split[1]; var track = new Track { FileName = fileName, AlternativePathObject = childUri,//path + Java.IO.File.Separator + fileName, }; findTracks.Add(track); } } return(findTracks); } catch (Exception) { return(null); } }