diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7a1883f..42762a3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,12 @@
+
+
+
+
+
+
+ android:value="${MAPS_API_KEY}" />
-
+ android:exported="false" />
\ No newline at end of file
diff --git a/app/src/main/java/com/sample/otuslocationmapshw/MapsActivity.kt b/app/src/main/java/com/sample/otuslocationmapshw/MapsActivity.kt
index c063bfb..d20c60b 100644
--- a/app/src/main/java/com/sample/otuslocationmapshw/MapsActivity.kt
+++ b/app/src/main/java/com/sample/otuslocationmapshw/MapsActivity.kt
@@ -31,7 +31,7 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == CameraActivity.SUCCESS_RESULT_CODE) {
- // TODO("Обновить точки на карте при получении результата от камеры")
+ showPreviewsOnMap()
}
}
@@ -41,9 +41,8 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
binding = ActivityMapsBinding.inflate(layoutInflater)
setContentView(binding.root)
- val mapFragment = supportFragmentManager
- .findFragmentById(R.id.map) as SupportMapFragment
- // TODO("Вызвать инициализацию карты")
+ val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
+ mapFragment.getMapAsync(this)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -57,6 +56,7 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
cameraForResultLauncher.launch(Intent(this, CameraActivity::class.java))
true
}
+
else -> {
super.onOptionsItemSelected(item)
}
@@ -72,23 +72,24 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private fun showPreviewsOnMap() {
map.clear()
val folder = File("${filesDir.absolutePath}/photos/")
+ var lastPoint: LatLng? = null
folder.listFiles()?.forEach {
val exifInterface = ExifInterface(it)
val location = locationDataUtils.getLocationFromExif(exifInterface)
val point = LatLng(location.latitude, location.longitude)
+ lastPoint = point
val pinBitmap = Bitmap.createScaledBitmap(
BitmapFactory.decodeFile(
- it.path,
- BitmapFactory.Options().apply {
+ it.path, BitmapFactory.Options().apply {
inPreferredConfig = Bitmap.Config.ARGB_8888
}), 64, 64, false
)
- // TODO("Указать pinBitmap как иконку для маркера")
map.addMarker(
- MarkerOptions()
- .position(point)
+ MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromBitmap(pinBitmap))
)
- // TODO("Передвинуть карту к местоположению последнего фото")
+ lastPoint?.let {
+ map.animateCamera(CameraUpdateFactory.newLatLngZoom(it, 10f))
+ }
}
}
}
\ 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..df49487 100644
--- a/app/src/main/java/com/sample/otuslocationmapshw/camera/CameraActivity.kt
+++ b/app/src/main/java/com/sample/otuslocationmapshw/camera/CameraActivity.kt
@@ -26,6 +26,7 @@ import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
+import kotlin.invoke
import kotlin.math.abs
class CameraActivity : AppCompatActivity() {
@@ -58,9 +59,8 @@ class CameraActivity : AppCompatActivity() {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
cameraProviderFuture = ProcessCameraProvider.getInstance(this)
- // TODO("Получить экземпляр SensorManager")
- // TODO("Добавить проверку на наличие датчика акселерометра и присвоить значение tiltSensor")
- tiltSensor = TODO("Get tilt sensor")
+ sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
+ tiltSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
}, ContextCompat.getMainExecutor(this))
@@ -81,14 +81,24 @@ class CameraActivity : AppCompatActivity() {
}
}
- // TODO("Подписаться на получение событий обновления датчика")
+ override fun onResume() {
+ super.onResume()
+ tiltSensor?.let {
+ sensorManager.registerListener(
+ sensorEventListener,
+ it,
+ SensorManager.SENSOR_DELAY_UI
+ )
+ }
+ }
- // TODO("Остановить получение событий от датчика")
+ override fun onPause() {
+ super.onPause()
+ sensorManager.unregisterListener(sensorEventListener)
+ }
override fun onRequestPermissionsResult(
- requestCode: Int,
- permissions: Array,
- grantResults: IntArray
+ requestCode: Int, permissions: Array, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_PERMISSIONS) {
@@ -96,9 +106,7 @@ class CameraActivity : AppCompatActivity() {
startCamera()
} else {
Toast.makeText(
- this,
- "Permissions not granted by the user.",
- Toast.LENGTH_SHORT
+ this, "Permissions not granted by the user.", Toast.LENGTH_SHORT
).show()
finish()
}
@@ -115,21 +123,42 @@ class CameraActivity : AppCompatActivity() {
if (!folder.exists()) {
folder.mkdirs()
}
- val filePath = folderPath + SimpleDateFormat(FILENAME_FORMAT, Locale.getDefault()).format(Date())
+ val filePath =
+ folderPath + SimpleDateFormat(FILENAME_FORMAT, Locale.getDefault()).format(Date())
- // TODO("4. Добавить установку местоположения в метаданные фото")
- val outputFileOptions = ImageCapture.OutputFileOptions.Builder(File(filePath))
- .build()
-
- // TODO("Добавить вызов CameraX для фото")
- // TODO("Вывести Toast о том, что фото успешно сохранено и закрыть текущее активити c указанием кода результата SUCCESS_RESULT_CODE")
- // imageCapture...
+ val metadata = ImageCapture.Metadata().apply {
+ this.location = location
+ }
+ val outputFileOptions =
+ ImageCapture.OutputFileOptions.Builder(File(filePath)).setMetadata(metadata).build()
+
+ imageCapture.takePicture(
+ outputFileOptions,
+ ContextCompat.getMainExecutor(this),
+ object : ImageCapture.OnImageSavedCallback {
+ override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
+ Toast.makeText(baseContext, "Фото успешно сохранено", Toast.LENGTH_SHORT)
+ .show()
+ setResult(SUCCESS_RESULT_CODE)
+ finish()
+ }
+
+ override fun onError(exception: androidx.camera.core.ImageCaptureException) {
+ Log.e("CameraXApp", "Ошибка при съемке: ${exception.message}", exception)
+ Toast.makeText(baseContext, "Ошибка сохранения фото", Toast.LENGTH_SHORT)
+ .show()
+ }
+ })
}
}
@SuppressLint("MissingPermission")
private fun getLastLocation(callback: (location: Location?) -> Unit) {
- // TODO("Добавить получение местоположения от fusedLocationClient и передать результат в callback после получения")
+ fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
+ callback.invoke(location)
+ }.addOnFailureListener {
+ callback.invoke(null)
+ }
}
private fun startCamera() {
@@ -137,11 +166,9 @@ class CameraActivity : AppCompatActivity() {
cameraProviderFuture.addListener({
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
- val preview = Preview.Builder()
- .build()
- .also {
- it.setSurfaceProvider(binding.cameraPreview.surfaceProvider)
- }
+ val preview = Preview.Builder().build().also {
+ it.setSurfaceProvider(binding.cameraPreview.surfaceProvider)
+ }
imageCapture = ImageCapture.Builder().build()
@@ -168,9 +195,10 @@ 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("Добавить требуемые разрешения")
+ android.Manifest.permission.CAMERA,
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
).toTypedArray()
const val SUCCESS_RESULT_CODE = 15
diff --git a/build.gradle b/build.gradle
index 2938249..5e39d76 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,10 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ dependencies {
+ classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
+ }
+}
+
plugins {
id 'com.android.application' version '8.7.3' apply false
id 'com.android.library' version '8.7.3' apply false