【问题标题】:How to extract file URI from camera intent?如何从相机意图中提取文件 URI?
【发布时间】:2013-06-01 15:53:54
【问题描述】:

我正在查看一些触发android.media.action.IMAGE_CAPTURE 意图并使用类级变量来存储结果图像的示例。我不想那样做。我想我应该能够给意图文件的 URI,然后在完成时从意图中取回该 URI。我正在尝试这样做:

void snapPixButton_Click(object sender, EventArgs e)
{
    Intent cameraIntent = new Intent(MediaStore.ActionImageCapture);
    File file = new File(Home.SnapStorageLocation, string.Format("{0}.jpg", Guid.NewGuid()));

    cameraIntent.PutExtra(MediaStore.ExtraOutput, file.ToURI().ToString());

    StartActivityForResult(cameraIntent, SnapPixIntentRequestCode);
}

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    if (requestCode == SnapPixIntentRequestCode && resultCode == Result.Ok)
    {
        URI uri = new URI(data.GetStringExtra(MediaStore.ExtraOutput));
        File file = new File(uri);

        using (Bitmap bitmap = LoadAndResizeBitmap(file.Path, this.ImageView.Width, this.ImageView.Height))
        {
            this.ImageView.SetImageBitmap(bitmap);
        }
    }
}

但在OnActivityResult 中,对data.GetStringExtra(MediaStore.ExtraOutput) 的调用导致消息:未知标识符:MediaStore

我做错了什么?我认为我不应该保留类级别的变量,我应该能够将数据传递给意图,然后再提取它,对吗?

【问题讨论】:

标签: android android-intent android-camera xamarin


【解决方案1】:

我以这种方式检索 Uri

    String[] filePathColumn = { MediaStore.Images.Media.DATA };
    Uri imageFilePathUri = null;
    if (cameraImagePath != null) {
        Cursor imageCursor = getContentResolver().query(
            cameraImagePath, filePathColumn, null, null, null);
    if (imageCursor != null && imageCursor.moveToFirst()) {
        int columnIndex = imageCursor.getColumnIndex(filePathColumn[0]);
        String filePath = imageCursor.getString(columnIndex);
        imageCursor.close();
        imageFilePathUri = filePath != null ? Uri
                .parse(filePath) : null;
    }

从这个 Intent 开始

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    ContentValues values = new ContentValues(3);

    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    cameraImagePath = getContentResolver().insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImagePath);
    startActivityForResult(takePictureIntent, CAMERA_REQUEST);

【讨论】:

  • 看起来您仍在使用全局/类级别变量cameraImagePath。我特别问如何不这样做,只需在拍摄照片后从Intent 中提取保存路径。如果我错了并且您发布的代码不完整,请纠正我。谢谢!
【解决方案2】:

我这样做的方式是使用一个新的 File 对象。在我拍照之前,我会创建一个新文件,这样我就知道要使用什么文件了。

我的 Intent 启动代码:

var cameraIntent = new Intent(MediaStore.ActionImageCapture);
var availableActivies = PackageManager.QueryIntentActivities(cameraIntent,
                                                             PackageInfoFlags.Permissions);

if (availableActivies != null && availableActivies.Count > 0)
{
    var dir =
        new File(
            Android.OS.Environment.GetExternalStoragePublicDirectory(
                Android.OS.Environment.DirectoryPictures), "Map name");
    if (!dir.Exists())
    {
        dir.Mkdirs();
    }
    _imageFile = new File(dir, string.Format("CP2{0}.jpg", DateTime.Now.Ticks));
    cameraIntent.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(_imageFile));

    StartActivityForResult(cameraIntent,100);
}

然后在 Activity Result 我只是这样做:

using (Bitmap usedBitmap = BitmapFactory.DecodeFile(_imageFile.AbsolutePath))
{
    _usedImageView = FindViewById<ImageView>(Resource.Id.imageView1);
    _usedImageView.SetImageBitmap(usedBitmap);
    _usedImageView.Dispose();
    usedBitmap.Dispose();
}

希望这对您的问题有所帮助。

【讨论】:

  • 谢谢。我明白了 - 但您仍在使用类级变量 (_imageFile),而不是从 Intent 获取路径/数据。必须保留类级别的变量来执行异步工作似乎是超级蹩脚的。当相机完成拍摄照片时,它应该返回您的意图以及图像的路径/数据(如果用户拍摄了),或空路径/数据。如果您之前提供了保存路径,intent 发送为 null 似乎很奇怪(可能是一个错误)。
  • 嗯,是的,我知道如果您能询问提供路径的意图,那就太好了。我无法帮助你,因为我从来没有调查过,因为类变量对我来说不是问题。祝你找到答案好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-02
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
相关资源
最近更新 更多