From 942bc76a186207f5ee68588983319e227fd765e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B0=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=92=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Sat, 27 Sep 2025 19:24:34 +0300 Subject: [PATCH] activity 03 --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 10 +- .../activities/EditProfileActivity.kt | 152 +++++++++++++++++- .../homework/activities/FillFormActivity.kt | 40 +++++ .../homework/activities/FillFormContract.kt | 34 ++++ .../otus/gpb/homework/activities/UserInfo.kt | 11 ++ .../main/res/layout/activity_fill_form.xml | 60 +++++++ app/src/main/res/values/strings.xml | 5 + build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 10 files changed, 316 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/otus/gpb/homework/activities/FillFormActivity.kt create mode 100644 app/src/main/java/otus/gpb/homework/activities/FillFormContract.kt create mode 100644 app/src/main/java/otus/gpb/homework/activities/UserInfo.kt create mode 100644 app/src/main/res/layout/activity_fill_form.xml diff --git a/app/build.gradle b/app/build.gradle index 57688408..7f476125 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,10 +2,11 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id("io.gitlab.arturbosch.detekt") + id("org.jetbrains.kotlin.plugin.parcelize") } android { - compileSdk 34 + compileSdk 36 defaultConfig { applicationId "otus.gpb.homework.activities" @@ -60,4 +61,5 @@ dependencies { implementation 'androidx.activity:activity-ktx:1.9.0' implementation 'androidx.fragment:fragment-ktx:1.7.1' implementation 'com.squareup.picasso:picasso:2.71828' + implementation 'androidx.activity:activity:1.11.0' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e3d3319b..64469ed8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,12 @@ + + + + - + diff --git a/app/src/main/java/otus/gpb/homework/activities/EditProfileActivity.kt b/app/src/main/java/otus/gpb/homework/activities/EditProfileActivity.kt index d55ee922..78d0cd75 100644 --- a/app/src/main/java/otus/gpb/homework/activities/EditProfileActivity.kt +++ b/app/src/main/java/otus/gpb/homework/activities/EditProfileActivity.kt @@ -1,15 +1,145 @@ package otus.gpb.homework.activities +import android.Manifest +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri import android.os.Bundle +import android.provider.MediaStore +import android.provider.Settings +import android.util.Log +import android.widget.Button import android.widget.ImageView +import android.widget.TextView +import android.widget.Toast +import androidx.activity.result.PickVisualMediaRequest +import androidx.activity.result.contract.ActivityResultContracts +import androidx.activity.result.launch import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import java.io.ByteArrayOutputStream +import androidx.core.net.toUri class EditProfileActivity : AppCompatActivity() { private lateinit var imageView: ImageView + private var isSecondCameraAccessAttempt: Boolean = false + + private val choosePhotoDialog + get() = MaterialAlertDialogBuilder(this) + .setItems( + arrayOf( + resources.getString(R.string.take_photo), + resources.getString(R.string.choose_photo), + ) + ) { d, w -> + when (w) { + 0 -> { + Log.i("TAG", "Take photo") + requestCameraAccess() + if (ContextCompat.checkSelfPermission( + this, + Manifest.permission.CAMERA + ) == PackageManager.PERMISSION_GRANTED + ) { + takePhoto() + } + } + + 1 -> { + Log.i("TAG", "Choose photo") + selectPhoto() + } + } + }.create() + + private val requestCameraPermissionDialog + get() = MaterialAlertDialogBuilder(this) + .setMessage("Камера нужна для создания аватара") + .setPositiveButton(resources.getString(R.string.allow_access)) { d, w -> + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", packageName, null) + }.let { startActivity(it) } + } + .setNegativeButton(resources.getString(R.string.cancel)) { d, w -> + Log.i("TAG", "no access") + } + .create() + + private val requestCameraAccessLauncher = registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { isGranted -> + when { + isGranted -> setCatToImageView() + !shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> { + if (!isSecondCameraAccessAttempt) { + isSecondCameraAccessAttempt = true + requestCameraPermissionDialog.show() + } else { + MaterialAlertDialogBuilder(this) + .setPositiveButton(resources.getString(R.string.to_app_settings)) { d, w -> + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", packageName, null) + }.let { startActivity(it) } + }.show() + + } + } + + } + } + + private fun requestCameraAccess() { + requestCameraAccessLauncher.launch(Manifest.permission.CAMERA) + } + + private fun setCatToImageView() { + imageView.setImageDrawable( + ResourcesCompat.getDrawable(resources, R.drawable.cat, null) + ) + } + + fun getImageUriFromBitmap(context: Context, bitmap: Bitmap): Uri? { + val bytes = ByteArrayOutputStream() + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes) // Compress the bitmap to JPEG format + val path = MediaStore.Images.Media.insertImage(context.contentResolver, bitmap, "Image Title", null) + return path?.toUri() + } + + private val takePhoneLauncher = registerForActivityResult( + ActivityResultContracts.TakePicturePreview() + ) { picture -> + imageView.setImageBitmap(picture) + picture?.let { + imageView.tag = getImageUriFromBitmap(this,it) + } + } + + private fun takePhoto() = takePhoneLauncher.launch() + + private val selectPictureLauncher = registerForActivityResult( + ActivityResultContracts.PickVisualMedia() + ) { result -> + result?.let { populateImage(it) } + } + + private fun selectPhoto() = selectPictureLauncher.launch( + PickVisualMediaRequest( + ActivityResultContracts.PickVisualMedia.ImageOnly + ) + ) + + private val fillUserDataLauncher = registerForActivityResult(FillFormContract()) { userInfo -> + userInfo?.name?.let { findViewById(R.id.textview_name).text = it } + userInfo?.surName?.let { findViewById(R.id.textview_surname).text = it } + userInfo?.age?.let { findViewById(R.id.textview_age).text = it.toString() } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -28,6 +158,14 @@ class EditProfileActivity : AppCompatActivity() { } } } + + findViewById(R.id.imageview_photo).setOnClickListener { + choosePhotoDialog.show() + } + + findViewById