Android 多媒体应用——调用摄像头

本次分享的源码来源于《Android第一行代码》,最近在研究Android 多媒体应用方面的知识,所以在此整理了一下,也是对自己知识的一个巩固。

Android 第一行代码

前言

本篇 Demo 主要是实现两个功能:

  1. 点击 Button 调用摄像头进行拍照
  2. 将拍的照片显示在界面中

接下来,我们开始实战吧

1. Demo实现

1.1 设置布局

新建一个项目,名为:CameraApplication
activity_main.xml 中设置布局,布局中设置两个控件,一个是Button用于打开摄像头进行拍照,另一个是ImageView,主要用于将拍摄的照片展示出来。代码如下:

<?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:id="@+id/take_photo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Take Photo"
        />
    <ImageButton
        android:id="@+id/picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        />

</LinearLayout>

1.2 调用摄像头

MainActivity.java 中编写调用摄像头的逻辑,代码如下:

package com.xiaozeng.cameraapplication;
。。。
public class MainActivity extends AppCompatActivity {
    public static final int TAKE_PHOTO = 1;
    private ImageView picture;
    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button takePhoto = findViewById(R.id.take_photo);
        picture = findViewById(R.id.picture);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                第一步
                创建File对象,用于存储拍照后的照片,并将它存放在手机SD卡的应用关联缓存目录下。
                应用关联缓存目录:指SD卡中专门用于存放当前应用缓存数据的位置,调用getExternalCacheDir()方法可以得到该目录。
                具体的路径是/sdcard/Android/data/<package name>/cache .
                */
                File outputImage = new File(getExternalCacheDir(),"output_image.jpg");
                try {
                    if (outputImage.exists()){
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                }catch (Exception e){
                    e.printStackTrace();
                }
                /*
                第二步
                对当前运行设备的系统版本进行判断,低于Android7.0,就调用Uri.fromFile(outputImage);
                否则,就调用FileProvider的getUriForFile()方法
                  */
                if(Build.VERSION.SDK_INT >= 24 ){
                    imageUri = FileProvider.getUriForFile(MainActivity.this,
                            "com.xiaozeng.cameraapplication.fileprovider",outputImage);
                }else{
                    imageUri = Uri.fromFile(outputImage);
                }
                //启动相机程序
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                startActivityForResult(intent,TAKE_PHOTO);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case TAKE_PHOTO:
                if(resultCode == RESULT_OK){
                    //将拍摄的照片显示出来
                    try{
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        picture.setImageBitmap(bitmap);
                    }catch (FileNotFoundException e){
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }
}

解析:

  1. 总体逻辑:获取 Button和ImageView的实例,并给 Button 获取监听事件,并在button的点击事件中处理调用摄像头的逻辑。
  2. 首先创建了File对象,用于存放拍下的图片,
  3. 对当前运行的版本进行判断,因为从Android7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,
  4. 构建Intent对象,调用startActivityForResult 用于启动拍照程序。
  5. 拍完照之后会将结果返回到onActivityResult方法中,如果拍照成功,就调用BitmapFactory的decodeStream方法将照片解析成Bitmap对象,然后把他设置到 ImageView中显示出来。

1.3 注册内容提供器

AndroidManifest.xml 文件的标签中进行注册。代码如下:

<provider
    android:authorities="com.xiaozeng.cameraapplication.fileprovider"
    android:name="androidx.core.content.FileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
         android:name="android.support.FILE_PROVIDER_PATHS"
         android:resource="@xml/file_paths"/>
</provider>

在这里插入图片描述

1.4 新建资源共享路径

在第三步标签中的内部使用了来指定Uri的共享路径,并引用了 @xml/file_paths资源。该资源需要被创建
在res目录下——新建xml目录,再xml目录下——新建file_paths.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="my_images"
        path="/"
        />
</paths>

1.5 获取存储权限

AndroidManifest.xml 文件中添加访问SD卡的权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2. Demo展示

拍摄画面界面
在这里插入图片描述
图片展示界面
在这里插入图片描述

GitHub源码下载

https://github.com/Jenny-Zeng/AndroidStudyTest/tree/main/CameraApplication

行文仓促,认识有限,一直在学习的路上。欢迎讨论拍砖啊

  • 6
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小曾同学.com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值