【发布时间】:2017-08-02 01:52:12
【问题描述】:
我有一些用于在 Android 上选择文件的代码。我是从网上某处挑选的。实际上,代码在一种情况下工作,但在我的应用程序中,它不起作用。 Android 认为用户实际上没有取消文件选择。
代码如下:
private Task<FileData> PickAndOpenFile(bool isSave)
{
var id = GetRequestId();
var ntcs = new TaskCompletionSource<FileData>(id);
if (Interlocked.CompareExchange(ref _CompletionSource, ntcs, null) != null)
{
throw new InvalidOperationException("Only one operation can be active at a time");
}
try
{
var pickerIntent = new Intent(_Context, typeof(FilePickerActivity));
pickerIntent.SetFlags(ActivityFlags.NewTask);
_Context.StartActivity(pickerIntent);
EventHandler<FilePickerEventArgs> handler = null;
EventHandler<EventArgs> cancelledHandler = null;
handler = (s, e) =>
{
var tcs = Interlocked.Exchange(ref _CompletionSource, null);
FilePickerActivity.FilePicked -= handler;
Stream fileStream = isSave ? File.OpenRead(e.FilePath) : File.OpenWrite(e.FilePath);
tcs?.SetResult(new FileData { FileName = e.FileName, FileStream = fileStream });
};
cancelledHandler = (s, e) =>
{
var tcs = Interlocked.Exchange(ref _CompletionSource, null);
FilePickerActivity.FilePickCancelled -= cancelledHandler;
tcs?.SetResult(null);
};
FilePickerActivity.FilePickCancelled += cancelledHandler;
FilePickerActivity.FilePicked += handler;
}
catch (Exception exAct)
{
Debug.Write(exAct);
}
return _CompletionSource.Task;
}
要看到它正确运行,请克隆这个 repo 并运行 android 示例。选择文件示例位于第二个选项卡上。 https://github.com/MelbourneDeveloper/Adapt.Presentation.git
但是,在我的应用程序中,我使用的代码完全相同:
var filePicker = App.PlatformSpecificStartupArguments.PresentationFactory.CreateFilePicker();
using (var fileData = await filePicker.PickAndOpenFileForReading())
{
if (fileData == null)
{
return;
}
using (var readFileStream = fileData.FileStream)
{
var fileExtension = Path.GetExtension(fileData.FileName);
var relativeUri = Guid.NewGuid() + fileExtension;
await OnPictureTakenAsync(this, new PictureTakenEventArgs(readFileStream, relativeUri, fileData.FileName));
}
}
但是,当我选择文件(从现有图像中选择图像)时,代码会进入 cancelledHandler。这显然是权限问题,因为我在设备日志中收到此错误消息:
08-02 15:15:28.697 LGE Nexus 5X 错误 18911 DatabaseUtils java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/来自 pid=18684、uid=10221 的媒体需要 android.permission.READ_EXTERNAL_STORAGE 或 grantUriPermission() 在 android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:608) 在 android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:483) 在 android.content.ContentProvider$Transport.query(ContentProvider.java:212) 在 android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112) 在 android.os.Binder.execTransact(Binder.java:565)
因此,我在 Visual Studio 级别的 Android Manifest 中打开了此权限,但问题仍然存在。我针对失败的 Android 版本是 6.0。您可以看到,在上面提到的 repo 中,目标版本设置为“使用 SDK 版本进行编译”。而且我什至没有将 READ_EXTERNAL_STORAGE 添加到该示例应用程序中。
【问题讨论】:
标签: c# android xamarin xamarin.android filepicker