Beispiel #1
0
            /// <summary>
            /// liefert das DocumentFile für eine Datei oder ein Verzeichnis (API level 14)
            /// <para>Wenn das Objekt noch nicht ex., wird es erzeugt. Auch ein notwendiger Pfad wird vollständig erzeugt.</para>
            /// </summary>
            /// <param name="storagename">z.B. "primary" oder "19F4-0903"</param>
            /// <param name="volpath">abs. Pfad im Volume</param>
            /// <param name="isDirectory">Pfad bezieht sich auf eine Datei oder ein Verzeichnis</param>
            /// <returns></returns>
            public DocumentFile GetDocumentFile(string storagename, string volpath, bool isDirectory)
            {
                global::Android.Net.Uri rooturi  = GetTreeDocumentUri(storagename);
                DocumentFile            document = DocumentFile.FromTreeUri(Activity.ApplicationContext, rooturi);

                string[] pathelems = volpath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; document != null && i < pathelems.Length; i++)
                {
                    DocumentFile nextDocument = document.FindFile(pathelems[i]);
                    if (nextDocument == null)
                    {
                        if ((i < pathelems.Length - 1) || isDirectory)
                        {
                            nextDocument = document.CreateDirectory(pathelems[i]);
                        }
                        else
                        {
                            nextDocument = document.CreateFile("", pathelems[i]);
                        }
                    }
                    document = nextDocument;
                }

                System.Diagnostics.Debug.WriteLine("AndroidGetDocumentFile(" + storagename + ", " + volpath + ", " + isDirectory.ToString() + ") = " + (document != null && (isDirectory == document.IsDirectory)).ToString());

                return(document != null ?
                       (isDirectory == document.IsDirectory ? document : null) :
                       null);
            }
        private async Task <RestoreResult> RestoreFromDir(Uri destUri)
        {
            if (!HasPersistablePermissionsAtUri(destUri))
            {
                throw new InvalidOperationException("No permission at URI");
            }

            var directory = DocumentFile.FromTreeUri(_context, destUri);
            var files     = directory.ListFiles();

            var mostRecentBackup = files
                                   .Where(f => f.IsFile && f.Type == Backup.MimeType && f.Name.EndsWith(Backup.FileExtension) &&
                                          f.Length() > 0 && f.CanRead())
                                   .OrderByDescending(f => f.LastModified())
                                   .FirstOrDefault();

            if (mostRecentBackup == null || mostRecentBackup.LastModified() <= _preferences.MostRecentBackupModifiedAt)
            {
                return(new RestoreResult());
            }

            _preferences.MostRecentBackupModifiedAt = mostRecentBackup.LastModified();
            var password = await GetBackupPassword();

            if (password == null)
            {
                throw new InvalidOperationException("No password defined.");
            }

            var data = await FileUtil.ReadFile(_context, mostRecentBackup.Uri);

            var backup = Backup.FromBytes(data, password);

            return(await _restoreService.RestoreAndUpdateAsync(backup));
        }
        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);
            }
        }
