0% found this document useful (0 votes)
26 views9 pages

23 Working With The Camera

The document describes the layout and functionality of an Android application that captures photos using the camera. It includes an XML layout file defining a button and image view, as well as a Kotlin activity file that manages camera permissions, captures images, and displays them. The application uses CameraX for image capture and requires camera permissions to function properly.

Uploaded by

ansamaan99
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views9 pages

23 Working With The Camera

The document describes the layout and functionality of an Android application that captures photos using the camera. It includes an XML layout file defining a button and image view, as well as a Kotlin activity file that manages camera permissions, captures images, and displays them. The application uses CameraX for image capture and requires camera permissions to function properly.

Uploaded by

ansamaan99
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Working with the activity_main.

xml file

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/black"

tools:context=".MainActivity">

<Button

android:id="@+id/camera_capture_button"

android:layout_width="120dp"

android:layout_height="120dp"

android:layout_marginBottom="50dp"

android:background="@drawable/capture_button"

android:elevation="2dp"

android:scaleType="fitCenter"

android:text="Capture Photo"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent" />

<ImageView

android:id="@+id/iv_capture"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_marginEnd="20dp"

android:layout_marginBottom="50dp"

android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintRight_toRightOf="parent" />

<androidx.camera.view.PreviewView

android:id="@+id/viewFinder"

android:layout_width="match_parent"

android:layout_height="450dp"

android:layout_marginStart="20dp"

android:layout_marginTop="20dp"

android:layout_marginEnd="20dp"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Create capture button drawable

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="oval">

<solid android:color="#0F9D58" />

<size

android:width="118dp"

android:height="118dp" />

</shape>

Working with the MainActivity.kt file

import android.Manifest

import android.content.pm.PackageManager

import android.net.Uri

import android.os.Bundle

import android.util.Log
import android.view.View

import android.widget.Button

import android.widget.ImageView

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 kotlinx.android.synthetic.main.activity_main.*

import java.io.File

import java.text.SimpleDateFormat

import java.util.*

import java.util.concurrent.ExecutorService

import java.util.concurrent.Executors

class MainActivity : AppCompatActivity() {

private var imageCapture: ImageCapture? = null

private lateinit var outputDirectory: File

private lateinit var cameraExecutor: ExecutorService

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

// hide the action bar

supportActionBar?.hide()
// Check camera permissions if all permission granted

// start camera else ask for the permission

if (allPermissionsGranted()) {

startCamera()

} else {

ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS,
REQUEST_CODE_PERMISSIONS)

// set on click listener for the button of capture photo

// it calls a method which is implemented below

findViewById<Button>(R.id.camera_capture_button).setOnClickListener {

takePhoto()

outputDirectory = getOutputDirectory()

cameraExecutor = Executors.newSingleThreadExecutor()

private fun takePhoto() {

// Get a stable reference of the

// modifiable image capture use case

val imageCapture = imageCapture ?: return

// Create time-stamped output file to hold the image

val photoFile = File(

outputDirectory,

SimpleDateFormat(FILENAME_FORMAT,
Locale.US).format(System.currentTimeMillis()) + ".jpg"

// Create output options object which contains 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)

override fun onImageSaved(output:


ImageCapture.OutputFileResults) {

val savedUri = Uri.fromFile(photoFile)

// set the saved uri to the image view

findViewById<ImageView>(R.id.iv_capture).visibility =
View.VISIBLE

findViewById<ImageView>(R.id.iv_capture).setImageURI(savedUri)

val msg = "Photo capture succeeded: $savedUri"

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

Log.d(TAG, msg)

})

private fun startCamera() {


val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

cameraProviderFuture.addListener(Runnable {

// Used to bind the lifecycle of cameras to the lifecycle owner

val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

// Preview

val preview = Preview.Builder()

.build()

.also {

it.setSurfaceProvider(viewFinder.createSurfaceProvider())

imageCapture = ImageCapture.Builder().build()

// Select back camera as a default

val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

try {

// Unbind use cases before rebinding

cameraProvider.unbindAll()

// Bind use cases to camera

cameraProvider.bindToLifecycle(

this, cameraSelector, preview, imageCapture

} catch (exc: Exception) {

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

}
}, ContextCompat.getMainExecutor(this))

private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {

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

// creates a folder inside internal storage

private fun getOutputDirectory(): File {

val mediaDir = externalMediaDirs.firstOrNull()?.let {

File(it, resources.getString(R.string.app_name)).apply { mkdirs() }

return if (mediaDir != null && mediaDir.exists())

mediaDir else filesDir

// checks the camera permission

override fun onRequestPermissionsResult(

requestCode: Int, permissions: Array<String>, grantResults:

IntArray

){

if (requestCode == REQUEST_CODE_PERMISSIONS) {

// If all permissions granted , then start Camera

if (allPermissionsGranted()) {

startCamera()

} else {

// If permissions are not granted,

// present a toast to notify the user that

// the permissions were not granted.


Toast.makeText(this, "Permissions not granted by the user.",
Toast.LENGTH_SHORT).show()

finish()

companion object {

private const val TAG = "CameraXGFG"

private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"

private const val REQUEST_CODE_PERMISSIONS = 20

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

override fun onDestroy() {

super.onDestroy()

cameraExecutor.shutdown()

OUTPUT:

You might also like