Android: Function to let user take photo or choose existing

What?
A quick article on a function to allow the user to take a photo using their built-in camera or to choose an existing photo from their gallery.

Why?
I wanted both options to be available to the user and for it to replace a displayed image in an ImageView.

How?
More as a reference for myself but this displays an AlertDialog designed by an XML layout file ("res/layout/dialog_edititem_photo"). The ImageView exists in another XML with an identifier called @+id/hangar_aircraft_photo. The following is a full example of what can be added to a Main Activity Java file and will display an AlertDialog with the 3 options to "take a photo", "choose from existing", or "cancel":
copyraw
/* 201411040126 */

    static final int REQUEST_IMAGE_CAPTURE = 1;
    private static int RESULT_LOAD_IMAGE = 1;
    private static int TAKE_OR_PICK = 0;

    public void chooseOrTakePhoto(View view) {
        final View v = getLayoutInflater().inflate(R.layout.dialog_edititem_photo, null);
        AlertDialog.Builder b = new AlertDialog.Builder(this);
        LayoutInflater inflater = this.getLayoutInflater();
        b.setView(v);
        b.setPositiveButton("Take Photo", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
                TAKE_OR_PICK = 1;
                Intent takePictureIntent = new Intent(
                        MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }
            }
        });
        b.setNeutralButton("Choose Existing", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                TAKE_OR_PICK = 2;
                Intent choosePictureIntent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(choosePictureIntent, RESULT_LOAD_IMAGE);
            }
        });
        b.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        b.setView(inflater.inflate(R.layout.dialog_edititem_photo, null));
        b.create().show();
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        // if taking
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK && null != data  && TAKE_OR_PICK == 1) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");

            // my ImageView
            ImageView myPhotoImage = (ImageView) findViewById(R.id.hangar_aircraft_photo);
            myPhotoImage.setImageBitmap(imageBitmap);

        // if choosing
        } else if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data  && TAKE_OR_PICK == 2) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();

            // my ImageView
            ImageView myPhotoImage = (ImageView) findViewById(R.id.hangar_aircraft_photo);
            myPhotoImage.setImageBitmap(BitmapFactory.decodeFile(picturePath));
        }
    }
  1.  /* 201411040126 */ 
  2.   
  3.      static final int REQUEST_IMAGE_CAPTURE = 1
  4.      private static int RESULT_LOAD_IMAGE = 1
  5.      private static int TAKE_OR_PICK = 0
  6.   
  7.      public void chooseOrTakePhoto(View view) { 
  8.          final View v = getLayoutInflater().inflate(R.layout.dialog_edititem_photo, null)
  9.          AlertDialog.Builder b = new AlertDialog.Builder(this)
  10.          LayoutInflater inflater = this.getLayoutInflater()
  11.          b.setView(v)
  12.          b.setPositiveButton("Take Photo", new DialogInterface.OnClickListener() { 
  13.              @Override 
  14.              public void onClick(DialogInterface dialog, int whichButton) { 
  15.                  TAKE_OR_PICK = 1
  16.                  Intent takePictureIntent = new Intent( 
  17.                          MediaStore.ACTION_IMAGE_CAPTURE)
  18.                  if (takePictureIntent.resolveActivity(getPackageManager()) != null) { 
  19.                      startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
  20.                  } 
  21.              } 
  22.          })
  23.          b.setNeutralButton("Choose Existing", new DialogInterface.OnClickListener() { 
  24.              @Override 
  25.              public void onClick(DialogInterface dialog, int which) { 
  26.                  TAKE_OR_PICK = 2
  27.                  Intent choosePictureIntent = new Intent( 
  28.                          Intent.ACTION_PICK, 
  29.                          android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
  30.                  startActivityForResult(choosePictureIntent, RESULT_LOAD_IMAGE)
  31.              } 
  32.          })
  33.          b.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
  34.              @Override 
  35.              public void onClick(DialogInterface dialog, int which) { 
  36.                  dialog.cancel()
  37.              } 
  38.          })
  39.          b.setView(inflater.inflate(R.layout.dialog_edititem_photo, null))
  40.          b.create().show()
  41.      } 
  42.   
  43.      @Override 
  44.      protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
  45.   
  46.          // if taking 
  47.          if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK && null != data  && TAKE_OR_PICK == 1) { 
  48.              Bundle extras = data.getExtras()
  49.              Bitmap imageBitmap = (Bitmap) extras.get("data")
  50.   
  51.              // my ImageView 
  52.              ImageView myPhotoImage = (ImageView) findViewById(R.id.hangar_aircraft_photo)
  53.              myPhotoImage.setImageBitmap(imageBitmap)
  54.   
  55.          // if choosing 
  56.          } else if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data  && TAKE_OR_PICK == 2) { 
  57.              Uri selectedImage = data.getData()
  58.              String[] filePathColumn = { MediaStore.Images.Media.DATA }
  59.              Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null)
  60.              cursor.moveToFirst()
  61.              int columnIndex = cursor.getColumnIndex(filePathColumn[0])
  62.              String picturePath = cursor.getString(columnIndex)
  63.              cursor.close()
  64.   
  65.              // my ImageView 
  66.              ImageView myPhotoImage = (ImageView) findViewById(R.id.hangar_aircraft_photo)
  67.              myPhotoImage.setImageBitmap(BitmapFactory.decodeFile(picturePath))
  68.          } 
  69.      } 

Just in case
The ImageView I have (minus the width, height, margins, etc):
copyraw
<ImageView android:id="@+id/hangar_aircraft_photo" />
  1.  <ImageView android:id="@+id/hangar_aircraft_photo" /> 

Additional
To check if the user has a camera beforehand, apparently if(hasSystemFeature(PackageManager.FEATURE_CAMERA)) is a way to go. I haven't tested yet as I need a tablet/phone that doesn't have a camera...

Applies to:
  • Android Studio v0.8.9
  • Microsoft Windows 7 Pro
  • Android: Min SDK v4.0.3 (IceCreamSandwich) API 15
  • Android: Target SDK v4.4 (KitKat) API 19
Category: AndroidOS :: Article: 594

Add comment

Your rating:

Submit

Credit where Credit is Due:


Feel free to copy, redistribute and share this information. All that we ask is that you attribute credit and possibly even a link back to this website as it really helps in our search engine rankings.

Disclaimer: Please note that the information provided on this website is intended for informational purposes only and does not represent a warranty. The opinions expressed are those of the author only. We recommend testing any solutions in a development environment before implementing them in production. The articles are based on our good faith efforts and were current at the time of writing, reflecting our practical experience in a commercial setting.

Thank you for visiting and, as always, we hope this website was of some use to you!

Kind Regards,

Joel Lipman
www.joellipman.com

Please publish modules in offcanvas position.