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() 方法允许我们异步处理用户的操作,获取操作结果并进行后续处理。

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

相关推荐
流浪的小新1 分钟前
【AI】人工智能、LLM学习资源汇总
人工智能·学习
A懿轩A1 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
云边有个稻草人1 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
南宫生9 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
拭心9 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
sanguine__9 小时前
Web APIs学习 (操作DOM BOM)
学习
冷眼看人间恩怨9 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
数据的世界0111 小时前
.NET开发人员学习书籍推荐
学习·.net
带电的小王11 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
四口鲸鱼爱吃盐11 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习