Android 知识要点整理(7)----拍照和录像

如果想要我们的APP具有拍照功能,有两种方式可以实现,一种是调用拍照APP,比如Android系统自带的Camera APP;另一种就是完全自己写,自己调用照相机的API,控制快门等,实现类似Camera APP的应用。第一种相对简单,第二种就比较复杂。如果我们的APP不是以拍照功能为主,我们就可以选择第一种简单的实现方式。下面就讲一讲第一种方式的重点知识。第二种方式暂时不讲。

1.声明照相机权限

如果APP有照相功能,首先要做的就是在AndroidManifest.xml中添加如下声明:

<uses-feature android:name="android.hardware.camera" android:required="true" />

虽然这不是必须的,但是这是一种推荐的做法。声明了这个之后,如果某个手机设备不支持拍照功能,那么它就不能安装这个APP。如果想要它即使没有摄像头也能安装,那么可以将required的值设置为false。这时候我们需要在代码中检测是否受摄像头,如果没有,需要禁用掉拍照模块。

if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
    photoBtn.setOnClickListener(this);
}else{
    photoBtn.setVisibility(View.GONE);
}

2.调起拍照APP

调起第三方拍照APP拍照的代码如下:

static final int REQUEST_IMAGE_CAPTURE = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }
}

需要注意的是,在调用startActivityForResult()方法之前需要先检查是否有第三方拍照的APP响应这个Intent,否则APP会崩溃。

3.获取缩略图

由于一张照片通常比较大,至少2M,所以Android 系统只会在拍照的返回结果Intent中存入拍摄的照片的缩略图,不会返回完整尺寸的照片。缩略图以Bitmap对象存储在Intent的“data”字段,可以用来当作icon等。如下是处理缩略图的代码:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        mImageView.setImageBitmap(imageBitmap);
        String desc = "缩略图信息:\n"+"w="+imageBitmap.getWidth()+"\nh="+imageBitmap.getHeight();
            mDescTv.setText(desc);
    }
}

4.获取完整尺寸的照片

我们如果想要获得拍摄的完整尺寸的照片,可以在发起拍照的Intent中传入要保存的照片的完整路径。
首先创建要保存的照片的临时文件:

private File createImageFile() throws IOException {
    // 使用当前时间命名文件,避免冲突
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    //存放在公共目录Pictures
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
   // 保存当前照片的完整路径,备用
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;
}

然后在Intent中传入路径:

File photoFile = null;
try {
    photoFile = createImageFile();
} catch (IOException e) {
    e.printStackTrace();
}
if(photoFile != null){
//设置保存照片的路径
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}

注意:如果指定了EXTRA_OUTPUT,那么onActivityResult(int requestCode, int resultCode, Intent data)的Intent data == null。

5.将照片添加到媒体库

虽然照片存储在了公共目录Pictures下,但是我们使用其它图库APP查看手机图片时却找不到我们刚刚拍摄的照片。这是因为我们还没有将他们添加到MediaProvider。我们需要主动调起系统MediaScanner,将照片添加到MediaProvider的数据库中。代码如下:

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

我们是通过发送一个广播消息来通知MediaScanner将指定的文件加入到媒体库中,这样其他的APP就可以通过MediaProvider访问到我们拍摄的照片了。当然,如果我们的照片存储在APP私有目录下(getExternalFileDirs),MediaScanner是没法扫描到的,上面的方法就没有作用了。

6.录制视频

同样,我们可以调起第三方APP来录制视频。我们也可以使用EXTRA_OUTPUT指定视频存储的位置。同时,在返回结果的Intent中通过getData可以获得视频的URI。关键代码如下:

private void dispatchTakeVideoIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

            File videoFile = null;
            try {
                videoFile = createMediaFile(".mp4");
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(videoFile != null){
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(videoFile));
                startActivityForResult(takePictureIntent, REQUEST_VIDEO_CAPTURE);
            }


        }
    }

得到视频的URI后,我们可以通过VideoView来播放视频。如下:

if(requestCode == REQUEST_VIDEO_CAPTURE){
    addFileToMedia();
    if (data == null) return;
    Uri videoUri = data.getData();
    Log.e("test", "data uri=>" + videoUri);
    if (videoUri != null) {
        mVideoView.setVideoURI(videoUri);
        mVideoView.start();
    }
}

以上就是拍照录像功能涉及到的一些比较重点的知识。

你可能感兴趣的:(android)