From 8f837b225954d61100fa934ed5be6d54ef35ee0a Mon Sep 17 00:00:00 2001 From: Ekaterina Leonidova Date: Sat, 22 Feb 2025 19:13:34 +0300 Subject: [PATCH] Homework 18 --- app/src/main/AndroidManifest.xml | 21 +++---- .../sample/otuslocationmapshw/MapsActivity.kt | 11 ++-- .../camera/CameraActivity.kt | 62 +++++++++++++++---- build.gradle | 4 +- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a1883f..1313d52 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,15 @@ + + + + + + + - + android:value="${MAPS_API_KEY}" /> + onMapReady(googleMap) + } } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -83,12 +85,13 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback { inPreferredConfig = Bitmap.Config.ARGB_8888 }), 64, 64, false ) - // TODO("Указать pinBitmap как иконку для маркера") + map.addMarker( MarkerOptions() .position(point) + .icon(BitmapDescriptorFactory.fromBitmap(pinBitmap)) ) - // TODO("Передвинуть карту к местоположению последнего фото") + map.moveCamera(CameraUpdateFactory.newLatLngZoom(point, 20f)) } } } \ No newline at end of file diff --git a/app/src/main/java/com/sample/otuslocationmapshw/camera/CameraActivity.kt b/app/src/main/java/com/sample/otuslocationmapshw/camera/CameraActivity.kt index 076ade5..b0ad10f 100644 --- a/app/src/main/java/com/sample/otuslocationmapshw/camera/CameraActivity.kt +++ b/app/src/main/java/com/sample/otuslocationmapshw/camera/CameraActivity.kt @@ -1,11 +1,15 @@ package com.sample.otuslocationmapshw.camera +import android.Manifest.permission.ACCESS_COARSE_LOCATION +import android.Manifest.permission.ACCESS_FINE_LOCATION +import android.Manifest.permission.CAMERA import android.annotation.SuppressLint import android.content.pm.PackageManager import android.hardware.Sensor import android.hardware.SensorEvent import android.hardware.SensorEventListener import android.hardware.SensorManager +import android.hardware.SensorManager.SENSOR_DELAY_UI import android.location.Location import android.os.Bundle import android.util.Log @@ -14,10 +18,12 @@ 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.google.android.gms.location.CurrentLocationRequest import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.google.common.util.concurrent.ListenableFuture @@ -58,9 +64,9 @@ class CameraActivity : AppCompatActivity() { fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) cameraProviderFuture = ProcessCameraProvider.getInstance(this) - // TODO("Получить экземпляр SensorManager") - // TODO("Добавить проверку на наличие датчика акселерометра и присвоить значение tiltSensor") - tiltSensor = TODO("Get tilt sensor") + sensorManager = getSystemService(SensorManager::class.java) + tiltSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) + cameraProviderFuture.addListener({ cameraProvider = cameraProviderFuture.get() }, ContextCompat.getMainExecutor(this)) @@ -81,9 +87,17 @@ class CameraActivity : AppCompatActivity() { } } - // TODO("Подписаться на получение событий обновления датчика") + override fun onResume() { + super.onResume() + if (tiltSensor == null) return + sensorManager.registerListener(sensorEventListener, tiltSensor, SENSOR_DELAY_UI) + } - // TODO("Остановить получение событий от датчика") + override fun onPause() { + super.onPause() + if (tiltSensor == null) return + sensorManager.unregisterListener(sensorEventListener) + } override fun onRequestPermissionsResult( requestCode: Int, @@ -117,19 +131,39 @@ class CameraActivity : AppCompatActivity() { } val filePath = folderPath + SimpleDateFormat(FILENAME_FORMAT, Locale.getDefault()).format(Date()) - // TODO("4. Добавить установку местоположения в метаданные фото") val outputFileOptions = ImageCapture.OutputFileOptions.Builder(File(filePath)) + .setMetadata(ImageCapture.Metadata().apply { this.location = location }) .build() - // TODO("Добавить вызов CameraX для фото") - // TODO("Вывести Toast о том, что фото успешно сохранено и закрыть текущее активити c указанием кода результата SUCCESS_RESULT_CODE") - // imageCapture... + imageCapture.takePicture( + outputFileOptions, + ContextCompat.getMainExecutor(this), + object : ImageCapture.OnImageSavedCallback { + override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) { + Toast.makeText( + this@CameraActivity, + "Photo is saved", + Toast.LENGTH_SHORT + ).show() + setResult(SUCCESS_RESULT_CODE) + finish() + } + + override fun onError(e: ImageCaptureException) { + Toast.makeText( + this@CameraActivity, + "Error: ${e.message}", + Toast.LENGTH_LONG + ).show() + } + }) } } @SuppressLint("MissingPermission") private fun getLastLocation(callback: (location: Location?) -> Unit) { - // TODO("Добавить получение местоположения от fusedLocationClient и передать результат в callback после получения") + fusedLocationClient.getCurrentLocation(CurrentLocationRequest.Builder().build(), null) + .addOnCompleteListener { callback.invoke(it.result) } } private fun startCamera() { @@ -168,9 +202,11 @@ class CameraActivity : AppCompatActivity() { private const val TAG = "CameraXApp" private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS" private const val REQUEST_CODE_PERMISSIONS = 10 - // TODO("Указать набор требуемых разрешений") - private val REQUIRED_PERMISSIONS: Array = mutableListOf( - // TODO("Добавить требуемые разрешения") + + private val REQUIRED_PERMISSIONS: Array = mutableListOf( + CAMERA, + ACCESS_FINE_LOCATION, + ACCESS_COARSE_LOCATION ).toTypedArray() const val SUCCESS_RESULT_CODE = 15 diff --git a/build.gradle b/build.gradle index 2938249..9fb51b5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '8.7.3' apply false - id 'com.android.library' version '8.7.3' apply false + id 'com.android.application' version '8.4.0' apply false + id 'com.android.library' version '8.4.0' apply false id 'org.jetbrains.kotlin.android' version '2.0.21' apply false id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false } \ No newline at end of file