您的位置:

Android相机应用的开发

一、基本介绍

Android相机应用是移动设备拍摄和录制视频的主要途径,它可以让用户使用相机来拍摄照片、录制视频、使手机成为一个扫描仪,扫描条形码等。

Android中使用相机应用需要使用Camera API。该API通过提供访问相机硬件的功能来实现相机应用。可以通过检测相机是否可用来查询硬件是否支持相机功能,然后将其用于调用相机。应用可以通过Camera API来获得硬件视频流并对其进行处理。

二、Camera API的使用

使用API将相机集成到应用程序时,需要执行以下操作:

1.检查相机支持

应用程序使用系统服务PackageManager.queryIntentActivities ()检查“启动相机”功能是否存在。如果设备上没有摄像机硬件,或者没有应用程序允许使用相机,此方法将返回null。

PackageManager pm = context.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA))
    return false;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
return list.size() > 0;

2.打开相机

在使用相机之前,需要先访问许可(Manifest.permission.CAMERA)。然后,使用Camera.open()方法打开一个访问相机的实例。如果需要使用前置摄像头,则可以使用Camera.open(int cameraId)方法获取该摄像头的ID。

//打开后置摄像头
camera = Camera.open();
//打开前置摄像头
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);

3.设置相机参数

在启动预览之前,还需要设置相机参数,如预览尺寸,照片/视频大小和格式等等。Camera API中的Camera.Parameters类可用于设置这些参数。

Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(width, height);
parameters.setPictureSize(width, height);
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(parameters);

4.预览

设置好相机参数之后,调用camera.startPreview()方法即可启动预览。预览会在SurfaceView或TextureView对象上呈现:

try {
    camera.setPreviewDisplay(surfaceHolder);
    camera.startPreview();
} catch (IOException e) {
    e.printStackTrace();
}

5.拍照

要拍照,需要调用Camera.getPicture()方法。此方法异步处理请求,因此需要实现Camera.PictureCallback回调来接收结果。

camera.takePicture(null, null, new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        // 处理图片data,保存到文件等
        // 拍完照后需要重新启动预览
        camera.startPreview();
    }
});

三、实现一个完整的Camera应用

下面我们会介绍如何实现一个完整的Camera应用:

1.准备工作

我们需要创建以下布局文件和资源文件:

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

    <SurfaceView
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="20dp" />

    <Button
        android:id="@+id/button_capture"
        android:text="Capture"
        android:textSize="20dp"
        android:textColor="@color/colorPrimary"
        android:background="@color/colorAccent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="10dp" />

</LinearLayout>

定义一个SurfaceView对象并设置它的layout_width、layout_height属性为match_parent. 在布局文件中添加一个按钮对象,当您点击时它将启动拍照操作。

2.定义主活动

定义主活动来处理相机的逻辑。

public class CameraActivity extends AppCompatActivity {
    private Camera camera;
    private SurfaceView surfaceView;
    private Button buttonCapture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        surfaceView = findViewById(R.id.surface_view);
        buttonCapture = findViewById(R.id.button_capture);
        buttonCapture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                camera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        // 处理图片data,保存到文件等
                        // 拍完照后需要重新启动预览
                        camera.startPreview();
                    }
                });
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        startCamera();
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }

    private void startCamera() {
        camera = Camera.open();
        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(640, 480);
        parameters.setPictureSize(1280, 720);
        parameters.setPictureFormat(ImageFormat.JPEG);
        camera.setParameters(parameters);

        try {
            camera.setPreviewDisplay(surfaceView.getHolder());
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void releaseCamera() {
        if(camera != null) {
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }
}

3.许可请求

打开相机需要许可请求,对应代码如下:

private void requestPermission(){
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
    }else {
        startCamera();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startCamera();
        } else {
            Toast.makeText(this, "拒绝授权,无法使用相机", Toast.LENGTH_SHORT).show();
        }
    }
}

4.权限检查

检查权限的方法如下:

private boolean checkPermission(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
            return false;
        }
    } else {
        return true;
    }
}

然后在onCreate()中调用checkPermission()方法来检查相机权限并启动相机。

结论

以上是Android相机应用的开发过程,在Android的相机应用中,需要用到一些Camera API来实现。通过这些API,我们可以非常轻松地实现一个相机应用,但是需要注意应用的安全要求和用户体验。