1

Edit

My functions now look like this:

p
Community
  • 1
  • 1
  • 1
    https://stackoverflow.com/questions/32789157/how-to-write-files-to-external-public-storage-in-android-so-that-they-are-visibl – CommonsWare Apr 08 '18 at 13:47
  • Where exactly would I use this function? Before startActivityForResult(callCameraApplicationIntent, REQUEST_TAKE_PHOTO);? – Joe O'Brien Apr 08 '18 at 14:04
  • No, because the photo has not been taken yet. Do it on `onActivityResult()`, if the photo appears to have been taken at the location that you specified. – CommonsWare Apr 08 '18 at 14:05
  • How will I use photoFile as an argument if it is set inside another function? – Joe O'Brien Apr 08 '18 at 14:21
  • Hold onto it in a field in your activity. Also, be sure to save it as part of the saved instance state `Bundle`, as your process may be terminated while the camera app is in the foreground. [This sample app](https://github.com/commonsguy/cw-omnibus/tree/v8.11/Camera/FileProvider) demonstrates the technique, though I use the `File` for `ACTION_VIEW` instead of `MediaScannerConnection`. – CommonsWare Apr 08 '18 at 14:23
  • If its outside that function will that not mean everytime a new image is taken in-app, its name will always be the same? – Joe O'Brien Apr 08 '18 at 15:03
  • Ordinary fields in Java are not read-only (though `final` ones are). You are welcome to change the value of the field to reflect a new filename as you see fit. In my sample, I only use one filename, but that just is how I chose to implement that sample. In the end, how you write this code is up to you -- to solve your original problem, you need to have the `MediaStore` scan the photo file, after the camera app has taken the picture. – CommonsWare Apr 08 '18 at 15:11
  • What I mean is that if I set the variable photoFile in the takePhoto() function, how can I use this value in onActivityResult()? – Joe O'Brien Apr 08 '18 at 15:59

3 Answers3

0

I have made some changes to your code:

Add this to you application level in your Manifest:

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

Then create file_paths.xml file:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-cache-path name="my_cache" path="." />
    <external-path name="my_images" path="Pictures/" />
     </paths>

Then in your code:

  private static final String FILE_PROVIDER_AUTHORITY = "com.example.android.fileprovider";

  private String mTempPhotoPath;

 public void takePhoto() {
// Create the capture image intent
    Intent imageCapture= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    // Ensure that there's a camera activity to handle the intent
    if (imageCapture.resolveActivity(getPackageManager()) != null) {
        // Create the temporary File where the photo should go
        File photoFile = null;
        try {
            photoFile = createTempImageFile(this);
        } catch (IOException ex) {
            // Error occurred while creating the File
            ex.printStackTrace();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {

            // Get the path of the temporary file
            mTempPhotoPath = photoFile.getAbsolutePath();

            // Get the content URI for the image file
            Uri imageUri = FileProvider.getUriForFile(this,
                    FILE_PROVIDER_AUTHORITY,
                    photoFile);

            // Add the URI so the camera can store the image
            imageCapture.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    }

    static File createTempImageFile(Context context) throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = context.getExternalCacheDir();

    return File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
}


//To save image

String mCurrentPhotoPath = null;
private File createImageFile() throws IOException {

    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "IMG_" + timeStamp + "_";
    File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/DCIM/Camera");
    Log.d(TAG, "createImageFile: Saving image to:" + storageDir);
    File image = new File(storageDir, imageFileName);

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();

    //Return the saved image
    return mCurrentPhotoPath ;
} 
  • This function is for creating the filename that the image will be stored as. I already have a function for getting the filepath of last image stored. – Joe O'Brien Apr 08 '18 at 18:30
  • This is good, but do you know how I can set the file_paths.xml so that I can save the new image in the DCIM/Camera folder, as part of the app gets all images from that folder. Would I just replace 'path="Pictures/" ' with 'DCIM/Camera/' ? – Joe O'Brien Apr 09 '18 at 16:13
  • I've tried this and I'm getting the error - java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/DCIM/Camera/IMG_20180409_190420_896248155.jpg – Joe O'Brien Apr 09 '18 at 18:05
  • No, replace `Environment.DIRECTORY_PICTURES` with `Environment.DIRECTORY_DCIM` – Damilola Omoyiwola Apr 09 '18 at 19:26
0

If uou want to save image in your external storage use Externalstoragepublicdirectory function.

rupesh
  • 39
  • 11
0

This intent expects the EXTRA_OUTPUT location in Uri format, see https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE. Some devices may understand an absolute file path, but this is not the documented behavior.

You can use getExternalMediaDirs() to avoid many permission restrictions.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307