Closed riandesign closed 7 years ago
@riandesign , Hi it seems this is caused by line 71 in FilePickerImplementation.cs.
Changing it to OnFilePicked (new FilePickerEventArgs (dataBytes, filename, pathname));
should fix it, because line 141 in FilePickerImplementation.cs expects a FilePath to create the filestream. tcs?.SetResult (new FileData (e.FilePath, e.FileName, () => File.OpenRead (e.FilePath)));
@jfversluis any thoughts?
@elmernocon , but I don't have the variable pathname
. Thus, it doesn't exist in the context.
What shoul I do in this case?
@riandesign , this should do the trick.
string filename = doc.LocalizedName;
string pathname = doc.FileUrl?.ToString();
// iCloud drive can return null for LocalizedName.
if (filename == null)
{
// Retrieve actual filename by taking the last entry after / in FileURL.
// e.g. /path/to/file.ext -> file.ext
// filesplit is either:
// 0 (pathname is null, or last / is at position 0)
// -1 (no / in pathname)
// positive int (last occurence of / in string)
var filesplit = pathname?.LastIndexOf ('/') ?? 0;
filename = pathname?.Substring (filesplit + 1);
}
@elmernocon great work! If you could pour this into an PR I will check it out somewhere today or tomorrow and if it looks good, I can merge it in.
@elmernocon @jfversluis I still got the same error:
System.Exception: Error getting value from 'DataArray' on 'Plugin.FilePicker.Abstractions.FileData'.
@riandesign , hmm, did you recompile?
@elmernocon, yes. I rebuilt the DLLs.
@elmernocon @jfversluis I realized the problem is not with null FilePath. Maybe FilePath is wrong, not null. I tried the code below and I still got the same error:
...
private Task<FileData> TakeMediaAsync () {
...
Handler = (s, e) => {
...
if (e != null && e.FilePath != null)
// I also tested e.FilePath != String.empty
// So, FilePath is not empty or null
tcs.SetResult(new FileData(e.FilePath, e.FileName, () => File.OpenRead(e.FilePath)));
else
tcs.SetResult(null);
...
@elmernocon @jfversluis any idea?
@riandesign , Hi, can you try these changes?
In the class FileData
private byte[] _dataArray = null;
public byte[] DataArray
{
get { return _dataArray; }
}
public FileData (byte[] dataArray, string fileName, string filePath)
{
_dataArray = dataArray;
_fileName = fileName;
_filePath = filePath;
}
the reasoning for this is we're already getting and passing the dataArray (byte[]) but it's not being used. see:
FilePickerEventArgs line 29: public FilePickerEventArgs (byte [] fileByte, string fileName, string filePath) : this (fileByte, fileName) { ... }
FilePickerActivity (Android) line 58: OnFilePicked (new FilePickerEventArgs (file, fileName, filePath));
FilePickerImplementation (iOS) line 71: OnFilePicked (new FilePickerEventArgs (dataBytes, filename, pathname));
FilePickerImplementation (Android) line 59: tcs?.SetResult (new FileData (e.FilePath, e.FileName, () => System.IO.File.OpenRead (e.FilePath)));
FilePickerImplementation (iOS) line 141: tcs?.SetResult (new FileData (e.FilePath, e.FileName, () => File.OpenRead (e.FilePath)));
so now with the changes to FileData replace the following lines with:
tcs?.SetResult (new FileData (e.FileByte, e.FileName, e.FilePath));
tcs?.SetResult (new FileData (e.FileByte, e.FileName, e.FilePath));
I think this is caused by this: var securityEnabled = e.Url.StartAccessingSecurityScopedResource ();
with FileData not having access to the "caged" resource it's failing in getting the byte[] value. this is just a guess though.
@jfversluis any thoughts?
@elmernocon I can't do this: FilePickerImplementation (iOS) line 141: tcs?.SetResult (new FileData (e.DataArray, e.FileName, e.FilePath));
Because FilePickerEventArgs doesn't have e.DataArray. However, it has e.FileByte;
And it worked like a charm! Now, I'm able to pick files on iOS.
I appreciate a lot your help, @elmernocon ! Thank you very much. Any thing you need, please tell me.
@riandesign Hi, yeah missed that on my part, fixed the comment above :)
Quick question, were you able to make the document picker appear on an iPad Simulator / iPad?
@elmernocon I haven't test on Simulator. I've tested it on iPhone device.
@riandesign if possible can you test it on an iPad Simulator?
` private async void btnUpload_Clicked(object sender, EventArgs e)
{
FileData fileData = await CrossFilePicker.Current.PickFile();
Byte[] byteArray = fileData.DataArray; // when i select pdf or doc from GoogleDrive Its getting DataArray = empty;//
await CrossFilePicker.Current.SaveFile(fileData);
if (fileData.FileName == string.Empty)
{
string filepath1 = await DependencyService.Get
}
else
{
string fileName = fileData.FileName;
string filepath = await DependencyService.Get<ISaveFile>().SaveFiles(fileName, byteArray);
await DisplayAlert("Downloaded File path", filepath, "ok");
var fstream = new MemoryStream(byteArray);
imgSelected.Source = ImageSource.FromStream(() => fstream);
}
}`
when i select pdf or doc from GoogleDrive Its getting DataArray = empty;//
hi just add permissions in your
in manifest file and public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } in mainactivity.cs
@divya morampudi
I tested it on iOS and I got this error:
System.Exception: Error getting value from 'DataArray' on 'Plugin.FilePicker.Abstractions.FileData'.
My code: