我从Xamarin开始,以便能够创建同时在iOS和Android上运行的应用程序。 我要做的第一件事是单击一个按钮->打开图库->选择图像->在图像标签上显示所选图像
MainPage.xaml的当前内容为:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloWorld" x:Class="HelloWorld.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin.Forms!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
<Label Text="0" x:Name="lbl_counter" HorizontalOptions="Center" VerticalOptions="StartAndExpand" FontSize="Large"/>
<Image x:Name="img_selected" Source="" />
<Button Text="Click Me" Clicked="Handle_Clicked" VerticalOptions="StartAndExpand"/>
</StackLayout>
</ContentPage>
我正在使用Plugin.Media,因此,当单击按钮时,我运行以下代码:
async void Handle_Clicked(object sender, System.EventArgs e){
lbl_counter.Text = (++counter).ToString();
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsPickPhotoSupported){
await DisplayAlert("no upload", "picking a photo is not supported", "ok");
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
img_selected.Source = ImageSource.FromStream(file.GetStream);
}
经过大量的努力,我设法使其在iOS上运行。 但是我无法在Android上使用它。它不断抱怨权限。 我已经从以下所有方面想到了我的想法:
有什么主意吗?
从评论中添加信息
评论1:
我在Xamarin中没有(可见的)堆栈跟踪。 如果我从错误窗口中复制,则会得到此信息:
Plugin.Media.Abstractions.MediaPermissionException: Storage permission(s) are required.
在“输出”窗口中,我可以看到:
Does not have storage permission granted, requesting.
Storage permission Denied.
代码
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Plugin.Media;
using Plugin.Permissions;
using Plugin.Permissions.Abstractions;
namespace HelloWorld
{
public partial class MainPage : ContentPage
{
private int counter;
public MainPage()
{
InitializeComponent();
}
async void Handle_Clicked(object sender, System.EventArgs e)
{
lbl_counter.Text = (++counter).ToString();
/******************************/
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage))
{
await DisplayAlert("Need Storage", "Gunna need that Storage", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage);
status = results[Permission.Storage];
}
if (status == PermissionStatus.Granted)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("no upload", "picking a photo is not supported", "ok");
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
img_selected.Source = ImageSource.FromStream(file.GetStream);
}
else if (status != PermissionStatus.Unknown)
{
await DisplayAlert("Storage Permission Denied", "Can not continue, try again.", "OK");
}
}
catch
{
//...
}
/******************************/
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloWorld" x:Class="HelloWorld.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin.Forms!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
<Label Text="0" x:Name="lbl_counter" HorizontalOptions="Center" VerticalOptions="StartAndExpand" FontSize="Large"/>
<Image x:Name="img_selected" Source="" />
<Button Text="Click Me" Clicked="Handle_Clicked" VerticalOptions="StartAndExpand"/>
</StackLayout>
</ContentPage>
MainActivity.cs
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
namespace HelloWorld.Droid
{
[Activity(Label = "HelloWorld", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.gedons.HelloWorld">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission android:name="android.permission.CAMERA" />
<application android:label="HelloWorld.Android">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
_file_path.xml _
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures" />
<external-files-path name="my_movies" path="Movies" />
</paths>
答案 0 :(得分:0)
在Android上从图库中选择图像时出现权限问题
从Android 6.0(API级别23)开始,用户在应用程序运行时(而不是在安装应用程序时)授予应用程序权限。您应该在运行时requesting permissions。
系统权限分为正常和危险两类:
READ_EXTERNAL_STORAGE
分为Dangerous permissions,因此您应该手动检查API级别23及更高版本的此权限。
对于Xamarin.Forms
项目,您可以在运行时使用PermissionsPlugin在Xamarin.Forms
中请求此权限。
PermissionsPlugin
的正式示例。此处使用简单,请将此代码添加到您的MainActivity
中:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
在需要时请求权限:
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
if (status != PermissionStatus.Granted)
{
if(await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage))
{
await DisplayAlert("Need Storage", "Gunna need that Storage", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage);
status = results[Permission.Storage];
}
if (status == PermissionStatus.Granted)
{
//Permission granted, do what you want do.
}
else if(status != PermissionStatus.Unknown)
{
await DisplayAlert("Storage Permission Denied", "Can not continue, try again.", "OK");
}
}
catch (Exception ex)
{
//...
}
答案 1 :(得分:0)
从Android M开始,您必须拥有其他应用程序,例如(画廊)存储许可,即图库需要将选择的图像保存到提供的URI路径中。
请按照以下步骤操作: https://thinkandroid.wordpress.com/2012/08/07/granting-content-provider-uri-permissions/