实现打开Android系统相册、照相机并实现照相,录像功能。

通过本篇博客,你将学到以下知识点: 
1.学会如何打开Android系统中相册的图片,视频,并使用这些图片,视频。 
2.学会如何打Android开照相机进行照相,录像,并使用这样图片和视频。 
下面我将展示两种方法来实现这些需求,注意:以下代码要用真机测试才行。 
一. 第一种方法: 

①.想顺利的打开Android手机中的相册和照相机,首先我们要在清单中注册一些权限:

 <!--使用相机硬件的权限-->
    <uses-permission android:name="android.permission.CAMERA"/>
    <!--录音的权限-->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--过滤不支持相机的设备-->
    <uses-feature android:name="android.hardware.Camera"/>


 
②.MainActivity的代码:
 

/**
 * 通过相机拍照返回的Bitmap有两种方式:
 * 1.不传入MediaStore.EXTRA_OUTPUT时,直接由data返回一个缩略图
 * 2.当传入MediaStore.EXTRA_OUTPUT时,可以通过设置的图片保存路径来获取完整图片
 */
public class MainActivity extends AppCompatActivity {

    private ImageView iv;

    private VideoView videoView;

    private final static int FLAG_REQUEST_SYSTEM_IMAGE = 0;

    private final static int FLAG_REQUEST_CAMERA_IMAGE = 1;

    private final static int FLAG_REQUEST_CAMERA_VIDEO = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
        videoView = (VideoView) findViewById(R.id.video);
    }

    public void doclick(View view) {
        switch (view.getId()) {
            case R.id.btn_pick_imager:
                // TODO 选取系统相册图片
                doPickImageFromSystem();
                break;
            case R.id.btn_open_pick_imager:
                // TODO 打开相机拍照
                doOpenCameraForImage();
                break;
            case R.id.btn_open_pick_video:
                // TODO 打开相机录像
                doOpenCameraForVideo();
                break;
        }
    }

    private void doPickImageFromSystem() {
        /**
         * 参数一:打开系统相册的ACTION
         * 参数二:返回数据的方式(从系统相册的数据库获取)
         */
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, FLAG_REQUEST_SYSTEM_IMAGE);
    }

    private void doOpenCameraForImage() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //todo 仅当设置了MediaStore.EXTRA_OUTPUT参数时,系统将不再返回缩略图,而是会被完整保存以下路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/test.jpg")));

        startActivityForResult(intent,FLAG_REQUEST_CAMERA_IMAGE);
    }

    private void doOpenCameraForVideo() {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/test.mp4")));
        startActivityForResult(intent, FLAG_REQUEST_CAMERA_VIDEO);
    }

    //TODO onActivityResul该方法根据requestCode返回码进行判断和处理数据
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //当结果码为RESULT_OK时,表示用户有效
        if (resultCode == RESULT_OK) {
            Log.i("info", "确认用户操作");
            switch (requestCode) {
                case FLAG_REQUEST_SYSTEM_IMAGE:
                    //TODO 处理从相册返回的图片数据
                    Uri uri = data.getData();//使用getData方法获取要调用的接口
                    //第二个参数表示要查询的数据的字段名
                    Cursor c = getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
                    if (c != null) {
                        c.moveToFirst();
                        //通过游标来获取名为MediaStore.Images.Media.DATA字段的值
                        String path = c.getString(c.getColumnIndex(MediaStore.Images.Media.DATA));
                        iv.setImageBitmap(BitmapFactory.decodeFile(path));
                    }
                    break;
                case FLAG_REQUEST_CAMERA_IMAGE:
                    //TODO 处理从相机返回的图片数据
                    if (data != null) {
                        Bitmap bm = data.getParcelableExtra("data");
                        iv.setImageBitmap(bm);
                    } else {
                        Bitmap bm = BitmapFactory.decodeFile("/sdcard/test.jpg");
                        iv.setImageBitmap(bm);
                    }
                    break;
                case FLAG_REQUEST_CAMERA_VIDEO:
                    //TODO 处理从相机返回的视频数据
                    videoView.setVideoURI(Uri.parse("/sdcard/test.mp4"));
                    videoView.start();
                    break;
            }
        } else {
            Log.i("info", "取消用户操作");
        }
    }
}
 


 
③布局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/btn_pick_imager"
        android:onClick="doclick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选取系统相册"/>
    <Button
        android:id="@+id/btn_open_pick_imager"
        android:onClick="doclick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开相机拍照"/>
    <Button
        android:id="@+id/btn_open_pick_video"
        android:onClick="doclick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开相机录像"
       />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:id="@+id/iv"/>
    <VideoView
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:id="@+id/video"/>
</LinearLayout>

第二种方法:这种方法主要是使用CameraUtils这个工具类,因为这个工具类封装了这些繁琐的方法,有了这个工具类,代码量将减少很多,想实现这些业务的话只要调用CameraUtils这个工具类即可。 

①。第一步还是注册权限:

 <!--使用相机硬件的权限-->
    <uses-permission android:name="android.permission.CAMERA"/>
    <!--录音的权限-->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--过滤不支持相机的设备-->
    <uses-feature android:name="android.hardware.Camera"/>


②MainActivity的代码:

