Android调用相机拍照录视频录音以及存储,7.0以上及以下都可使用

一、前言:

gitHub地址:https://gitee.com/luoyanyong/PhotoDemo

1. 在开头,先说一下在imageVIew中如何显示文件中存储的视频的第一帧的图片。很简单,几行代码就搞定。

    MediaMetadataRetriever media = new MediaMetadataRetriever();
                media.setDataSource(user.getPath());
                Bitmap bitmap = media.getFrameAtTime();

2. 下来,开始说拍照和存储视频,先在配置文件中声明一下provider,因为在安卓7.0以上想要存储必须要这个东西,没办法,写吧。

    <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="zj.it.bhne.gridengineeringsurvey.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>

3. meta-data中的file_paths就是自己建的一个xml文件。"."的意思时所有格式。

    <?xml version="1.0" encoding="utf-8"?>
    <paths >
        <external-path name="external_files" path="."/>
        <files-path name="my_images" path="images/"/>
        <root-path
            name="root_path"
            path="." />
    </paths>

效果图:


Screenshot_2019-12-09-15-38-26-387_com.sumansoul.photodemo.png

二、开始使用:

1. 录屏:

/**
     * 启动相机,创建文件,并要求返回uri
     */
    private void startVideo() {
        Intent intent = new Intent();
        //指定动作,启动相机
        intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        Log.d(TAG, "指定启动相机动作,完成。");
        //创建文件
        createVideoFile();
        Log.d(TAG, "创建视频文件结束。");
        //添加权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Log.d(TAG, "添加权限。");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //做一些处理
            //获取uri
            mVideoUri = FileProvider.getUriForFile(this, "zj.it.bhne.gridengineeringsurvey.fileprovider", mVideoFile);
        } else {
            //在版本低于此的时候,做一些处理
            mVideoUri = Uri.fromFile(mVideoFile);
        }
 
        Log.d(TAG, "根据视频文件路径获取uri。");
        //将uri加入到额外数据
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mVideoUri);
        Log.d(TAG, "将uri加入启动相机的额外数据。");
        Log.d(TAG, "启动相机...");
        //启动相机并要求返回结果
        startActivityForResult(intent, VIDEO_RESULT_CODE);
        Log.d(TAG, "拍摄中...");
    }
 
    /**
     * 创建视频文件
     */
    private void createVideoFile() {
        Log.d(TAG, "开始创建图片文件...");
        //设置图片文件名(含后缀),以当前时间的毫秒值为名称
        mVideoName = Calendar.getInstance().getTimeInMillis() + ".mp4";
        Log.d(TAG, "设置图片文件的名称为:"+mVideoName);
        //创建图片文件
        mVideoFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/bhne/" + getPath() + "/", mVideoName);
        //将图片的绝对路径设置给mImagePath,后面会用到
        mVideoPath = mVideoFile.getAbsolutePath();
        //按设置好的目录层级创建
        mVideoFile.getParentFile().mkdirs();
        Log.d(TAG, "按设置的目录层级创建图片文件,路径:"+mVideoPath);
        //不加这句会报Read-only警告。且无法写入SD
        mVideoFile.setWritable(true);
        Log.d(TAG, "将图片文件设置可写。");
    }

2. 拍照

/**
     * 启动相机,创建文件,并要求返回uri
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void startCamera() {
        Intent intent = new Intent();
        //指定动作,启动相机
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        Log.d(TAG, "指定启动相机动作,完成。");
        //创建文件
        createImageFile();
        Log.d(TAG, "创建图片文件结束。");
        //添加权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Log.d(TAG, "添加权限。");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //做一些处理
            //获取uri
            mImageUri = FileProvider.getUriForFile(this, "zj.it.bhne.gridengineeringsurvey.fileprovider", mImageFile);
        } else {
            //在版本低于此的时候,做一些处理
            mImageUri = Uri.fromFile(mImageFile);
        }
 
        Log.d(TAG, "根据图片文件路径获取uri。");
        //将uri加入到额外数据
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
        Log.d(TAG, "将uri加入启动相机的额外数据。");
        Log.d(TAG, "启动相机...");
        //启动相机并要求返回结果
        startActivityForResult(intent, PHOTO_RESULT_CODE);
        Log.d(TAG, "拍摄中...");
    }
 
 
    /**
     * 创建图片文件
     */
    private void createImageFile(){
        Log.d(TAG, "开始创建图片文件...");
        //设置图片文件名(含后缀),以当前时间的毫秒值为名称
        mImageName = Calendar.getInstance().getTimeInMillis() + ".jpg";
        Log.d(TAG, "设置图片文件的名称为:"+mImageName);
        //创建图片文件
        mImageFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/bhne/" + getPath() + "/", mImageName);
        //将图片的绝对路径设置给mImagePath,后面会用到
        mImagePath = mImageFile.getAbsolutePath();
        //按设置好的目录层级创建
        mImageFile.getParentFile().mkdirs();
        Log.d(TAG, "按设置的目录层级创建图片文件,路径:"+mImagePath);
        //不加这句会报Read-only警告。且无法写入SD
        mImageFile.setWritable(true);
        Log.d(TAG, "将图片文件设置可写。");
    }

