public async Task <bool> RemoveFileIfExists(ContentType accessType, string filename, string storageLocationBase)
        {
            var fileIfExists = GetPathIfFileExists(accessType, filename, storageLocationBase);

            if (!fileIfExists.Exists)
            {
                return(false);
            }

            switch (accessType)
            {
            case ContentType.DirectAccess:
                File.Delete(fileIfExists.Path);
                await Task.Delay(50);

                return(true);

            case ContentType.StorageFramework:
                var          doc  = DocumentsContract.BuildDocumentUriUsingTree(Uri.Parse(storageLocationBase), fileIfExists.Path);
                DocumentFile file = DocumentFile.FromTreeUri(Android.App.Application.Context, doc);
                await Task.Delay(50);

                return(file.Delete());

            default:
                throw new ArgumentOutOfRangeException(nameof(accessType), accessType, null);
            }
        }
        private async Task <byte[]> ReadExistingFileAsync(ContentType accessType, string filePath, string storageLocationBase)
        {
            switch (accessType)
            {
            case ContentType.DirectAccess:
                return(await File.ReadAllBytesAsync(filePath));

            case ContentType.StorageFramework:
                var baseUri     = Uri.Parse(storageLocationBase);
                var contentPath = DocumentsContract.BuildDocumentUriUsingTree(baseUri, filePath);
                var descriptor  = AppContentResolver.OpenAssetFileDescriptor(contentPath !, "r");

                if (descriptor == null)
                {
                    throw new Exception($"File descriptor null, tried to open {contentPath}.");
                }

                var readStream = descriptor.CreateInputStream();
                if (!readStream.CanRead)
                {
                    throw new Exception("Cannot read the readStream.");
                }
                byte[] outputBuffer = new byte[readStream.Length];
                await readStream.ReadAsync(outputBuffer);

                return(outputBuffer);

            default:
                throw new ArgumentOutOfRangeException(nameof(accessType), accessType, null);
            }
        }
Exemple #3
0
        internal static string GetPathForDocTree(Context context, Uri uri)
        {
            var docUri = DocumentsContract.BuildDocumentUriUsingTree(uri,
                                                                     DocumentsContract.GetTreeDocumentId(uri));
            string path = GetPath(context, docUri);

            return(path);
        }
Exemple #4
0
        /// <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()));
        }
Exemple #5
0
            /// <summary>
            /// z.B.: //com.android.externalstorage.documents/tree/19F4-0903:/document/19F4-0903:abc/def/ghi.txt aus /abc/def/ghi.txt (API level 21 / Lollipop / 5.0)
            /// </summary>
            /// <param name="storagename">z.B. "primary" oder "19F4-0903"</param>
            /// <param name="volpath">abs. Pfad im Volume</param>
            /// <returns></returns>
            global::Android.Net.Uri GetDocumentUriUsingTree(string storagename, string volpath)
            {
                if (volpath.Length > 0 &&
                    volpath[0] == '/')
                {
                    volpath = volpath.Substring(1);
                }

                // Build URI representing the target Document#COLUMN_DOCUMENT_ID in a document provider. (API level 21 / Lollipop / 5.0)
                return(DocumentsContract.BuildDocumentUriUsingTree(GetTreeDocumentUri(storagename), storagename + ":" + volpath));
            }
        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);
            }
        }
Exemple #9
0
        /// <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);
            }
        }
Exemple #10
0
        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 {
            }
        }
        /// <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();
                }
            }
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        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();
            }
        }
Exemple #16
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());
        }