Android 调用手机相册,相机功能实现

学习笔记

学习笔记:实现相机和相册图片选择功能

在这篇学习笔记中,我们将详细介绍如何在 Android 应用中实现一个功能,允许用户通过相机拍照或从相册选择图片,并将选中的图片显示在应用界面上。这是一个常见的应用功能,可以用于用户头像上传、图片预览等场景。


1. 项目需求

我们需要实现一个功能,用户可以通过点击按钮选择两种操作:

  • 相册 中选择一张图片。
  • 使用 相机 拍摄一张新照片。

选中的图片将被显示在界面中的 ImageView 控件中。


2. 设计思路
  • 使用 Intent 来启动相册和相机的 Activity。
  • 使用 startActivityForResult() 来启动一个异步的操作,并且能够获取操作完成后的结果。
  • onActivityResult() 方法中处理返回的图片数据。
    • 对于相册选择的图片,我们获取图片的 URI。
    • 对于相机拍摄的图片,我们获取 Bitmap 数据。
  • 将获取到的图片数据显示在 ImageView 控件中。

3. 实现逻辑
3.1 视图绑定

使用 View Binding 来简化视图的绑定,使得代码更加简洁且易于维护。通过 ActivityXiangJiCeBinding,我们可以直接访问布局中的控件,如按钮和 ImageView

3.2 处理按钮点击事件

我们有两个按钮:一个是打开相册选择图片,另一个是打开相机拍照。

  • 打开相册 :点击按钮时,我们通过 Intent.ACTION_PICK 启动相册选择图片。
  • 打开相机 :点击按钮时,我们通过 MediaStore.ACTION_IMAGE_CAPTURE 启动相机拍照。
3.3 启动 Activity
  • 使用 startActivityForResult() 来启动相册或相机的 Activity,并传入请求码(REQUEST_PICK_IMAGEREQUEST_IMAGE_CAPTURE)。当操作完成后,系统会回调 onActivityResult() 方法,并将结果传递给我们。
3.4 处理返回的结果
  • 如果用户选择了相册中的图片,我们通过 getData() 获取图片的 URI。
  • 如果用户拍摄了照片,我们通过 getExtras() 获取 Bitmap 数据。
  • 将获取到的图片数据显示在 ImageView 中。

4. 代码实现
复制代码
java 复制代码
package com.example.practice;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import com.example.practice.databinding.ActivityXiangJiCeBinding;

public class XiangJiCeActivity extends AppCompatActivity {

    private ActivityXiangJiCeBinding binding;

    // 定义请求码常量,用于区分不同的请求
    private static final int REQUEST_IMAGE_CAPTURE = 1; // 拍照请求码
    private static final int REQUEST_PICK_IMAGE = 2; // 选择图片请求码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化 binding,绑定视图
        binding = ActivityXiangJiCeBinding.inflate(getLayoutInflater());
        // 设置视图
        setContentView(binding.getRoot());

        // 为相机按钮设置点击事件
        binding.xiangjiXiang.setOnClickListener(v -> {
            // 调用方法打开相册
            intixiangji();
        });

        // 为相册按钮设置点击事件
        binding.xaingcecXiang.setOnClickListener(v -> {
            // 调用方法打开相机
            intixiangce();
        });
    }

    // 打开相册方法
    private void intixiangji() {
        // 创建一个 Intent,用于打开设备的相册,选择图片
        Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

        // 启动相册 Activity 并期望返回结果
        startActivityForResult(galleryIntent, REQUEST_PICK_IMAGE);
    }

    // 打开相机方法
    private void intixiangce() {
        // 创建一个 Intent,用于打开设备的相机
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        // 确认设备上是否有可以处理相机启动的应用
        // 启动相机 Activity 并期望返回结果
        if (intent.resolveActivity(getPackageManager()) != null)
            startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }

    // 处理返回的结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // 如果返回的结果是成功的
        if (resultCode == RESULT_OK) {
            // 清除原来的背景
            binding.userphotoXiang.setBackground(null);  // 删除原来的背景

            // 判断请求码,来分别处理相机或相册返回的图片
            if (requestCode == REQUEST_IMAGE_CAPTURE) {
                // 如果是相机拍照返回的图片
                Bundle extras = data.getExtras();  // 获取返回的额外数据
                Bitmap imageBitmap = (Bitmap) extras.get("data");  // 获取图片的 Bitmap 数据

                // 将获取到的图片设置到 ImageView 中
                binding.userphotoXiang.setImageBitmap(imageBitmap);
            } else if (requestCode == REQUEST_PICK_IMAGE) {
                // 如果是从相册选择的图片
                Uri contentURI = data.getData();  // 获取图片的 URI

                // 将获取到的图片 URI 设置到 ImageView 中
                binding.userphotoXiang.setImageURI(contentURI);
            }
        }
    }
}

5. 代码解析
  • 视图绑定

    复制代码
    java 复制代码
    binding = ActivityXiangJiCeBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
  • 打开相册

    复制代码
    java 复制代码
    Intent galleryIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(galleryIntent, REQUEST_PICK_IMAGE);

    Intent.ACTION_PICK 用来打开相册,选择图片。REQUEST_PICK_IMAGE 用来标识这个请求。

  • 打开相机

    复制代码
    java 复制代码
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (intent.resolveActivity(getPackageManager()) != null)
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);

    MediaStore.ACTION_IMAGE_CAPTURE 用来启动相机拍照。resolveActivity() 确保设备上有可处理相机请求的应用。

  • 处理返回结果

    复制代码
    java 复制代码
    if (requestCode == REQUEST_IMAGE_CAPTURE) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        binding.userphotoXiang.setImageBitmap(imageBitmap);
    } else if (requestCode == REQUEST_PICK_IMAGE) {
        Uri contentURI = data.getData();
        binding.userphotoXiang.setImageURI(contentURI);
    }

    根据请求码判断返回的是相机拍照还是相册选择的图片,并将图片显示在 ImageView 控件中。


6. 总结

通过这篇学习笔记,我们学习了如何在 Android 中使用 Intent 来启动相机和相册并获取返回的图片。startActivityForResult()onActivityResult() 方法允许我们异步处理用户的操作,获取操作结果并进行后续处理。

此功能在许多应用中都很常见,学习了这些基本的图片选择和拍照功能后,你可以更进一步地扩展和优化这部分功能,例如裁剪图片、存储图片等。

相关推荐
CCCC13101631 小时前
嵌入式学习(day 28)线程
jvm·学习
安卓开发者2 小时前
Android RxJava 组合操作符实战:优雅处理多数据源
android·rxjava
星星火柴9362 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头2 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
阿华的代码王国2 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼2 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jerry说前后端2 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
艾莉丝努力练剑3 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
alexhilton3 小时前
深入浅出着色器:极坐标系与炫酷环形进度条
android·kotlin·android jetpack
武昌库里写JAVA4 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习