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

Posted znapast

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 知识要点整理----拍照和录像相关的知识,希望对你有一定的参考价值。

如果想要我们的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 知识要点整理----拍照和录像的主要内容,如果未能解决你的问题,请参考以下文章

Android CameraX 仿一甜相机(录像拍照可调节尺寸聚焦照明网格线),最全的CameraX教程

Android知识要点整理----Bitmap图片处理和展示

Android 开发 Camera类的拍照与录像

Android 知识要点整理(12)----Animation(动画)

android R 无法调起拍照录像问题

Android知识要点整理(21)----Gradle 之创建任务和插件