66

I have created an app with a button and wrote onClickListener for that button. I have tried several sample code examples and none of them worked. They all bring up the Android camera app and don't take photographs. I want some code which I can put in my onClickListener so when I press the button on the screen, a picture will be taken.

How can I make the camera take a picture when I press a button in an Android activity?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kevik
  • 9,181
  • 19
  • 92
  • 148

7 Answers7

99

Look at following demo code.

Here is your XML file for UI,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btnCapture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Camera" />

</LinearLayout>

And here is your Java class file,

public class CameraDemoActivity extends Activity {
    int TAKE_PHOTO_CODE = 0;
    public static int count = 0;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Here, we are making a folder named picFolder to store
        // pics taken by the camera using this application.
        final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/picFolder/";
        File newdir = new File(dir);
        newdir.mkdirs();

        Button capture = (Button) findViewById(R.id.btnCapture);
        capture.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                // Here, the counter will be incremented each time, and the
                // picture taken by camera will be stored as 1.jpg,2.jpg
                // and likewise.
                count++;
                String file = dir+count+".jpg";
                File newfile = new File(file);
                try {
                    newfile.createNewFile();
                }
                catch (IOException e)
                {
                }

                Uri outputFileUri = Uri.fromFile(newfile);

                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

                startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
            }
        });
    }

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

        if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
            Log.d("CameraDemo", "Pic saved");
        }
    }
}

Note:

Specify the following permissions in your manifest file,

<uses-permission android:name="android.permission.CAMERA"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mehul Joisar
  • 15,348
  • 6
  • 48
  • 57
  • 5
    Your again puts the camera in preview mode but does not enable it take a snap by itself and then return. Can you please check? Thanks – Muhammad Maqsoodur Rehman Dec 19 '13 at 11:26
  • @MuhammadMaqsoodurRehman: you need to `click` on capture button to capture the image – Mehul Joisar Dec 19 '13 at 11:35
  • 1
    Which button exactly? Do you mean the button specified in my layout or do you mean the button when the camera is in the preview mode? Please clarify. – Muhammad Maqsoodur Rehman Dec 19 '13 at 12:06
  • 1
    @MuhammadMaqsoodurRehman: the button specified in your layout which has text written like `Camera` as mentioned in my answer – Mehul Joisar Dec 19 '13 at 12:07
  • Fine. I uploaded the app on the device, clicked the "Camera" button.When I checked my gallery then there were no pics. Where are these picture files are really getting stored?Let say if I want to store these picture files on my HTC phone's gallery then can I do that? Please explain and clarify. Thanks – Muhammad Maqsoodur Rehman Dec 19 '13 at 12:28
  • 1
    @MuhammadMaqsoodurRehman: the image has been stored in folder named `picFolder` but android doesn't know about newly created file.so you need to send broadcast to update it.have a look at `http://stackoverflow.com/questions/8667623/updating-gallery-after-taking-pictures-gallery-not-showing-all-the-pictures-andr` – Mehul Joisar Dec 19 '13 at 12:34
  • This is honestly confusing. I need the complete code. Can you please direct me to a better link or tutorial? Thanks – Muhammad Maqsoodur Rehman Dec 19 '13 at 12:53
  • 2
    @MuhammadMaqsoodurRehman: you should start with `http://developer.android.com/training/camera/photobasics.html` – Mehul Joisar Dec 19 '13 at 13:18
  • If there's a method to capture images hiddenly? – Elshan May 22 '14 at 04:32
  • even with the same answer you can programmatically press the camera button using this piece of code, **capture.performclick();** – AndroidManifester Jul 16 '15 at 13:43
  • 2
    @ranjithstar256: `camera.performclick();` can open camera only. it will not take picture directly. for that,user has to interact. – Mehul Joisar Jul 16 '15 at 14:24
  • obviously, that code will press the capture(button variable here) button programmatically. you are right – AndroidManifester Jul 16 '15 at 15:14
  • 1
    Why did you have to create file before starting activity... Am not understanding. Someone explain to me please – Karue Benson Karue May 22 '16 at 18:14
  • 1
    In Nexus 7, the code opens the camera and I can press the icon to take the picture but .... It freezes after taking the picture (freeze on the taken picture). Then you have the options to return back or to retake the picture. Both option result in picture not taken (or not saved) !! how to solve this please ? – McLan Nov 07 '16 at 15:55
  • What is TAKE_PHOTO_CODE here cannot find the symbol error. –  Jan 31 '17 at 17:56
  • 1
    This "answer" and its entire comment thread is frustrating. This does NOT automatically take a picture programmatically at all. All it does is programmatically LAUNCH the Camera via a button click, then the user has to INTERACTIVELY click again on the Camera view to accept the image. – Tam Bui Apr 08 '19 at 18:23
  • It gives me error: Failed to handle method call android.os.FileUriExposedException: file:///storage/emulated/0/APP_NAME/1596889464576.jpg exposed beyond app through ClipData.Item.getUri() – Pawan Aug 08 '20 at 12:25
  • @Pawan if you are trying above Android 10, it will be problem because Google has restricted it. reference : https://developer.android.com/training/data-storage/use-cases – Mehul Joisar Aug 17 '20 at 08:20
  • 1
    FYI `startActivityForResult` is deprecated so consider using the new way, can be reference here : https://stackoverflow.com/questions/62671106/onactivityresult-method-is-deprecated-what-is-the-alternative – Aviv Profesorsky Oct 13 '22 at 18:01
