这是迄今为止我找到的最佳解决方案:
private async Task<StorageLibrary> TryAccessLibraryAsync(KnownLibraryId library)
{
try
{
return await StorageLibrary.GetLibraryAsync(library);
}
catch (UnauthorizedAccessException)
{
//inform user about missing permission and ask to grant it
MessageDialog requestPermissionDialog =
new MessageDialog($"The app needs to access the {library}. " +
"Press OK to open system settings and give this app permission. " +
"If the app closes, please reopen it afterwards. " +
"If you Cancel, the app will have limited functionality only.");
var okCommand = new UICommand("OK");
requestPermissionDialog.Commands.Add(okCommand);
var cancelCommand = new UICommand("Cancel");
requestPermissionDialog.Commands.Add(cancelCommand);
requestPermissionDialog.DefaultCommandIndex = 0;
requestPermissionDialog.CancelCommandIndex = 1;
var requestPermissionResult = await requestPermissionDialog.ShowAsync();
if (requestPermissionResult == cancelCommand)
{
//user chose to Cancel, app will not have permission
return null;
}
//open app settings to allow users to give us permission
await Launcher.LaunchUriAsync(new Uri("ms-settings:appsfeatures-app"));
//confirmation dialog to retry
var confirmationDialog = new MessageDialog(
$"Please give this app the {library} permission.");
confirmationDialog.Commands.Add(okCommand);
await confirmationDialog.ShowAsync();
//retry
return await TryAccessLibraryAsync(library);
}
}
它首先尝试通过KnownLibraryId 获取给定的库。如果用户删除了应用程序的权限,那么它将失败并显示UnauthorizedAccessException。
现在我们向用户显示一个 MessageDialog,它解释了问题并要求他授予应用权限。
如果用户按下取消,该方法将返回null,因为用户没有授予我们权限。
否则,我们会使用特殊的启动 URI ms-settings:appsfeatures-app(请参阅 docs)启动 设置,这会打开带有权限切换的应用高级设置页面。
现在这是一个不幸的问题 - 我发现更改权限将在当前时刻强制关闭应用程序。我在第一个对话框中告知用户这个事实。万一将来发生这种变化,代码已经为此替代方案准备好了 - 将显示一个新对话框,用户可以在权限更改时确认它,并且该方法将递归调用自身并再次尝试访问库。
当然,我建议在应用因权限更改而关闭之前保存用户的数据,这样在重新打开时,数据将保持不变,用户的流程不会中断。
如果您确实依赖此权限来实现其功能,也可以在应用启动后立即调用此权限。这样你就知道你要么有访问权限,要么用户会在开始时就给它,所以应用程序将被终止这一事实并没有什么坏处。
更新:我发现这个问题很有趣,所以我有written a blogpost about it。