/// <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() !]);
Beispiel #2
0
        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);
            }
        }
        // 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);
            }
        }
        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 {
            }
        }
Beispiel #6
0
        private StorageEntryBase[] GetEntriesImpl(string searchPattern = null)
        {
            var itemProperties = new List <StorageEntryBase>();

            var childrenUri = DocumentsContract.BuildChildDocumentsUriUsingTree(AndroidUri, DocumentsContract.GetDocumentId(AndroidUri));
            var projection  = new string[] {
                DocumentsContract.Document.ColumnDocumentId,
                DocumentsContract.Document.ColumnDisplayName,
                DocumentsContract.Document.ColumnMimeType,
                DocumentsContract.Document.ColumnSize,
                DocumentsContract.Document.ColumnLastModified
            };

            //build searchPattern
            string selection = null;

            string[] selectionArgs = null;
            var      regXpattern   = searchPattern != null?Storage.WildcardToRegex(searchPattern) : null;

            //it looks doesn't supported for storage
            //if (!string.IsNullOrEmpty(searchPattern))
            //{
            //    selection = $"{DocumentsContract.Document.ColumnDocumentId}=?";
            //    selectionArgs = new string[] { searchPattern.Replace("*", "%") };
            //}


            //run the query
            using (var cursor = Context.ContentResolver.Query(childrenUri, projection, selection, selectionArgs, null))
            {
                while (cursor.MoveToNext())
                {
                    var documentId = cursor.GetString(0);
                    var name       = cursor.GetString(1);

                    if (regXpattern != null && !Regex.IsMatch(name, regXpattern))
                    {
                        continue;
                    }

                    StreamAttributes attribute = 0;
                    if (!string.IsNullOrEmpty(name) && name[0] == '.')
                    {
                        attribute |= StreamAttributes.Hidden;
                    }

                    itemProperties.Add(
                        new StorageEntryBase()
                    {
                        Name          = name,
                        Uri           = AndroidUriToUri(DocumentsContract.BuildDocumentUriUsingTree(AndroidUri, documentId)),
                        IsStorage     = cursor.GetString(2) == DocumentsContract.Document.MimeTypeDir,
                        Size          = long.Parse(cursor.GetString(3)),
                        LastWriteTime = cursor.GetString(4) != null ? JavaTimeStampToDateTime(double.Parse(cursor.GetString(4))) : DateTime.Now,
                        Attributes    = attribute,
                    });

                    if (!string.IsNullOrEmpty(searchPattern))
                    {
                        break;
                    }
                }
                cursor.Close();
            }

            return(itemProperties.ToArray());
        }
Beispiel #7
0
        /// <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;
        }