要创建一个Android相机应用程序,可以使用GLSurfaceView来显示相机预览。以下是一个包含代码示例的基本解决方案:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
implementation 'androidx.camera:camera-core:1.0.0-beta08'
implementation 'androidx.camera:camera-camera2:1.0.0-beta08'
implementation 'androidx.camera:camera-lifecycle:1.0.0-beta08'
implementation 'androidx.camera:camera-view:1.0.0-alpha28'
implementation 'androidx.camera:camera-extensions:1.0.0-alpha28'
implementation 'androidx.camera:camera-view:1.0.0-alpha28'
import android.Manifest
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
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 kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
class MainActivity : AppCompatActivity() {
private lateinit var imageCapture: ImageCapture
private lateinit var outputDirectory: File
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Request camera permissions
if (allPermissionsGranted()) {
startCamera()
} else {
ActivityCompat.requestPermissions(
this,
REQUIRED_PERMISSIONS,
REQUEST_CODE_PERMISSIONS
)
}
// Setup the directory where the captured images will be saved
outputDirectory = getOutputDirectory()
// Set up the listener for take photo button
btnTakePhoto.setOnClickListener { takePhoto() }
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
imageCapture = ImageCapture.Builder()
.build()
// Select back camera as the default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
cameraProvider.unbindAll()
// Bind the camera to the lifecycle
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
// Create a timestamped output file to hold the captured image
val photoFile = File(
outputDirectory,
SimpleDateFormat(
FILENAME_FORMAT, Locale.US
).format(System.currentTimeMillis()) + ".jpg")
// Create the output options object which contains the file + metadata
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
// Set up image capture listener, which is triggered after photo has
// been taken
imageCapture.takePicture(
outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e(TAG, "Photo capture failed: ${exc.message}", exc)