Beispiel #4
0
        private async Task <RestoreResult> RestoreFromDir(Uri destUri)
        {
            if (!HasPersistablePermissionsAtUri(destUri))
            {
                throw new Exception("No permission at URI");
            }

            var directory = DocumentFile.FromTreeUri(_context, destUri);
            var files     = directory.ListFiles();

            var mostRecentBackup = files
                                   .Where(f => f.IsFile && f.Type == Backup.MimeType && f.Name.EndsWith(Backup.FileExtension) && f.Length() > 0 && f.CanRead())
                                   .OrderByDescending(f => f.LastModified())
                                   .FirstOrDefault();

            if (mostRecentBackup == null || mostRecentBackup.LastModified() <= _preferences.MostRecentBackupModifiedAt)
            {
                return(new RestoreResult());
            }

            _preferences.MostRecentBackupModifiedAt = mostRecentBackup.LastModified();
            var password = await SecureStorageWrapper.GetAutoBackupPassword();

            if (password == null)
            {
                throw new Exception("No password defined.");
            }

            var data = await FileUtil.ReadFile(_context, mostRecentBackup.Uri);

            var backup = Backup.FromBytes(data, password);

            var(authsAdded, authsUpdated) = await _authSource.AddOrUpdateMany(backup.Authenticators);

            var categoriesAdded = backup.Categories != null
                ? await _categorySource.AddMany(backup.Categories)
                : 0;

            if (backup.AuthenticatorCategories != null)
            {
                await _authSource.AddOrUpdateManyCategoryBindings(backup.AuthenticatorCategories);
            }

            var customIconsAdded = backup.CustomIcons != null
                ? await _customIconSource.AddMany(backup.CustomIcons)
                : 0;

            try
            {
                await _customIconSource.CullUnused();
            }
            catch (Exception e)
            {
                // ignored
                Logger.Error(e);
            }

            return(new RestoreResult(authsAdded, authsUpdated, categoriesAdded, customIconsAdded));
        }
Beispiel #5
0
 internal SafFolder(Android.Net.Uri uri) : base(uri.Path ?? string.Empty)
 {
     _folderUri         = uri ?? throw new ArgumentNullException(nameof(uri));
     _directoryDocument = DocumentFile.FromTreeUri(Application.Context, uri);
     if (string.IsNullOrEmpty(Path))
     {
         Path = _directoryDocument.Name;
     }
 }
Beispiel #6
0
 private DocumentFile GetDocumentFile(string path)
 {
     if (path.Contains("://"))
     {
         return(DocumentFile.FromTreeUri(context, Android.Net.Uri.Parse(path)));
     }
     else
     {
         return(DocumentFile.FromFile(new Java.IO.File(path)));
     }
 }
        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);
            }
        }
Beispiel #8
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);
            }
        }
