在Android上以编程方式使用相机拍照

66

我创建了一个有按钮的应用程序,并为该按钮编写了onClick监听器。我尝试了几个示例代码,但它们都没有起作用。它们都会打开Android相机应用程序,但不会拍照。我想要一些代码,可以将其放入我的onClick监听器中,因此当我按下屏幕上的按钮时,就会拍摄一张照片。

如何在Android活动中按下按钮时让相机拍摄照片?


1
请参考以下链接:https://dev59.com/4mYr5IYBdhLWcg3wE2Oz#40041381 - Karthik Sridharan
7个回答

99

请看下面的演示代码。

这是您用于UI的XML文件,

<?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>

这是你的Java类文件:

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");
        }
    }
}

注意:

在您的清单文件中指定以下权限,

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

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

5
请再次将相机设置为预览模式,但不要使它自动拍照并返回。您能检查一下吗?谢谢。 - Muhammad Maqsoodur Rehman
1
哪个按钮确切地说?你是指我的布局中指定的按钮还是指相机处于预览模式时的按钮?请澄清。 - Muhammad Maqsoodur Rehman
1
@MuhammadMaqsoodurRehman:在您的布局中指定的按钮,其文本写作Camera,如我在答案中所述。 - Mehul Joisar
2
@MuhammadMaqsoodurRehman:你应该从 http://developer.android.com/training/camera/photobasics.html 开始。 - Mehul Joisar
2
@ranjithstar256: camera.performclick(); 只能打开相机,不能直接拍照。用户需要进行交互才能拍照。 - Mehul Joisar
显示剩余14条评论

31

拍照有两种方式:

1 - 使用Intent拍照

2 - 使用相机API

我认为您应该使用第二种方式,这里有两种方式的示例代码


1
我正在使用这个例子。在第二个例子中,应用程序崩溃了。它说java.lang.RuntimeException:takePicture失败。 - Abdul Waheed
@AbdulWaheed,我认为你正在使用Android 6.0+,这需要在访问相机之前显式请求运行时权限。你的Android版本是多少? - Akah
该示例使用了Camera类,该类已自API 21(Android 5.0,棒棒糖)起被弃用。但即使请求了权限,在按钮点击时仍会崩溃。 - Mikolasan

6
你可以使用神奇拍照库。
1. 尝试在gradle中编译。
compile 'com.frosquivel:magicaltakephoto:1.0'

2. 你需要在 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. 这样实例化类

// “this” 是当前活动参数

MagicalTakePhoto magicalTakePhoto =  new MagicalTakePhoto(this,ANY_INTEGER_0_TO_4000_FOR_QUALITY);

4. 如果需要拍照,请使用以下方法:

magicalTakePhoto.takePhoto("my_photo_name");

5. 如果你需要在设备上选择图片,请尝试以下方法:

magicalTakePhoto.selectedPicture("my_header_name");

6. 您需要重写活动或片段的onActivityResult方法,如下所示:

@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());
}

注意:只有使用这个库才可以在设备上获取和选择图片,此库最低支持API 15。


该库未更新,请建议更新的库。 - Anand Savjani

3

如果您正在寻找一种使用Android的Camera和Camera2 API以编程方式拍摄照片/照片的方法,请查看Google提供的开源示例 这里


2
将图片拍摄并保存到指定文件夹中。
 //Global Variables
   private static final int CAMERA_IMAGE_REQUEST = 101;
    private String imageName;

拍照功能

 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);

        }

广播新添加的图片,否则图片将无法在图库中显示

    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();
                }
            }

权限

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

是的,这里有完整的文档和代码:https://developer.android.com/training/camera/photobasics.html#TaskPath。 - Kirill Vashilo

-1
以下是打开相机的简单方法:
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);
}

1
“打开相机的方式”是什么意思?它是指你以某种方式访问图片并显示吗?还是指你在智能手机上使用/打开“相机应用程序”? - humanityANDpeace

-5
Intent takePhoto = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(takePhoto, CAMERA_PIC_REQUEST)

并设置CAMERA_PIC_REQUEST= 1或0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接