Monodroid setting imageview to image stored on sdc

2019-07-18 17:44发布

问题:

How do I take a photo and save it to a specific folder. I know it saves to the sdcard/DCIM/etc

But I don't want it there, I want it to be stored in a folder in /sdcard/Camera

I have made the directory with the following :

String destPath = Android.OS.Environment.ExternalStorageDirectory + "/Camera";

Then I launch the camera intent and try point the save file to the path I made.

Intent launchCamera = new Intent(Android.Provider.MediaStore.ActionImageCapture);
launchCamera.PutExtra(MediaStore.ExtraOutput, destPath);

This isn't working. Images still get saved to /sdcard/dcim/etc

Ideas?

回答1:

From what I gathered when I developed an application using Monodroid is that the camera is very buggy and does not do what you want it to most of the time. This includes specifying the destination where images capture are to be saved. To my knowledge these issues aren't specific to Monodroid and do occur with the java android sdk.

A work around to this issue that you may want to look at is capturing the image without specifying a destination, then in the OnActivityResult method retrieve the latest image saved to the gallery. Once you get the latest image you can then move it to your preferred destination.

Here is some example code from within OnActivityResult.

Retrieve the filename of the captured image

Android.Net.Uri targetUri = data.Data;
String origin = "";
String [] proj = { MediaStore.MediaColumns.Data.ToString (), BaseColumns.Id };

var qry = ManagedQuery (MediaStore.Images.Media.ExternalContentUri, proj, null, null, "date_added DESC");

qry.MoveToFirst ();

origin = qry.GetString (qry.GetColumnIndexOrThrow (MediaStore.MediaColumns.Data.ToString ()));

Move the image to your desired destination

System.IO.File.Move (origin, "yourdestinationfilenamehere");


回答2:

I'd like to add to lanks's solution.

Let's say you use the following code to take a picture

var uri = ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri,
                                 new ContentValues());

var intent = new Intent(MediaStore.ActionImageCapture);
intent.PutExtra(MediaStore.ExtraOutput, uri);
StartActivityForResult(intent, ACTIVITY_RESULT_PICTURE_TAKEN);

pictureUri = uri;

Where the ACTIVITY_RESULT_PICTURE_TAKEN is just a simple value you can use in the OnActivityResult to check which activity was completed.

Your OnActivityResult could look something like this:

protected override void OnActivityResult(int requestCode, 
                                         Result resultCode, Intent data)
{
    if (resultCode == Result.Ok && requestCode == ACTIVITY_RESULT_PICTURE_TAKEN)
    {
         string picturePath = GetRealPathFromURI(pictureUri);
         //Do something with the file
    }
}

The Uri you got earlier is something specific to android and needs to be translated.

It looks like "//content://media/external/media/11917" which is not a valid path.

Which is exactly what the GetRealPathFromURI function does:

public string GetRealPathFromURI(Android.Net.Uri contentUri)
{            
    var mediaStoreImagesMediaData = "_data";
    string[] projection = { mediaStoreImagesMediaData };
    Android.Database.ICursor cursor = this.ManagedQuery(contentUri, projection, 
                                                        null, null, null);
    int columnIndex = cursor.GetColumnIndexOrThrow(mediaStoreImagesMediaData);
    cursor.MoveToFirst();
    return cursor.GetString(columnIndex);
}

Once you've got the real path, you can move it to wherever you want as lanks suggested.