如何从拍摄相机照片的URI中打开位图?

时间:2018-03-29 18:36:15

标签: xamarin xamarin.forms xamarin.android

我在这里感到非常困惑,并尝试了很多我在SO上看过的建议。我正在遵循Xamarin配方在Android上访问相机并拍照。有些东西缺失/过时,但无论我到达需要调用BitmapFactory.DecodeFile的位置,我都可以打开用户刚拍摄的图像并调整大小以显示在我的视图中。我遇到的问题是我无法使用文件路径,我必须使用URI。所以我按照说明in this SO thread

并设置我的文件提供程序。我在resources / xml目录中有这个文件:provider_paths.xml(MyApp是从我的实际应用程序详细信息重命名的)

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="MyApp" path="."/>
</paths>

然后在清单中我在部分内添加了这个:

<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.myapp.provider" android:exported="false" android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
</provider>

我通过执行以下操作确保目录存在:

var file = new File(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures), "MyApp");
Directory = file.AbsolutePath;
if (!file.Exists())
    file.Mkdirs();

(目录是一个字符串变量)。

我创建了意图和文件名,如下所示:

Intent intent = new Intent(MediaStore.ActionImageCapture);              
var file = new File(Directory, $"myPhoto_{Guid.NewGuid()}.jpg");
BaseFilename = file.Name;

_uri = FileProvider.GetUriForFile(MainActivity.Instance, "com.myapp.provider", file);

intent.PutExtra(MediaStore.ExtraOutput, _uri);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);

(BaseFilename是此类中的字符串变量)

起初我想也许我应该以某种方式将URI转换为文件路径,以便我可以调用BitmapFactory.DecodeFile。我跟着几个SO线程,但没有一个工作。当他们都开始做ContentResolver.Query或游标操作时,我得到了各种异常。

所以我想,嗯,有一个BitmapFactory.DecodeStream方法,为什么不使用它呢?我尝试从URI中获取流,如下所示:

var stream = MainActivity.Instance.ContentResolver.OpenInputStream(_uri)

但是当我这样做时,我得到一个例外:Java.Lang.Exception: open failed: ENOENT (No such file or directory)

尝试此操作时URI的示例:

content://com.myapp.provider/MyApp/Pictures/MyApp/myPhoto_2d13056f-6d23-461a-ad4b-532e10d9cb75.jpg

我在这一点上很困惑甚至问题是什么,并且很难用很多过时的Xamarin样本,我不知道在哪里看,甚至是什么这里真正的潜在问题。任何见解将不胜感激。顺便说一句,如果重要的话,我至少可以正确地获得许可。我已经提示进行相机和存储访问(我已经处理了关于没有相机/读/写外部存储许可的错误,所以至少已经结束了。)

1 个答案:

答案 0 :(得分:0)

天啊,我刚刚把头撞到墙上2天后想出来了。事实证明,小睡实际上是非常有帮助的。我以为我已经处理了所有的许可请求。但后来我开始探索我的设备的文件结构,并注意到图像没有被保存。这真是奇怪,因为昨晚的图像实际上是在保存。我可以看到它们和日期戳。无论如何,我决定尝试提示WRITE_EXTERNAL_STORAGE许可(已经用READ和CAMERA做了)并解决了所有问题。