【问题标题】:android media picker from Xamarin forms来自 Xamarin 表单的 android 媒体选择器
【发布时间】:2017-11-27 03:44:33
【问题描述】:

我正在为 iOS 和 Android 编写一个带有 xamarin 表单的应用程序。

我想从图片库中挑选一张照片。

我已经创建了一个 android 特定的静态助手:

var i = new Intent();
i.SetType("*/*");
Forms.Context.StartActivity(Intent.CreateChooser(i, ""));

但我没有办法获得选定的图片字节。 我在 android 教程上看到我应该实现 onActivityResult,但我不在活动上,这是一个特定的静态调用...

谢谢

【问题讨论】:

  • 为什么不使用媒体插件? github.com/jamesmontemagno/MediaPlugin
  • 不实现OnActivityResult就无法获取图片。正如 Jason 建议的那样,您应该使用 James Montemagno 的插件 :)
  • 我想了解它是如何工作的

标签: xamarin xamarin.forms


【解决方案1】:

通过表单的依赖服务:

  • 创建您的依赖接口 (IMediaPicker)
  • 创建一个 Activity 子类 (MediaChooserActivityProxy),作为您的 Intent.ActionPick 代理
  • IMediaPickerXamarin.Android 实现中,使用AutoResetEvent 将Android StartActivityForResult / OnActivityResult 回调转换为可等待的同步流。

依赖服务交互:

public interface IMediaPicker
{
    Task<string> ChooseAFileAsync();
}

Android 依赖实现:

public class MediaPicker : IMediaPicker
{
    public static string filePickedPath;
    public static AutoResetEvent waitHandle;

    public async Task<string> ChooseAFileAsync()
    {
        waitHandle = new AutoResetEvent(false);
        filePickedPath = "";
        Forms.Context.StartActivity(typeof(MediaChooserActivityProxy));
        await Task.Run(() => waitHandle.WaitOne());
        return filePickedPath;
    }
}

要捕获OnActivityResult 的代理/伪活动:

public class MediaChooserActivityProxy : Activity
{
    const string mimeType = "image/*";
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        var intent = new Intent(Intent.ActionPick);
        intent.SetType(mimeType);
        if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
        {
            intent.PutExtra(Intent.ExtraMimeTypes, mimeType);
        }
        StartActivityForResult(Intent.CreateChooser(intent, "StackOverflow"), 73);
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        if (requestCode == 73)
            if (resultCode == Result.Ok)
            {
                string[] filePathColumn = { MediaStore.Images.ImageColumns.Data };
                var cursor = ContentResolver.Query(data.Data, filePathColumn, null, null, null);
                cursor.MoveToFirst();
                var colummIndex = cursor.GetColumnIndex(filePathColumn[0]);
                MediaPicker.filePickedPath = cursor.GetString(colummIndex);
            }
        MediaPicker.waitHandle.Set();
        Finish();
    }
}

注意:如果需要,这可以在 MainActivity/FormsAppCompatActivity 上实现以避免这个额外的 Activity...

用法:

var filePath = await DependencyService.Get<IMediaPicker>().ChooseAFileAsync();
System.Diagnostics.Debug.WriteLine(filePath);

【讨论】:

  • 我在运行时得到这个异常:Android.Content.ActivityNotFoundException MediaChooserActivityProxy};你有没有在你的 AndroidManifest.xml 中声明这个活动,但我把它放在清单中:
  • @Bob5421 从您的清单中删除它,并将Activity 属性添加到MediaChooserActivityProxy 类,即[Activity(Label = "MediaChooserActivityProxy")]
  • 现在我对路径 propertystore.forms 的异常访问被拒绝
猜你喜欢
  • 2019-03-27
  • 2021-12-14
  • 2014-08-22
  • 2020-06-14
  • 2020-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
相关资源
最近更新 更多