31

There are two ways to take a photo:

1 - Using an Intent to make a photo

2 - Using the camera API

I think you should use the second way and there is a sample code here for two of them.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hm1984ir
  • 554
  • 3
  • 7
  • 1
    I am using this example.in second example application crashing.it says java.lang.RuntimeException: takePicture failed – Abdul Waheed Jun 28 '16 at 10:14
  • @AbdulWaheed i think you are using android 6.0+ which requires that you explicitly request permission at runtime before accessing the camera. What is your version of android? – Akah Apr 24 '18 at 02:23
  • The example uses the Camera class, which has been deprecated as of API 21 (Android 5.0, Lollipop). But even with requested permissions it crashes on button click. – Mikolasan Jun 06 '20 at 00:15
6

You can use Magical Take Photo library.

1. try with compile in gradle

compile 'com.frosquivel:magicaltakephoto:1.0'

2. You need this permission in your manifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>

3. instance the class like this

// "this" is the current activity param

MagicalTakePhoto magicalTakePhoto =  new MagicalTakePhoto(this,ANY_INTEGER_0_TO_4000_FOR_QUALITY);

4. if you need to take picture use the method

magicalTakePhoto.takePhoto("my_photo_name");

5. if you need to select picture in device, try with the method:

magicalTakePhoto.selectedPicture("my_header_name");

6. You need to override the method onActivityResult of the activity or fragment like this:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);
     magicalTakePhoto.resultPhoto(requestCode, resultCode, data);

     // example to get photo
     // imageView.setImageBitmap(magicalTakePhoto.getMyPhoto());
}

Note: Only with this Library you can take and select picture in the device, this use a min API 15.

Stav Alfi
  • 13,139
  • 23
  • 99
  • 171
fabian7593
  • 77
  • 1
  • 2
3

For those who came here looking for a way to take pictures/photos programmatically using both Android's Camera and Camera2 API, take a look at the open source sample provided by Google itself here.

Phileo99
  • 5,581
  • 2
  • 46
  • 54
2

Take and store image in desired folder

 //Global Variables
   private static final int CAMERA_IMAGE_REQUEST = 101;
    private String imageName;

Take picture function

 public void captureImage() {

            // Creating folders for Image
            String imageFolderPath = Environment.getExternalStorageDirectory().toString()
                    + "/AutoFare";
            File imagesFolder = new File(imageFolderPath);
            imagesFolder.mkdirs();

            // Generating file name
            imageName = new Date().toString() + ".png";

            // Creating image here
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(imageFolderPath, imageName)));
            startActivityForResult(takePictureIntent,
                    CAMERA_IMAGE_REQUEST);

        }

Broadcast new image added otherwise pic will not be visible in image gallery

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
                // TODO Auto-generated method stub
                super.onActivityResult(requestCode, resultCode, data);

                if (resultCode == Activity.RESULT_OK && requestCode == CAMERA_IMAGE_REQUEST) {

                    Toast.makeText(getActivity(), "Success",
                            Toast.LENGTH_SHORT).show();

 //Scan new image added
                    MediaScannerConnection.scanFile(getActivity(), new String[]{new File(Environment.getExternalStorageDirectory()
                            + "/AutoFare/" + imageName).getPath()}, new String[]{"image/png"}, null);


 // Work in few phones
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

                        getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(Environment.getExternalStorageDirectory()
                                + "/AutoFare/" + imageName)));

                    } else {
                        getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse(Environment.getExternalStorageDirectory()
                                + "/AutoFare/" + imageName)));
                    }
                } else {
                    Toast.makeText(getActivity(), "Take Picture Failed or canceled",
                            Toast.LENGTH_SHORT).show();
                }
            }

Permissions

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
-1

The following is a simple way to open the camera:

private void startCamera() {

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI.getPath());
    startActivityForResult(intent, 1);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Guru
  • 186
  • 14
  • 1
    what does that "way to open the camera" mean. Does it mean that you access somehow the picture and display it? Or does it rather mean that you use/open the "Camera App" on the smartphone? – humanityANDpeace Mar 13 '16 at 20:33
-5
Intent takePhoto = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(takePhoto, CAMERA_PIC_REQUEST)

and set CAMERA_PIC_REQUEST= 1 or 0

Nikhil Patel
  • 1,761
  • 12
  • 23
Rutul Mehta
  • 55
  • 1
  • 6