0

I am writing my first App. I am using KitKat and an Experia Z for testing. My app will display photos that have been previously taken by the app.

I have been going round in ever decreasing circles, searching and trying, but never succeeding. I realise that I am possibly asking a duplicate question, but I have been unable to find it - and hence, the answer I need.

My starting point was from the Getting Started tutorials: http://developer.android.com/training/camera/photobasics.html

I create the Intent using:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

I can get hold of the small image using:

Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) data.getExtras().get("data");

BTW, I have just noticed that all my test photos taken this way are visible the 'Album' app, and have the traditional file path in a camera, such as '/storage/sdcard1/DCIM/100ANDRO/DSC_0120.jpg'

Is there a way to get hold of this file path (in the onActivityResult() method)?

When I provide a file system URI, using:

File storageDir = 
     Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File photoFile = new File(storageDir, "test.jpg");
mCurrentPhotoPath = "file:" + photoFile.getAbsolutePath(); 

The path for 'storageDir' displays as: "/storage/emulated/0/Pictures". Which looks like some kind of temporary or logical location.

I add an 'extra' to the intent:

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));

However, when I try to get the photo, it is never found (and it isn't in the standard camera file system, shown above)

bmOptions.inPurgeable = true;
Bitmap imBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);    

The Bitmap imBitmap is null. Which suggest the the location in 'mCurrentPhotoPath' is not found.

AH! I don't know why 'mCurrentPhotoPath' is created with 'file:' as a prefix. I have removed it, and I now get my photo returned. (It was taken as portrait, but it is displayed across the ImageView, as if taken in landscape - no doubt that can handled).

However, I still don't know where it is. I have searched the phone and SD card using File Commander, and I can't find it. I would like to have the images stored in the same place as other photos, where they can be accessed by other apps.

Is there another step, whereby I ask for the image to be saved as a photo, so it gets the next file name in the 'DSC_nnnn.jpg' sequence? Or, as date-defined file path / name of my choice, on the same media defined for photos (internal or SD card)?

I would be really grateful for any help on this.

Regards, John

[edit 1]

Took phone to the beach - beach-weather days in the UK are a rare thing! This is my first Android phone - so I am in at the deep end.

In the relaxed conditions, I searched the phone using File Commander and, as stated in a reply, I found a 'Pictures' directory on the internal storage, and it contained the jpegs taken when I provided the location via the 'putExtra', and their location was as defined by Environment.DIRECTORY_PICTURES - so they are retrievable.

What I would prefer to happen is for the pictures to be placed wherever the Camera is set to store them - in my case this is on the SD card. This is what happens when I don't provide a target file location via 'putExtras' - which makes complete sense. I can get the thumbnail image using 'data.getExtras().get("data")'. Is there a way to get the file path for the actual image?

If that isn't possible, how can I get the location used by Camera on the SD card, in order to provide this as an Extra? All of the 'Environment.getXxxDir() methods look to return the internal storage.

[/edit 1]

  • `File f;` `f.FileName` = Path of the file. Save this path in a string then use it when you need – angel Jun 12 '14 at 12:48
  • YOu get a path like /storage/emulated/0/Pictures if your device doesn't have an actual sd card. If you don't have an sd card, you have no external storage. So Android instead uses a subset of internal storage and calls it external so anything that calls getExternalStorage will work. That doesn't mean its temporary- it just means its pretending that directory is an sd card. The file in the filename is because you're creating a URI, not a path. I think you're missing a '/' or two in there though- it may not be reading your protocol right because of that. – Gabe Sechan Jun 12 '14 at 12:51
  • Thanks angel and Gabe. I now understand a bit more, and have narrowed my questions in [edit 1]. – John Ormerod Jun 12 '14 at 22:09

1 Answers1

0

The way to find the location of the photo just taken on the file system is:

  1. No Extras to provide a file path and location. The image will be placed wherever defined in the Camera's settings (Internal or SD card)

  2. Start the Activity to take the picture:

    private static final int REQUEST_IMAGE_CAPTURE = 1;
    ...
    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    
  3. Handle the result (the key is that data.getData() returns the URI of the photo's file):

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
           Uri imageUri = data.getData();
           System.out.println("DisplayImageActivity#onActivityResult() - imageUri = "+imageUri);
           String imagePath = getRealPathFromURI(imageUri);
           System.out.println("DisplayImageActivity#onActivityResult() - image file path = 
                       "+imagePath);
           ...
    
  4. Get the actual path from the URI: This code is from: Get file path of image on Android , and provided by Siddarth Lele (thanks Siddarth)

    public String getRealPathFromURI(Uri uri) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null); 
        cursor.moveToFirst(); 
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
        return cursor.getString(idx); 
    }
    

The values from the System.outs are:

imageUri = content://media/external/images/media/4777

imagePath = /storage/sdcard1/DCIM/100ANDRO/DSC_0143.JPG

I can now use the file path to get and show the photo:

Bitmap imBitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
imageView.setImageBitmap(imBitmap); 

I now have a new challenge: the photo was taken in portrait mode, but the resultant image is shown in landscape mode across the top of the ImageView, instead of as taken. If I can't find or figure out how to rotate it, I will create another SO request.

Community
  • 1
  • 1