This is probably super simple but I'm having trouble reading bytes from a file. I have it working fine with iOS but with Android it always crashes with a DirectoryNotFoundException
. So I think the uri is wrong but I'm not sure where I'm wrong with it...
My view has a button that opens up a file picker...
var selectedDocumentPath = await DependencyService.Get<IFilePicker>().pickDocument();
My FilePicker class...
class FilePicker : IFilePicker
{
public async Task<string> pickDocument()
{
string fileUri = string.Empty;
Console.WriteLine("Selecting Document from android device.");
Intent intent = new Intent(Intent.ActionOpenDocument);
intent.SetType("*/*");
intent.PutExtra(Intent.ExtraMimeTypes, new string[] { "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" });
intent.AddCategory(Intent.CategoryOpenable);
((Activity)Forms.Context).StartActivityForResult(Intent.CreateChooser(intent, "Select Document"), MainActivity.DOCUMENT_CODE);
return await GetDocumentPath(new CancellationTokenSource());
}
private async Task<string> GetDocumentPath(CancellationTokenSource TokenSource)
{
var path = string.Empty;
var LoopCheck = true;
while (LoopCheck)
{
for (var i = 0; i < 100; i++)
{
if (MainActivity.fileUri != null || MainActivity.cancelled) { LoopCheck = false; TokenSource.Cancel(); }
try { await Task.Delay(1000, TokenSource.Token); }
catch (TaskCanceledException) { break; }
}
}
if (!MainActivity.cancelled)
{
path = MainActivity.fileUri.OriginalString;
}
MainActivity.fileUri = null;
MainActivity.cancelled = false;
return path;
}
}
The OnActivityResult
method located in MainActivity.cs
....
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok && requestCode == DOCUMENT_CODE) { fileUri = new Uri(data.Data.Path); }
else if(resultCode == Result.Canceled) { cancelled = true; }
}
Some paths that I'm getting...
data.DataString = content://com.android.externalstorage.documents/document/primary%3ADownload%2FSampleResume%20(1).docx
data.Data.SchemeSpecificPart = //com.android.externalstorage.documents/document/primary:Download/SampleResume (1).docx
data.Data.Path = /document/primary:Download/SampleResume (1).docx
and then some encoded options as well. But all of these give me an error later on when I try and read it using ...
File.ReadAllBytes(selectedDocumentPath);
EDIT: I've replaced fileUri = new Uri(data.Data.Path);
with
var uri = DocumentsContract.BuildDocumentUri(data.Data.Authority,
DocumentsContract.GetDocumentId(data.Data));
fileUri = new Uri(uri.Path);
But still come out with the same type of path like /document/primary:Download/SampleResume (1).docx