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":
/* 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)); } }
- /* 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));
- }
- }
Just in case
The ImageView I have (minus the width, height, margins, etc):
<ImageView android:id="@+id/hangar_aircraft_photo" />
- <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