android camera操作,Android使用CameraX快速预览和拍照

本文档展示了一个Android应用,使用CameraX库进行相机预览和拍照功能。首先检查并请求必要的权限,然后启动相机,创建Preview和ImageCapture实例,并将它们绑定到生命周期。当用户点击拍照按钮时,会保存图片到外部存储,并显示成功提示。

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

package com.yeyupiaoling.cameraxapp

import android.Manifest

import android.content.pm.PackageManager

import android.net.Uri

import android.os.Bundle

import android.util.Log

import android.widget.Toast

import androidx.appcompat.app.AppCompatActivity

import androidx.camera.core.CameraSelector

import androidx.camera.core.ImageCapture

import androidx.camera.core.ImageCaptureException

import androidx.camera.core.Preview

import androidx.camera.lifecycle.ProcessCameraProvider

import androidx.core.app.ActivityCompat

import androidx.core.content.ContextCompat

import com.blankj.utilcode.util.PathUtils

import kotlinx.android.synthetic.main.activity_main.*

import java.io.File

import java.util.concurrent.ExecutorService

import java.util.concurrent.Executors

class MainActivity : AppCompatActivity() {

private var imageCapture: ImageCapture? = null

private lateinit var cameraExecutor: ExecutorService

companion object {

private const val TAG = "MainActivity"

private const val REQUEST_CODE_PERMISSIONS = 10

private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)

}

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

// 请求权限 if (allPermissionsGranted()) {

startCamera()

} else {

ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)

}

// 点击拍照 camera_capture_button.setOnClickListener { takePhoto() }

cameraExecutor = Executors.newSingleThreadExecutor()

}

// 启动相机 private fun startCamera() {

val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

cameraProviderFuture.addListener(Runnable {

// 绑定生命周期 val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

// 预览 val preview = Preview.Builder()

.build()

.also {

it.setSurfaceProvider(viewFinder.createSurfaceProvider())

}

imageCapture = ImageCapture.Builder().build()

// 使用后摄像头 val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

try {

// 在重新绑定之前取消绑定用例 cameraProvider.unbindAll()

// 将用例绑定到摄像机 cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)

} catch (exc: Exception) {

Log.e(TAG, "Use case binding failed", exc)

}

}, ContextCompat.getMainExecutor(this))

}

// 拍照 private fun takePhoto() {

// 保证相机可用 val imageCapture = imageCapture ?: return

// 保存路径 val photoFile = File(PathUtils.getExternalAppPicturesPath(), "" + System.currentTimeMillis() + ".jpg")

// 创建包含文件和metadata的输出选项对象 val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()

// 设置图像捕获监听器,在拍照后触发 imageCapture.takePicture(

outputOptions,

ContextCompat.getMainExecutor(this),

object : ImageCapture.OnImageSavedCallback {

override fun onError(exc: ImageCaptureException) {

Log.e(TAG, "Photo capture failed: ${exc.message}", exc)

}

override fun onImageSaved(output: ImageCapture.OutputFileResults) {

val savedUri = Uri.fromFile(photoFile)

val msg = "拍照成功,保存路径: $savedUri"

Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()

Log.d(TAG, msg)

}

})

}

override fun onDestroy() {

super.onDestroy()

cameraExecutor.shutdown()

}

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {

ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED

}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {

if (requestCode == REQUEST_CODE_PERMISSIONS) {

if (allPermissionsGranted()) {

startCamera()

} else {

Toast.makeText(this, "没有授权!", Toast.LENGTH_SHORT).show()

finish()

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值