3. 录音:

/**
     * 启动录音机,创建文件
     */
    private void startRecord() {
 
        Intent intent = new Intent();
        intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
        createVoiceFile();
        Log.d(TAG, "创建录音文件");
        //添加权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Log.d(TAG, "启动系统录音机,开始录音...");
        startActivityForResult(intent, VOICE_RESULT_CODE);
    }
 
    /**
     * 创建音频目录
     */
    private void createVoiceFile() {
        mVoiceName = getMyTime() + ".amr";
        Log.d(TAG, "录音文件名称:" + mVoiceName);
        mVoiceFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/" + SD_APP_DIR_NAME + "/" + VOICE_DIR_NAME + "/", mVoiceName);
        mVoicePath = mVoiceFile.getAbsolutePath();
        mVoiceFile.getParentFile().mkdirs();
        Log.d(TAG, "按设置的目录层级创建音频文件,路径:" + mVoicePath);
        mVoiceFile.setWritable(true);
    }
 
 
  /**
     * 获取日期并格式化
     * 如:2017_10_20 周三 上午 11:20:35
     *
     * @return 格式化好的日期字符串
     */
    private String getMyTime() {
        //存储格式化后的时间
        String time;
        //存储上午下午
        String ampTime = "";
        //判断上午下午,am上午,值为 0 ; pm下午,值为 1
        int apm = Calendar.getInstance().get(Calendar.AM_PM);
        if (apm == 0) {
            ampTime = "上午";
        } else {
            ampTime = "下午";
        }
        //设置格式化格式
        SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd E " + ampTime + " kk:mm:ss");
        time = format.format(new Date());
 
        return time;
    }
 
    /**
     * 保存音频到SD卡的指定位置
     *
     * @param path 录音文件的路径
     */
    private void saveVoiceToSD(String path) {
        //创建输入输出
        InputStream isFrom = null;
        OutputStream osTo = null;
        try {
            //设置输入输出流
            isFrom = new FileInputStream(path);
            osTo = new FileOutputStream(mVoicePath);
            byte bt[] = new byte[1024];
            int len;
            while ((len = isFrom.read(bt)) != -1) {
                Log.d(TAG, "len = " + len);
                osTo.write(bt, 0, len);
            }
            Log.d(TAG, "保存录音完成。");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (osTo != null) {
                try {
                    //不管是否出现异常,都要关闭流
                    osTo.close();
                    Log.d(TAG, "关闭输出流");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (isFrom != null) {
                try {
                    isFrom.close();
                    Log.d(TAG, "关闭输入流");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 
 
/**
     * 通过Uri,获取录音文件的路径(绝对路径)
     *
     * @param uri 录音文件的uri
     * @return 录音文件的路径(String)
     */
    private String getAudioFilePathFromUri(Uri uri) {
        Cursor cursor = getContentResolver()
                .query(uri, null, null, null, null);
        cursor.moveToFirst();
        int index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
        String temp = cursor.getString(index);
        cursor.close();
        return temp;
    }

4. 返回处理:

 /**
     * 处理返回结果。
     * 1、图片
     * 2、音频
     * 3、视频
     *
     * @param requestCode 请求码
     * @param resultCode  结果码 成功 -1 失败 0
     * @param data        返回的数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 
        super.onActivityResult(requestCode, resultCode, data);
 
//        Log.d(TAG, "拍摄结束。");
        Log.d(TAG, "录音结束。");
        if (resultCode == Activity.RESULT_OK) {
            Log.d(TAG, "返回成功。");
            Log.d(TAG, "请求码:" + requestCode + "  结果码:" + resultCode + "  data:" + data);
            switch (requestCode) {
                case PHOTO_RESULT_CODE: {
                    Bitmap bitmap = null;
                    try {
                        //根据uri设置bitmap
                        bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), mImageUri);
                        Log.d(TAG, "根据uri设置bitmap。");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //将图片保存到SD的指定位置
                    savePhotoToSD(bitmap);
                    //更新系统图库
                    updateSystemGallery();
                    Log.d(TAG, "结束。");
                    break;
                }
                case VOICE_RESULT_CODE: {
                    try {
                        Uri uri = data.getData();
                        String filePath = getAudioFilePathFromUri(uri);
                        Log.d(TAG, "根据uri获取文件路径:" + filePath);
                        Log.d(TAG, "开始保存录音文件");
                        saveVoiceToSD(filePath);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
 
                    break;
                }
                case VIDEO_RESULT_CODE: {
//                    saveVideoTOSD();
                    break;
                }
            }
        }
    }

三、完整代码:

1. SystemVideoActivity类

package com.sumansoul.photodemo.twoActivity;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;

import androidx.core.content.FileProvider;

import com.sumansoul.photodemo.CommonUtils;
import com.sumansoul.photodemo.R;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import butterknife.BindView;
import butterknife.ButterKnife;


/**
 * 支持拍照,拍视频
 */
public class SystemVideoActivity extends Activity {


    @BindView(R.id.btn1)
    Button btn1;
    @BindView(R.id.btn2)
    Button btn2;
    @BindView(R.id.btn3)
    Button btn3;
    @BindView(R.id.btn4)
    Button btn4;

    private Uri mVideoUri;
    private Uri mImageUri;
    private String TAG = "LUO";
    private File mVideoFile;
    private String mVideoPath;
    private String mVideoName;


    private String mImageName;
    private String mImagePath;
    private File mImageFile;
    /**
     * 拍照
     */
    private static int PHOTO_RESULT_CODE = 2;

    /**
     * 录视频
     */
    private static int VIDEO_RESULT_CODE = 1;

    private String mVoiceName;
    private String mVoicePath;

    /**
     * 录音
     */
    private static int VOICE_RESULT_CODE = 3;

    /**
     * 选择所有文件
     */
    private static int ALBUM = 4;

    private File mVoiceFile;

    /**
     * 系统选择的路径
     */
    private String selectPath;

    /**
     * 内容提供者和XML配置一样
     */
    String fileProvider = "com.sumansoul.photodemo.fileprovider";

    @SuppressLint("WrongViewCast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_system_video);
        ButterKnife.bind(this);


        /**
         * 拍照
         */
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startCamera();
            }
        });

        /**
         * 录像
         */
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startVideo();
            }
        });

        /**
         * 录音
         */
        btn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startRecord();
            }
        });
        /**
         * 从系统相册选择
         */
        btn4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setLocalPhoto();
            }
        });


    }

    /**
     * 相册
     */
    private void setLocalPhoto() {
        Intent albumIntent = new Intent(Intent.ACTION_PICK, null);
        // albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"*/*");
        // albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "video/*");
        startActivityForResult(albumIntent, ALBUM);
    }


    /**
     * 启动相机,创建文件,并要求返回uri
     */
    private void startVideo() {
        Intent intent = new Intent();
        //指定动作,启动相机
        intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        Log.d(TAG, "指定启动相机动作,完成。");
        //创建文件
        createVideoFile();
        Log.d(TAG, "创建视频文件结束。");
        //添加权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Log.d(TAG, "添加权限。");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //做一些处理
            //获取uri
            mVideoUri = FileProvider.getUriForFile(this, fileProvider, mVideoFile);
        } else {
            //在版本低于此的时候,做一些处理
            mVideoUri = Uri.fromFile(mVideoFile);
        }

        Log.d(TAG, "根据视频文件路径获取uri。");
        //将uri加入到额外数据
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mVideoUri);
        Log.d(TAG, "将uri加入启动相机的额外数据。");
        Log.d(TAG, "启动相机...");
        //启动相机并要求返回结果
        startActivityForResult(intent, VIDEO_RESULT_CODE);
        Log.d(TAG, "拍摄中...");
    }

    /**
     * 创建视频文件
     */
    private void createVideoFile() {
        Log.d(TAG, "开始创建图片文件...");
        //设置图片文件名(含后缀),以当前时间的毫秒值为名称
        mVideoName = Calendar.getInstance().getTimeInMillis() + ".mp4";
        Log.d(TAG, "设置图片文件的名称为:" + mVideoName);
        //创建图片文件
        mVideoFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/LUO/VIDEO/", mVideoName);
        //将图片的绝对路径设置给mImagePath,后面会用到
        mVideoPath = mVideoFile.getAbsolutePath();
        //按设置好的目录层级创建
        mVideoFile.getParentFile().mkdirs();
        Log.d(TAG, "按设置的目录层级创建图片文件,路径:" + mVideoPath);
        //不加这句会报Read-only警告。且无法写入SD
        mVideoFile.setWritable(true);
        Log.d(TAG, "将图片文件设置可写。");
    }


    /**
     * 启动相机,创建文件,并要求返回uri
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void startCamera() {
        Intent intent = new Intent();
        //指定动作,启动相机
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        Log.d(TAG, "指定启动相机动作,完成。");
        //创建文件
        createImageFile();
        Log.d(TAG, "创建图片文件结束。");
        //添加权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Log.d(TAG, "添加权限。");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //做一些处理
            //获取uri
            mImageUri = FileProvider.getUriForFile(this, fileProvider, mImageFile);
        } else {
            //在版本低于此的时候,做一些处理
            mImageUri = Uri.fromFile(mImageFile);
        }

        Log.d(TAG, "根据图片文件路径获取uri。");
        //将uri加入到额外数据
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
        Log.d(TAG, "将uri加入启动相机的额外数据。");
        Log.d(TAG, "启动相机...");
        //启动相机并要求返回结果
        startActivityForResult(intent, PHOTO_RESULT_CODE);
        Log.d(TAG, "拍摄中...");
    }


    /**
     * 创建图片文件
     */
    private void createImageFile() {
        Log.d(TAG, "开始创建图片文件...");
        //设置图片文件名(含后缀),以当前时间的毫秒值为名称
        mImageName = Calendar.getInstance().getTimeInMillis() + ".jpg";
        Log.d(TAG, "设置图片文件的名称为:" + mImageName);
        //创建图片文件
        mImageFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/LUO/IMAGE/", mImageName);
        //将图片的绝对路径设置给mImagePath,后面会用到
        mImagePath = mImageFile.getAbsolutePath();
        //按设置好的目录层级创建
        mImageFile.getParentFile().mkdirs();
        Log.d(TAG, "按设置的目录层级创建图片文件,路径:" + mImagePath);
        //不加这句会报Read-only警告。且无法写入SD
        mImageFile.setWritable(true);
        Log.d(TAG, "将图片文件设置可写。");
    }


    /**
     * 启动录音机,创建文件
     */
    private void startRecord() {

        Intent intent = new Intent();
        intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
        createVoiceFile();
        Log.d(TAG, "创建录音文件");
        //添加权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Log.d(TAG, "启动系统录音机,开始录音...");
        startActivityForResult(intent, VOICE_RESULT_CODE);
    }


    /**
     * 创建音频目录
     */
    private void createVoiceFile() {
        mVoiceName = getMyTime() + ".amr";
        Log.d(TAG, "录音文件名称:" + mVoiceName);
        mVoiceFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/LUO/VOICE/", mVoiceName);
        mVoicePath = mVoiceFile.getAbsolutePath();
        mVoiceFile.getParentFile().mkdirs();
        Log.d(TAG, "按设置的目录层级创建音频文件,路径:" + mVoicePath);
        mVoiceFile.setWritable(true);
    }


    /**
     * 获取日期并格式化
     * 如:2017_10_20 周三 上午 11:20:35
     *
     * @return 格式化好的日期字符串
     */
    private String getMyTime() {
        //存储格式化后的时间
        String time;
        //存储上午下午
        String ampTime = "";
        //判断上午下午,am上午,值为 0 ; pm下午,值为 1
        int apm = Calendar.getInstance().get(Calendar.AM_PM);
        if (apm == 0) {
            ampTime = "上午";
        } else {
            ampTime = "下午";
        }
        //设置格式化格式
        SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd E " + ampTime + " kk:mm:ss");
        time = format.format(new Date());

        return time;
    }

    /**
     * 保存音频到SD卡的指定位置
     *
     * @param path 录音文件的路径
     */
    private void saveVoiceToSD(String path) {
        //创建输入输出
        InputStream isFrom = null;
        OutputStream osTo = null;
        try {
            //设置输入输出流
            isFrom = new FileInputStream(path);
            osTo = new FileOutputStream(mVoicePath);
            byte bt[] = new byte[1024];
            int len;
            while ((len = isFrom.read(bt)) != -1) {
                Log.d(TAG, "len = " + len);
                osTo.write(bt, 0, len);
            }
            Log.d(TAG, "保存录音完成。");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (osTo != null) {
                try {
                    //不管是否出现异常,都要关闭流
                    osTo.close();
                    Log.d(TAG, "关闭输出流");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (isFrom != null) {
                try {
                    isFrom.close();
                    Log.d(TAG, "关闭输入流");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 通过Uri,获取录音文件的路径(绝对路径)
     *
     * @param uri 录音文件的uri
     * @return 录音文件的路径(String)
     */
    private String getAudioFilePathFromUri(Uri uri) {
        Cursor cursor = getContentResolver()
                .query(uri, null, null, null, null);
        cursor.moveToFirst();
        int index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
        String temp = cursor.getString(index);
        cursor.close();
        return temp;
    }


    /**
     * 处理返回结果。
     * 1、图片
     * 2、音频
     * 3、视频
     *
     * @param requestCode 请求码
     * @param resultCode  结果码 成功 -1 失败 0
     * @param data        返回的数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);


        if (resultCode == Activity.RESULT_OK) {
            Log.d(TAG, "返回成功。");
            Log.d(TAG, "请求码:" + requestCode + "  结果码:" + resultCode + "  data:" + data);

            if (requestCode == PHOTO_RESULT_CODE) {
                Bitmap bitmap = null;
                try {
                    //根据uri设置bitmap
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), mImageUri);
                    Log.d(TAG, "根据uri设置bitmap。");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Log.d(TAG, "结束。");
            } else if (requestCode == VOICE_RESULT_CODE) {
                try {
                    Uri uri = data.getData();
                    String filePath = getAudioFilePathFromUri(uri);
                    Log.d(TAG, "根据uri获取文件路径:" + filePath);
                    Log.d(TAG, "开始保存录音文件");
                    saveVoiceToSD(filePath);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }

            } else if (requestCode == VIDEO_RESULT_CODE) {

                Log.d(TAG, "拍摄结束。");
            } else if (requestCode == ALBUM) {
                //裁剪本地相册
                if (data != null && data.getData() != null) {
                    Uri data1 = data.getData();
                    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
                        selectPath = data1.toString();
                    } else {
                        selectPath = data1.getPath();
                    }
                    // Uri --> Path
                    if (selectPath.contains("content://")) {
                        selectPath = CommonUtils.getFilePathFromContentUri(data1, this.getContentResolver());
                    }
                    Log.d(TAG, "相册返回=====" + selectPath);

                }
            }


        }
    }
}

2. activity_system_video.XML

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


    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="30dp"
        android:text="拍照" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="30dp"
        android:text="录像" />

    <Button
        android:id="@+id/btn3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="30dp"
        android:text="录音" />

    <Button
        android:id="@+id/btn4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="30dp"
        android:text="选择系统相册" />
</LinearLayout>

3. manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.sumansoul.photodemo">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!--录音权限-->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />


    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <!--拍照使用 -->
        <provider
            android:name=".provider.CustfileProvider"
            android:authorities="com.sumansoul.photodemo.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>


        <activity android:name=".twoActivity.VideoActivity" />
        <activity android:name=".twoActivity.SystemVideoActivity" />
    </application>

</manifest>

参考链接:https://blog.csdn.net/haojiagou/article/details/81235574

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容