Beispiel #9
0
            /// <summary>
            /// liefert das DocumentFile für eine Datei oder ein Verzeichnis, wenn es existiert (sonst null) (API level 14)
            /// </summary>
            /// <param name="storagename">z.B. "primary" oder "19F4-0903"</param>
            /// <param name="volpath">abs. Pfad im Volume</param>
            /// <returns></returns>
            public DocumentFile GetExistingDocumentFile(string storagename, string volpath)
            {
                global::Android.Net.Uri rooturi  = GetTreeDocumentUri(storagename);
                DocumentFile            document = DocumentFile.FromTreeUri(Activity.ApplicationContext, rooturi);

                string[] pathelems = volpath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                for (int i = 0; document != null && i < pathelems.Length; i++)
                {
                    DocumentFile nextDocument = document.FindFile(pathelems[i]);
                    document = nextDocument;
                }

                System.Diagnostics.Debug.WriteLine("AndroidGetExistingDocumentFile(" + storagename + ", " + volpath + ") = " + (document != null).ToString());

                return(document);
            }
        /// <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 folder picking</param>
        protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);

            if (resultCode == Result.Canceled)
            {
                // Notify user folder 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;
                    //Android.Net.Uri testURI = Android.Net.Uri.Parse(uri);
                    var documentFile = DocumentFile.FromTreeUri(this, data.Data);

                    OnFolderPicked(new FolderPickerEventArgs(documentFile.Name, documentFile.Uri.ToString()));
                }
                catch (Exception readEx)
                {
                    System.Diagnostics.Debug.Write(readEx);

                    // Notify user folder picking failed.
                    FolderPickCancelled?.Invoke(
                        this,
                        new FolderPickerCancelledEventArgs
                    {
                        Exception = readEx
                    });
                }
                finally
                {
                    this.Finish();
                }
            }
        }
        protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        {
            AndroidApplication.Logger.Debug(() => $"MainActivity:OnActivityResult {requestCode}, {resultCode}");
            base.OnActivityResult(requestCode, resultCode, data);
            if (!resultCode.Equals(Result.Ok))
            {
                return;
            }

            AndroidApplication.Logger.Debug(() => $"MainActivity:OnActivityResult {data.Data.ToString()}");
            switch (requestCode)
            {
            // we asked for manage storage access in SDK30+
            case PermissionRequester.REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION:
                SelectFile();
                break;

            case REQUEST_SELECT_FILE:
                ToastMessage("OK");
                AndroidApplication.ControlFile = OpenControlFile(data.Data);
                if (AndroidApplication.ControlFile != null)
                {
                    PreferencesProvider.SetPreferenceString(ApplicationContext.GetString(Resource.String.prefs_control_uri_key), data.Data.ToString());
                    ApplicationContext.ContentResolver.TakePersistableUriPermission(data.Data, ActivityFlags.GrantReadUriPermission);
                }
                break;

            case REQUEST_SELECT_FOLDER:
                ToastMessage("OK");
                SetTextViewText(Resource.Id.txtRoot, $"{data.Data.ToString()}");

                //Android.Net.Uri uri = data.Data;
                //Android.Net.Uri docUri = DocumentsContract.BuildDocumentUriUsingTree(uri,DocumentsContract.GetTreeDocumentId(uri));
                // TODO - write GetRealPathFromUri()
                // see https://stackoverflow.com/questions/29713587/how-to-get-the-real-path-with-action-open-document-tree-intent
                //String path = GetRealPathFromURI(uri);

                DocumentFile file = DocumentFile.FromTreeUri(ApplicationContext, data.Data);
                AndroidApplication.Logger.Debug(() => $"MainActivity:OnActivityResult {file.Uri.Path}");
                SetTextViewText(Resource.Id.txtRoot, $"{file.Uri.Path}");
                break;
            }
        }
        private async Task <BackupResult> BackupToDir(Uri destUri)
        {
            var auths = (await _authenticatorRepository.GetAllAsync()).ToImmutableArray();

            if (!auths.Any())
            {
                return(new BackupResult());
            }

            if (!HasPersistablePermissionsAtUri(destUri))
            {
                throw new InvalidOperationException("No permission at URI");
            }

            var password = await GetBackupPassword();

            if (password == null)
            {
                throw new InvalidOperationException("No password defined");
            }

            var backup = new Backup(
                auths,
                await _categoryRepository.GetAllAsync(),
                await _authenticatorCategoryRepository.GetAllAsync(),
                await _customIconRepository.GetAllAsync()
                );

            var dataToWrite = backup.ToBytes(password);

            var directory = DocumentFile.FromTreeUri(_context, destUri);
            var file      = directory.CreateFile(Backup.MimeType,
                                                 FormattableString.Invariant($"backup-{DateTime.Now:yyyy-MM-dd_HHmmss}.{Backup.FileExtension}"));

            if (file == null)
            {
                throw new Exception("File creation failed, got null.");
            }

            await FileUtil.WriteFile(_context, file.Uri, dataToWrite);

            return(new BackupResult(file.Name));
        }
Beispiel #13
0
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            if (requestCode == 10001 && _currentRequest != null)
            {
                if (resultCode == Result.Ok)
                {
                    ContentResolver.TakePersistableUriPermission(data.Data, ActivityFlags.GrantWriteUriPermission);

                    var documentFile = DocumentFile.FromTreeUri(this, data.Data);
                    _currentRequest.AcceptRequest(documentFile);
                }
                else
                {
                    _currentRequest.RejectRequest();
                }

                _currentRequest = null;
            }
        }
