1

I am trying to make an app where the user can take a picture and that picture gets stored in an imageview. I have tried dozens of methods to get this to work.

A lot of answers I've viewed suggest using data.getExtra("data") with using the MediaStore intent and passing in ACTION_CAMERA_CAPTURE. This returns a smaller image and the image I am trying to display is large so the image shows up blurry using this method.

The other option is to use this same method and pass in EXTRA_OUTPUT. However, this requires putting in the storage location and every answer I have seen tells me to put in Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES). However when I try to do data.getData() in onActivityResult I get null. How do I do this?

alert.setPositiveButton("Take Photo", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        profileFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "image_" +
                                String.valueOf(System.currentTimeMillis()) + ".jpg");

        profile = Uri.fromFile(profileFile);
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, profile);


        startActivityForResult(intent, 1);
    }
});


protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == 1 && resultCode == RESULT_OK) {

        ImageView imageView = (ImageView) findViewById(R.id.ProfileImage);

        //This returns null. 
        //I am guessing that the Environment.getExternalSt...() method is getting a storage 
        //location that does not exist. 
        //I don't know what the correct storage location is and I have not 
        //been able to find it.
        Uri u = data.getData();

        File finalFile = new File(getRealPathFromURI(u));

        Picasso.with(this).load(finalFile).into(imageView);

    }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267

1 Answers1

0

I am guessing that the Environment.getExternalSt...() method is getting a storage location that does not exist.

Probably not. However, you are assuming that your EXTRA_OUTPUT value is returned to you by the camera app. There is nothing in the ACTION_IMAGE_CAPTURE documentation that would suggest that this occurs.

I don't know what the correct storage location is and I have not been able to find it.

You know where the image is supposed to be. It is supposed to be in the location that you supplied in EXTRA_OUTPUT. So, go look there to see if the image is there. However, make sure that you are putting profileImage in the saved instance state Bundle, as there is no guarantee that your process will remaining running while the camera application is in the foreground. Also, bear in mind that there are many buggy ACTION_IMAGE_CAPTURE implementations, so there is no guarantee that the image will be where you requested, though it should be.

For example, here is an activity that uses ACTION_IMAGE_CAPTURE to take a full-resolution picture, then uses ACTION_VIEW to have some image viewer display the result:

/***
 Copyright (c) 2008-2016 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 From _The Busy Coder's Guide to Android Development_
 https://commonsware.com/Android
 */

package com.commonsware.android.camcon;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;

public class CameraContentDemoActivity extends Activity {
  private static final String EXTRA_FILENAME=
    "com.commonsware.android.camcon.EXTRA_FILENAME";
  private static final String FILENAME="CameraContentDemo.jpeg";
  private static final int CONTENT_REQUEST=1337;
  private File output=null;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent i=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    if (savedInstanceState==null) {
      File dir=
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);

      dir.mkdirs();
      output=new File(dir, FILENAME);
    }
    else {
      output=(File)savedInstanceState.getSerializable(EXTRA_FILENAME);
    }

    if (output.exists()) {
      output.delete();
    }

    i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));

    startActivityForResult(i, CONTENT_REQUEST);
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    outState.putSerializable(EXTRA_FILENAME, output);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode,
                                  Intent data) {
    if (requestCode == CONTENT_REQUEST) {
      if (resultCode == RESULT_OK) {
        Intent i=new Intent(Intent.ACTION_VIEW);

        i.setDataAndType(Uri.fromFile(output), "image/jpeg");
        startActivity(i);
        finish();
      }
    }
  }
}

(from this sample app)

