/// <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. OnFilePickCancelled(); this.Finish(); } else { System.Diagnostics.Debug.Write(data.Data); try { var uri = data.Data; var filePath = IOUtil.GetPath(this.context, uri); if (string.IsNullOrEmpty(filePath)) { filePath = IOUtil.IsMediaStore(uri.Scheme) ? uri.ToString() : uri.Path; } var fileName = this.GetFileName(this.context, uri); OnFilePicked(new FilePickerEventArgs(fileName, filePath)); } catch (Exception readEx) { System.Diagnostics.Debug.Write(readEx); // Notify user file picking failed. FilePickCancelled?.Invoke( this, new FilePickerCancelledEventArgs { Exception = readEx }); } finally { this.Finish(); } } }
/// <summary> /// File picking implementation /// </summary> /// <param name="allowedTypes">list of allowed types; may be null</param> /// <param name="action">Android intent action to use; unused</param> /// <returns>picked file data, or null when picking was cancelled</returns> private Task <FileData> PickFileAsync(string[] allowedTypes, string action) { var id = this.GetRequestId(); var ntcs = new TaskCompletionSource <FileData>(id); if (Interlocked.CompareExchange(ref this.completionSource, ntcs, null) != null) { throw new InvalidOperationException("Only one operation can be active at a time"); } try { var pickerIntent = new Intent(this.context, typeof(FilePickerActivity)); pickerIntent.SetFlags(ActivityFlags.NewTask); pickerIntent.PutExtra(FilePickerActivity.ExtraAllowedTypes, allowedTypes); this.context.StartActivity(pickerIntent); EventHandler <FilePickerEventArgs> handler = null; EventHandler <FilePickerCancelledEventArgs> cancelledHandler = null; handler = (s, e) => { var tcs = Interlocked.Exchange(ref this.completionSource, null); FilePickerActivity.FilePickCancelled -= cancelledHandler; FilePickerActivity.FilePicked -= handler; tcs?.SetResult(new FileData( e.FilePath, e.FileName, () => { if (IOUtil.IsMediaStore(e.FilePath)) { var contentUri = Android.Net.Uri.Parse(e.FilePath); return(Application.Context.ContentResolver.OpenInputStream(contentUri)); } else { return(System.IO.File.OpenRead(e.FilePath)); } })); }; cancelledHandler = (s, e) => { var tcs = Interlocked.Exchange(ref this.completionSource, null); FilePickerActivity.FilePickCancelled -= cancelledHandler; FilePickerActivity.FilePicked -= handler; if (e?.Exception != null) { tcs?.SetException(e.Exception); } else { tcs?.SetResult(null); } }; FilePickerActivity.FilePickCancelled += cancelledHandler; FilePickerActivity.FilePicked += handler; } catch (Exception ex) { // Debug.Write(ex); this.completionSource.SetException(ex); } return(this.completionSource.Task); }