/**
 * 通过相机拍照返回的Bitmap有两种方式:
 * 1.不传入MediaStore.EXTRA_OUTPUT时,直接由data返回一个缩略图
 * 2.当传入MediaStore.EXTRA_OUTPUT时,可以通过设置的图片保存路径来获取完整图片
 */
public class MainActivity extends AppCompatActivity {

    private ImageView iv;

    private VideoView videoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
        videoView = (VideoView) findViewById(R.id.video);
    }

    public void doClick(View view) {
        switch (view.getId()) {
            case R.id.btn_pick_image:
                // TODO 选取系统相册图片
                doPickImageFromSystem();
                break;
            case R.id.btn_open_camera_for_image:
                // TODO 打开相机拍照
                doOpenCameraForImage();
                break;
            case R.id.btn_open_camera_for_video:
                // TODO 打开相机录像
                doOpenCameraForVideo();
                break;
        }
    }

    private void doPickImageFromSystem() {
        /**
         * 参数一:打开系统相册的ACTION
         * 参数二:返回数据的方式(从系统相册的数据库获取)
         */
        CameraUtils.pickImageFromSystem(this);
    }

    private void doOpenCameraForImage() {

        CameraUtils.openCameraForImage(this);
    }

    private void doOpenCameraForVideo() {

        CameraUtils.openCameraForVideo(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //当结果码为RESULT_OK时,表示用户有效
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case CameraUtils.RequestCode.FLAG_REQUEST_SYSTEM_IMAGE:

                    String path = CameraUtils.getImagePathFromSystem(this, data);
                    if (path != null) {
                        iv.setImageBitmap(BitmapFactory.decodeFile(path));
                    }
                    break;
                case CameraUtils.RequestCode.FLAG_REQUEST_CAMERA_IMAGE:
                    //TODO 处理从相机返回的图片数据
                    if (data != null) {
                        Bitmap bm = data.getParcelableExtra("data");

                        iv.setImageBitmap(bm);
                    } else {
                        Bitmap bm = BitmapFactory.decodeFile(CameraUtils.CAMERA_IMAGE);
                        iv.setImageBitmap(bm);
                    }

                    break;
                case CameraUtils.RequestCode.FLAG_REQUEST_CAMERA_VIDEO:
                    //TODO 处理从相机返回的视频数据
                    videoView.setVideoURI(data.getData());
                    videoView.start();
                    break;
            }
        } else {
            Log.i("info", "取消用户操作");
        }
    }
} 

 
③.CameraUtils工具类的代码:

public class CameraUtils
{
    public static final String CAMERA_IMAGE = "/sdcard/test.jpg";

    public static final String CAMERA_VIDEO = "/sdcard/test.mp4";

    public static void pickImageFromSystem(Activity activity)
    {
        /**
         * 参数一:打开系统相册的ACTION 参数二:返回数据的方式(从系统相册的数据库获取)
         */
        Intent intent = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        activity.startActivityForResult(intent,
                RequestCode.FLAG_REQUEST_SYSTEM_IMAGE);
    }

    public static String getImagePathFromSystem(Activity activity, Intent data)
    {
        // TODO 处理从相册返回的图片数据
        Uri uri = data.getData();// 使用getData方法获取要调用的接口
        // 第二个参数表示要查询的数据的字段名
        Cursor c = activity.getContentResolver().query(uri,
                new String[]{MediaStore.Images.Media.DATA}, null, null, null);
        if (c != null)
        {
            c.moveToFirst();
            // 通过游标来获取名为MediaStore.Images.Media.DATA字段的值
            String path = c.getString(c
                    .getColumnIndex(MediaStore.Images.Media.DATA));
            return path;
        }
        return null;
    }

    public static void openCameraForImage(Activity activity)
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 仅当设置了MediaStore.EXTRA_OUTPUT参数时,系统将不再返回缩略图,而是会被完整保存以下路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(CAMERA_IMAGE)));
        activity.startActivityForResult(intent,
                CameraUtils.RequestCode.FLAG_REQUEST_CAMERA_IMAGE);
    }

    public static void openCameraForVideo(Activity activity)
    {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        // 仅当设置了MediaStore.EXTRA_OUTPUT参数时,系统将不再返回缩略图,而是会被完整保存以下路径
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(CAMERA_VIDEO)));
        activity.startActivityForResult(intent,
                RequestCode.FLAG_REQUEST_CAMERA_VIDEO);
    }

    public interface RequestCode
    {
        int FLAG_REQUEST_SYSTEM_IMAGE = 0;

        int FLAG_REQUEST_CAMERA_IMAGE = 1;

        int FLAG_REQUEST_CAMERA_VIDEO = 2;
    }
}

 
④.布局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/btn_pick_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="doClick"
        android:text="选取系统相册图片" />

    <Button
        android:id="@+id/btn_open_camera_for_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="doClick"
        android:text="打开相机拍照" />

    <Button
        android:id="@+id/btn_open_camera_for_video"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="doClick"
        android:text="打开相机录像" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="120dp" />

    <VideoView
        android:id="@+id/video"
        android:layout_width="match_parent"
        android:layout_height="200dp" />
</LinearLayout>

--------------------- 
作者:Allen-华 
来源:CSDN 
原文:https://blog.csdn.net/carry_code/article/details/51615205 
 

猜你喜欢

转载自blog.csdn.net/danwuxie/article/details/84349240
今日推荐