Over the long haul, this is not a great solution, as file Uri values are going away. The official training page, and this revamped edition of my sample app, show using FileProvider instead.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • What do you mean the EXTRA_OUTPUT doesn't get returned? How do I get the intent data if this is wrong? Also, I looked for the storage location on my phone, but could not find it. I did find it by viewing my phone storage on my computer. This is the location [link] (http://i.imgur.com/MgAYa9U.png) (don't know if it helps). Do you know how I could get it to store in the gallery location instead? [link] (http://i.imgur.com/GhdIWB8.png) – kindOfABigDeal Jul 08 '16 at 18:25
  • Actually the folder it is trying to get is wrong. It gives me this location /storage/emulated/0/Pictures/ which doesn't exist. It should give me Pictures directory in the last image. – kindOfABigDeal Jul 08 '16 at 18:32
  • @kindOfABigDeal: "What do you mean the EXTRA_OUTPUT doesn't get returned?" -- I mean that you need to hold onto the value that you put in `EXTRA_OUTPUT`. That value does not come back to you in the result `Intent`. "Actually the folder it is trying to get is wrong" -- most likely, that is a correct location for [external storage](https://commonsware.com/blog/2014/04/08/storage-situation-external-storage.html). – CommonsWare Jul 08 '16 at 18:37
  • @kindOfABigDeal: I updated the answer with some sample code to illustrate how to use `EXTRA_OUTPUT`. – CommonsWare Jul 08 '16 at 18:42
  • It is still giving me the storage location. It doesn't go to the phones DCIM. Also, is there a way to get the image without going to the gallery to select it? – kindOfABigDeal Jul 08 '16 at 19:45
  • @kindOfABigDeal: "It doesn't go to the phones DCIM" -- use `DIRECTORY_DCIM`, not `DIRECTORY_PICTURES`. "Also, is there a way to get the image without going to the gallery to select it?" -- I do not know what you mean by this. – CommonsWare Jul 08 '16 at 19:52
  • So the problem is that my phone has no SD card. It is all stored on the phones internal storage. How do I access data from a phone without an SD card? – kindOfABigDeal Jul 08 '16 at 20:02
  • @kindOfABigDeal: "So the problem is that my phone has no SD card" -- you are not using [removable storage](https://commonsware.com/blog/2014/04/09/storage-situation-removable-storage.html). You are using [external storage](https://commonsware.com/blog/2014/04/08/storage-situation-external-storage.html). "It is all stored on the phones internal storage" -- you are not using [internal storage](https://commonsware.com/blog/2014/04/07/storage-situation-internal-storage.html), in terms of how the Android SDK defines it. "How do I access data from a phone without an SD card?" -- what do you mean? – CommonsWare Jul 08 '16 at 20:07
  • I could be misunderstanding, but I am not referring to removable storage. My phone has no external storage. There is no SD card. – kindOfABigDeal Jul 08 '16 at 20:12
  • Ok, I looked at your links. I think I get it. The problem is the method getExter... is not giving me my devices storage. It gives me something else. http://i.imgur.com/IpbKaDB.png The location it is giving me is in the highlighted storage folder instead of the DCIM folder near the top. – kindOfABigDeal Jul 08 '16 at 20:16
  • http://i.imgur.com/kugT5gn.png Sorry this is the correct image I meant to send. – kindOfABigDeal Jul 08 '16 at 20:23
  • @kindOfABigDeal: In your second comment on this answer, you indicated that `Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)` was returning `/storage/emulated/0/Pictures/`. This makes perfect sense, and it is the `Pictures` directory shown in your most recent screenshot. Your screenshot overall is of `/storage/emulated/0/`, the root of external storage. Using `DIRECTORY_DCIM` instead of `DIRECTORY_PICTURES` should give you `/storage/emulated/0/DCIM/`, which will be the `DCIM` directory in your screenshot. – CommonsWare Jul 08 '16 at 20:34
  • @kindOfABigDeal: Bear in mind that to get your images to actually show up, you also need to get the `MediaStore` to index them: https://stackoverflow.com/questions/32789157/how-to-write-files-to-external-public-storage-in-android-so-that-they-are-visibl – CommonsWare Jul 08 '16 at 20:36
  • What happened is my phone has a duplicate folder. There is another empty folder that has /storage/emulated/0/ and that is the storage folder at the bottom of the image I posted. There is no DCIM folder there. It contains nothing. Somehow a folder that looks like my storage folder is in my phone and that is the location it is going to. – kindOfABigDeal Jul 08 '16 at 20:46