Beispiel #14
0
        private async Task <BackupResult> BackupToDir(Uri destUri)
        {
            if (!_authSource.GetAll().Any())
            {
                return(new BackupResult());
            }

            if (!HasPersistablePermissionsAtUri(destUri))
            {
                throw new Exception("No permission at URI");
            }

            var password = await SecureStorageWrapper.GetAutoBackupPassword();

            if (password == null)
            {
                throw new Exception("No password defined.");
            }

            var backup = new Backup(
                _authSource.GetAll(),
                _categorySource.GetAll(),
                _authSource.CategoryBindings,
                _customIconSource.GetAll()
                );

            var dataToWrite = backup.ToBytes(password);

            var directory = DocumentFile.FromTreeUri(_context, destUri);
            var file      = directory.CreateFile(Backup.MimeType, $"backup-{DateTime.Now:yyyy-MM-dd_HHmmss}.{Backup.FileExtension}");

            if (file == null)
            {
                throw new Exception("File creation failed, got null.");
            }

            await FileUtil.WriteFile(_context, file.Uri, dataToWrite);

            return(new BackupResult(file.Name));
        }
        /// <inheritdoc/>
        public async Task <bool> TrySaveFileToPickedFolder(string fileName, byte[] content)
        {
            if (_pickedUri == null)
            {
                return(false);
            }

            try
            {
                DocumentFile folder   = DocumentFile.FromTreeUri(_context, _pickedUri);
                string       mimeType = URLConnection.GuessContentTypeFromName(fileName);
                DocumentFile file     = folder.CreateFile(mimeType, fileName);
                using (Stream stream = _context.ContentResolver.OpenOutputStream(file.Uri, "w"))
                {
                    await stream.WriteAsync(content, 0, content.Length);

                    return(true);
                }
            }
            catch (Exception ex)
            {
                return(false);
            }
        }
Beispiel #16
0
 /// <summary>
 /// Calls ScanFilesInSelectedFolder to begin scanning the initial directory
 /// </summary>
 /// <param name="folder">location chosen by user</param>
 /// <returns>Hashset of all the files in given location</returns>
 internal void GetFilesFromSelectedFolder()
 {
     ScanFilesInSelectedFolder(
         DocumentFile.FromTreeUri(this, _userSelectedDirectory)
         );
 }
