2

I was looking at some examples which fire an android.media.action.IMAGE_CAPTURE intent and use a class-level variable to store the resulting image. I don't want to do that. I think I should be able to give the intent the URI of the file and then get that URI back from the intent when it completes. I am trying to do this:

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);
        }
    }
}

But in OnActivityResult, the call to data.GetStringExtra(MediaStore.ExtraOutput) results in the message: Unknown identifier: MediaStore

What am I doing wrong? I don't think I should have to keep class-level variables around, I should be able to pass data to an intent and then extract it afterwards, right?

Josh M.
  • 26,437
  • 24
  • 119
  • 200

2 Answers2

0

I retrieve the Uri this way

    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;
    }

and the start with this 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);
Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • It looks like you're still using a global/class-level variable, `cameraImagePath`. I'm specifically asking how NOT to do that and just extract the save path from the `Intent` after the picture is taken. Correct me if I'm wrong and the code your posted is not complete. Thanks! – Josh M. Jun 01 '13 at 18:14
0

The way I'm doing this is with a new File object. Before I take the picture I make a new file so I know what file to use.

My code to start the in 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);
}

Then on Activity Result I just do this:

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

Hope this helps with your problem.

jHogen
  • 123
  • 8
  • 1
    Thanks. And I get that - but you're still using a class-level variable (`_imageFile`) instead of getting the path/data from the `Intent`. It just seems super-lame to have to keep class-level variables around to do async work. When the camera is done snapping a photo, it should return you the intent along with the path/data for the image (if the user took one), or a null path/data. It seems very strange (maybe a bug) that the `intent` is sent as `null` if you previously provided the save path. – Josh M. Jun 03 '13 at 11:27
  • Hmm yeah I understand that it would be nice if you could ask the intent to provide the path. I can't help you with that as I've never looked into that because the class variable is no issue for me. Good luck with finding an answer! – jHogen Jun 03 '13 at 11:41