实现手机拍照手机录像与打开图库

本文详细介绍在Android系统中如何使用动态权限申请进行相机拍照、录制视频及从图库选取图片的操作。涵盖Android6.0以上版本的权限管理,通过隐式意图启动系统组件,并解析了SurfaceView与MediaPlayer在视频播放中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android简单照相机

涉及知识点
隐式跳转
动态申请权限
SurfaceView+MediaPlayer

动态申请权限打开摄像头打开图库在Android6.0以后需要动态申请权限
隐式意图一般情况下用于,两个应用程序的:组件(Activity,Service,…) 与 组件(Activity,Service,…) 的激活调用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">


     <Button
         android:text="拍照"
         android:id="@+id/btnCamera"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
    <Button
        android:text="摄像"
        android:id="@+id/btnVideo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:text="图库"
        android:id="@+id/btnimage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".VideoActivity">

    <SurfaceView
        android:id="@+id/sfv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>
package com.example.day05;

import android.Manifest;
import android.app.Notification;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Magnifier;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView imageView;
    private int REQUEST_PERMISSION_CODE = 100;
    final private int REQUEST_VIDEO_CODE = 300;//调用系统相机录像的request code 码
    final private int REQUEST_CAMERA_CODE = 200;//调用系统相机的request code 码
    final private int REQUEST_PHOTO_CODE = 400;//调用系统图库的request code 码
    private boolean grantResult = true;
    private String savewCanerapath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = findViewById(R.id.img);
        findViewById(R.id.btnCamera).setOnClickListener(this);
        findViewById(R.id.btnVideo).setOnClickListener(this);
        findViewById(R.id.btnimage).setOnClickListener(this);

        initPermission();

    }

    private void initPermission() {
        //判断当前安卓系统的版本是否大于或者等于6.0?需要动态申请相机和存储权限:清单文件申请权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //判断当前应用是否已经有了相机权限。
            int hasCameraPermisson = checkSelfPermission(Manifest.permission.CAMERA);
            int hasWiteStoragePemisson = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            int hasReadStoragePemisson = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);

            //如果不等于改值,表示当前应用不具备相机权限||不具备存储Sd卡权限||不具备读取Sd卡权限
            if (hasCameraPermisson != PackageManager.PERMISSION_GRANTED
                    || hasWiteStoragePemisson != PackageManager.PERMISSION_GRANTED
                    || hasReadStoragePemisson != PackageManager.PERMISSION_GRANTED) {

                requestMyPermission();
            }
        }
    }

    //开始申请权限
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void requestMyPermission() {
        //可以一次性申请多个权限.
        String permissions[] = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissions, REQUEST_PERMISSION_CODE);
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        //用来判断,这次回调,是否是我们申请权限的回调
        if (requestCode == REQUEST_PERMISSION_CODE) {

            for (int i = 0; i < grantResults.length; i++) {
                //代表有权限永不并没有同一同意
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    grantResult = false;
                    Toast.makeText(this, "用户并没有授权给应用设置头像", Toast.LENGTH_SHORT).show();
                }
            }
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnCamera:
                if (!grantResult)
                    Toast.makeText(this, "用户并没有授权给应用设置头像,请手动到设置菜单给应用设置权限", Toast.LENGTH_SHORT).show();
                else
                    takeCapture();
                break;
            case R.id.btnVideo:
                if (!grantResult)
                    Toast.makeText(this, "用户并没有授权给应用设置录像", Toast.LENGTH_SHORT).show();
                else
                    takeVideo();
                break;

            case R.id.btnimage:
                if (!grantResult)
                    Toast.makeText(this, "用户并没有授权给应用图库", Toast.LENGTH_SHORT).show();
                else
                    takePhtoto();
                break;
            default:
                break;
        }
    }

    //从系统图库中,读取一张图片
    private void takePhtoto() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_PICK);//隐式打开系统图库的UI.
        intent.setType("image/*");
        startActivityForResult(intent, REQUEST_PHOTO_CODE);
    }

    private void takeVideo() {
        Intent intent = new Intent();
        intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
        startActivityForResult(intent, REQUEST_VIDEO_CODE);
    }

    private void takeCapture() {
        savewCanerapath = getSaveCamerapath();
        File file = new File(savewCanerapath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdir();//如果存储照片的目录不存在,我们需要创建目录.
        }
        Intent intent = new Intent();
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//启动系统相机的Activity(隐式启动)

        //如果大哥前系统小于6.0,一种处理方式,大于或者等于是另一种处理方式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Uri uri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        } else {//大于或者等于6.0版本的处理方式
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.DATA, savewCanerapath);
            Uri mediaduri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, mediaduri);

        }
        //调用系统相机经行拍照
        startActivityForResult(intent, REQUEST_CAMERA_CODE);
    }

    //产生存储相机图片的路径,利用时间戳,可以确保文件名唯一
    private String getSaveCamerapath() {

        return Environment.getExternalStorageDirectory().getAbsolutePath() + "/demcaera/" + System.currentTimeMillis() + ".jpg";
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            Toast.makeText(this, "拍照失败", Toast.LENGTH_SHORT).show();
            return;
        } else {
            switch (requestCode) {

                case REQUEST_CAMERA_CODE:

                    Log.d("LQS", "拍照成功");
                    Bitmap bitmap = BitmapFactory.decodeFile(savewCanerapath);

                    imageView.setImageBitmap(bitmap);
                    break;
                case REQUEST_VIDEO_CODE:
                    Uri videoUri = data.getData();
                    String videoPath = null;
                    Cursor cursor = getContentResolver().query(videoUri, null, null, null, null, null);
                    while (cursor.moveToNext()) {
                        //循环找到最后一个路径是我们新录制的视频.
                        videoPath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));

                    }
                    cursor.close();
                    Intent intent = new Intent(MainActivity.this, VideoActivity.class);
                    intent.putExtra("video", videoPath);
                    startActivity(intent);

                    break;

                case REQUEST_PHOTO_CODE:
                    Uri uri = data.getData() ;//获取选择到的图片的Uri
                    imageView.setImageURI(uri);
                    break;

                default:
                    break;
            }
        }
    }
}

package com.example.day05;

import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

public class VideoActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private MediaPlayer mediaPlayer;
    private String videoPath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        videoPath = getIntent().getStringExtra("video");

        surfaceView = findViewById(R.id.sfv);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);


    }

    private void initMediaPlayer() {

        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDisplay(surfaceHolder);
        try {
            mediaPlayer.setDataSource(videoPath);

        } catch (IOException e) {
            e.printStackTrace();
        }
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mediaPlayer.start();
            }
        });
        mediaPlayer.prepareAsync();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        initMediaPlayer();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mediaPlayer.stop();
        mediaPlayer.release();
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

拍照和录像点击按钮就可以实现应该需要连接手机所以就没有演示效果啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值