问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android实现调用摄像头和相册功能详解

创作时间:
作者:
@小白创作中心

Android实现调用摄像头和相册功能详解

引用
1
来源
1.
https://www.kdun.com/ask/1284104.html

在Android应用开发中,调用摄像头和相册是常见的功能需求。本文将详细介绍如何在Android应用中实现这两个功能,包括权限申请、界面设计以及代码实现。

权限申请

在Android 6.0(API级别23)及更高版本中,需要在运行时请求权限,以下是需要申请的权限列表:

权限名称
权限说明
android.permission.CAMERA
访问摄像头
android.permission.READ_EXTERNAL_STORAGE
读取外部存储中的图片
android.permission.WRITE_EXTERNAL_STORAGE
写入外部存储中的图片

在AndroidManifest.xml文件中声明权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cameraalbum">
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    ...
</manifest>

动态请求权限

在Activity中动态请求权限:

private static final int PERMISSION_REQUEST_CODE = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
    } else {
        // 权限已经授予,可以直接调用摄像头或相册
    }
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, grantResults);
    if (requestCode == PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限被授予,可以调用摄像头或相册
        } else {
            // 权限被拒绝,提示用户并关闭应用
            Toast.makeText(this, "权限被拒绝,无法使用摄像头和相册", Toast.LENGTH_SHORT).show();
            finish();
        }
    }
}

调用摄像头

创建布局文件

在res/layout/activity_main.xml中添加一个按钮用于启动摄像头:

<Button
    android:id="@+id/btn_take_photo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Take Photo" />

编写启动摄像头的逻辑

在MainActivity中编写启动摄像头的代码:

private Button btnTakePhoto;
private static final int REQUEST_IMAGE_CAPTURE = 1;
private String currentPhotoPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btnTakePhoto = findViewById(R.id.btn_take_photo);
    btnTakePhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dispatchTakePictureIntent();
        }
    });
}
private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
        }
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this, "com.example.cameraalbum.fileprovider", photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}
private File createImageFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(imageFileName, ".jpg", storageDir);
    currentPhotoPath = image.getAbsolutePath();
    return image;
}
@Override
protected void onActivityResult(int requestCode, resultCode, data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        // 在这里处理拍摄的照片,例如显示在 ImageView 上或保存到本地
    }
}

调用相册

创建布局文件

在res/layout/activity_main.xml中添加一个按钮用于启动相册:

<Button
    android:id="@+id/btn_choose_from_gallery"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Choose from Gallery" />

编写启动相册的逻辑

在MainActivity中编写启动相册的代码:

private Button btnChooseFromGallery;
private static final int PICK_IMAGE_REQUEST = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btnChooseFromGallery = findViewById(R.id.btn_choose_from_gallery);
    btnChooseFromGallery.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            openGallery();
        }
    });
}
private void openGallery() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, resultCode, data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
        Uri selectedImageUri = data.getData();
        // 在这里处理选择的图片,例如显示在 ImageView 上或保存到本地
    }
}

归纳

通过以上步骤,我们已经实现了Android应用中调用摄像头和相册的功能,需要注意的是,在实际开发中还需要处理各种异常情况,例如用户拒绝权限申请、设备没有摄像头等,还可以根据具体需求对拍摄和选择的照片进行进一步处理,如裁剪、压缩等,希望本文对您有所帮助!

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号