Beispiel #17
0
        public Task <bool> SavePhoto(byte[] image, string destination, bool external)
        {
            var taskCompletionSource = new TaskCompletionSource <bool>();

            Task.Run(async() =>
            {
                try
                {
                    var contentResolver = MainActivity.Instance.ContentResolver;

                    var currentTimeSeconds = JavaSystem.CurrentTimeMillis() / 1000;

                    if (external)
                    {
                        var externalPicturesDir = MainActivity.Instance.GetExternalFilesDirs(Environment.DirectoryPictures).ElementAt(1).AbsolutePath;
                        var newFilePath         = Path.Combine(externalPicturesDir, currentTimeSeconds + ".jpg");
                        using (var stream = new FileStream(newFilePath, FileMode.CreateNew))
                        {
                            using (var bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length))
                            {
                                await bitmap.CompressAsync(Bitmap.CompressFormat.Jpeg, 100, stream);
                            }
                        }

                        using (var file = new Java.IO.File(newFilePath))
                        {
                            MainActivity.Instance.SendBroadcast(new Intent(Intent.ActionMediaScannerScanFile, Uri.FromFile(file)));
                        }
                    }
                    else
                    {
                        Uri destinationFinalUri;
                        if (destination != null)
                        {
                            var pickedDir = DocumentFile.FromTreeUri(MainActivity.Instance, Uri.Parse(destination));
                            var newFile   = pickedDir.CreateFile("image/jpeg", currentTimeSeconds + ".jpg");
                            if (newFile == null)
                            {
                                throw new DirectoryNotFoundException();
                            }
                            destinationFinalUri = newFile.Uri;
                        }
                        else
                        {
                            var values = new ContentValues();
                            values.Put(MediaStore.Images.Media.InterfaceConsts.MimeType, "image/jpeg");
                            values.Put(MediaStore.Images.Media.InterfaceConsts.DateAdded, currentTimeSeconds);
                            values.Put(MediaStore.Images.Media.InterfaceConsts.DateModified, currentTimeSeconds);

                            destinationFinalUri = contentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, values);
                        }

                        using (var stream = contentResolver.OpenOutputStream(destinationFinalUri))
                        {
                            using (var bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length))
                            {
                                await bitmap.CompressAsync(Bitmap.CompressFormat.Jpeg, 100, stream);
                            }
                        }

                        MainActivity.Instance.SendBroadcast(new Intent(Intent.ActionMediaScannerScanFile, destinationFinalUri));
                    }

                    taskCompletionSource.SetResult(true);
                }
                catch (Exception e)
                {
                    taskCompletionSource.SetException(e);
                }
            });

            return(taskCompletionSource.Task);
        }
        protected override void OnActivityResult(int requestCode, Android.App.Result resultCode, Intent data)
        {
            switch ((ActivityRequest)requestCode)
            {
            case ActivityRequest.RequestDevelopmentSettings:
                UpdateDisplay();
                break;

            case ActivityRequest.RequestOpenDocumentTreeToApp:
                if (data != null && resultCode == Android.App.Result.Ok)
                {
                    Android.Net.Uri treeUri = data.Data;
                    if (treeUri != null)
                    {
                        _instanceData.CopyToAppSrcUri = treeUri.ToString();
                        if (!string.IsNullOrEmpty(_instanceData.CopyToAppSrcUri))
                        {
                            SelectCopyAppDir(false);
                        }
                    }
                }
                break;

            case ActivityRequest.RequestOpenDocumentTreeFromApp:
                if (data != null && resultCode == Android.App.Result.Ok)
                {
                    Android.Net.Uri treeUri = data.Data;
                    if (treeUri != null)
                    {
                        _instanceData.CopyFromAppDstUri = treeUri.ToString();
                        if (!string.IsNullOrEmpty(_instanceData.CopyFromAppSrcPath) && !string.IsNullOrEmpty(_instanceData.CopyFromAppDstUri))
                        {
                            try
                            {
                                DocumentFile srcDir = DocumentFile.FromFile(new Java.IO.File(_instanceData.CopyFromAppSrcPath));
                                DocumentFile dstDir = DocumentFile.FromTreeUri(this, Android.Net.Uri.Parse(_instanceData.CopyFromAppDstUri));
                                if (_activityCommon.RequestCopyDocumentsThread(srcDir, dstDir, (result, aborted) => { }))
                                {
                                    ActivityCommon.CopyFromAppSrc = _instanceData.CopyFromAppSrcPath;
                                    ActivityCommon.CopyFromAppDst = _instanceData.CopyFromAppDstUri;
                                }
                            }
                            catch (Exception)
                            {
                                // ignored
                            }
                        }
                    }
                }
                break;

            case ActivityRequest.RequestSelDirToApp:
                if (data != null && resultCode == Android.App.Result.Ok)
                {
                    _instanceData.CopyToAppDstPath = data.Extras?.GetString(FilePickerActivity.ExtraFileName);
                    if (!string.IsNullOrEmpty(_instanceData.CopyToAppSrcUri) && !string.IsNullOrEmpty(_instanceData.CopyToAppDstPath))
                    {
                        try
                        {
                            DocumentFile srcDir = DocumentFile.FromTreeUri(this, Android.Net.Uri.Parse(_instanceData.CopyToAppSrcUri));
                            DocumentFile dstDir = DocumentFile.FromFile(new Java.IO.File(_instanceData.CopyToAppDstPath));
                            if (_activityCommon.RequestCopyDocumentsThread(srcDir, dstDir, (result, aborted) => { }))
                            {
                                ActivityCommon.CopyToAppDst   = _instanceData.CopyToAppDstPath;
                                ActivityCommon.CopyFromAppDst = _instanceData.CopyFromAppDstUri;
                            }
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }
                }
                break;

            case ActivityRequest.RequestSelDirFromApp:
                if (data != null && resultCode == Android.App.Result.Ok)
                {
                    _instanceData.CopyFromAppSrcPath = data.Extras?.GetString(FilePickerActivity.ExtraFileName);
                    if (!string.IsNullOrEmpty(_instanceData.CopyFromAppSrcPath))
                    {
                        SelectCopyDocumentTree(true);
                    }
                }
                break;

            case ActivityRequest.RequestSelDirDelApp:
                if (data != null && resultCode == Android.App.Result.Ok)
                {
                    string delPath = data.Extras?.GetString(FilePickerActivity.ExtraFileName);
                    if (!string.IsNullOrEmpty(delPath))
                    {
                        try
                        {
                            DocumentFile delDir = DocumentFile.FromFile(new Java.IO.File(delPath));
                            _activityCommon.RequestDeleteDocumentsThread(delDir, (result, aborted) => { });
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }
                }
                break;
            }
        }
Beispiel #19
0
        public Task <bool> SaveFileInFolder(FileData fileToSave, FolderData folder, bool shouldOverWrite)
        {
            var uniqueId = Guid.NewGuid();
            var next     = new TaskCompletionSource <bool>(uniqueId);

            // Interlocked.CompareExchange(ref object location1, object value, object comparand)
            // Compare location1 with comparand.
            // If equal replace location1 by value.
            // Returns the original value of location1.
            // ---
            // In this context, tcs is compared to null, if equal tcs is replaced by next,
            // and original tcs is returned.
            // We then compare original tcs with null, if not null it means that a task was
            // already started.
            if (Interlocked.CompareExchange(ref tcs_bool_as_int, next, null) != null)
            {
                return(Task.FromResult <bool>(false));
            }

            EventHandler <PermissionRequestEventArgs> handler = null;

            weakContext.TryGetTarget(out Context newContext);

            var requestPermissionIntent = new Intent(newContext, typeof(RequestPermissionActivity));

            requestPermissionIntent.SetFlags(ActivityFlags.NewTask);
            requestPermissionIntent.PutExtra(RequestPermissionActivity.RequestedPermission, Manifest.Permission.WriteExternalStorage);



            handler = (sender, e) =>
            {
                // Interlocaked.Exchange(ref object location1, object value)
                // Sets an object to a specified value and returns a reference to the original object.
                // ---
                // In this context, sets tcs to null and returns it.
                var task = Interlocked.Exchange(ref tcs_bool_as_int, null);

                RequestPermissionActivity.OnPermissionGranted -= handler;

                if (e.success)
                {
                    try
                    {
                        var test = Android.Net.Uri.Parse(folder.FolderPath);// + "/test.pdf");



                        var documentFile = DocumentFile.FromTreeUri(newContext, test);

                        DocumentFile newFile = documentFile.FindFile(fileToSave.FileName);



                        if (newFile != null)
                        {
                            if (shouldOverWrite)
                            {
                                newFile.Delete();
                            }
                            else
                            {
                                //supposed to create uniuqe name in this case
                                var purefilename  = Path.GetFileNameWithoutExtension(fileToSave.FileName);
                                var fileextention = Path.GetExtension(fileToSave.FileName);
                                fileToSave.FileName = purefilename + "_" + Path.GetRandomFileName() + fileextention;
                            }
                        }

                        documentFile.CreateFile("*/*", fileToSave.FileName);
                        //var documentFile = DocumentFile.FromTreeUri(activity, test);


                        var outputstream = newContext.ContentResolver.OpenOutputStream(newFile.Uri);

                        fileToSave.GetStream().CopyTo(outputstream);

                        outputstream.Flush();
                        outputstream.Close();

                        task.SetResult(e.success);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        task.SetCanceled();
                    }
                }
            };
            RequestPermissionActivity.OnPermissionGranted += handler;

            //proably need a try statement here
            newContext.StartActivity(requestPermissionIntent);



            return(tcs_bool_as_int.Task);
        }