Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
id("io.gitlab.arturbosch.detekt")
}

android {
compileSdk 32
compileSdk 33

defaultConfig {
applicationId "otus.gpb.homework.activities"
minSdk 23
targetSdk 32
targetSdk 33
versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -53,7 +54,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.activity:activity-ktx:1.5.1'
implementation 'androidx.activity:activity-ktx:1.6.1'
implementation 'androidx.fragment:fragment-ktx:1.5.2'
implementation 'com.squareup.picasso:picasso:2.71828'
}
6 changes: 5 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
package="otus.gpb.homework.activities">

<uses-permission android:name="android.permission.CAMERA" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand All @@ -13,7 +15,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.Activities"
tools:targetApi="31">

<activity
android:name=".FillFormActivity"
android:exported="false" />
<activity
android:name=".EditProfileActivity"
android:exported="true">
Expand Down
142 changes: 140 additions & 2 deletions app/src/main/java/otus/gpb/homework/activities/EditProfileActivity.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,87 @@
package otus.gpb.homework.activities

import android.Manifest
import android.content.ActivityNotFoundException
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
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.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.appcompat.widget.Toolbar
import com.google.android.material.dialog.MaterialAlertDialogBuilder


class EditProfileActivity : AppCompatActivity() {

private val PERMISSION_REQUEST_CODE: Int = 200
private val REQUEST_CAMERA_STATE: Int = 0
private lateinit var imageView: ImageView
private lateinit var editProfileBtn: Button
private lateinit var pickedImageUri: Uri
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если здесь значения не будет, но кнопку отправки нажать, то будет краш

private var user = UserData("","","")

private val resultContract = registerForActivityResult(ActivityResultContracts.RequestPermission()){ granted ->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Rationale диалога не вижу
  2. Диалога перед тем как идти в настройки тоже не вижу
  3. У тебя в настройки ведет сразу после второго нажатия "Не давать разрешение", а должно вести в настройки

if(!granted)
{
if(!shouldShowRequestPermissionRationale(Manifest.permission.CAMERA))
{
MaterialAlertDialogBuilder(this)
.setTitle("Запрос разрешения")
.setMessage("Необходимо разрешение на использование камеры. Для этого перейдите в настройки.")
.setPositiveButton("Открыть настройки") { _, _ ->
val intent =
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
val uri = Uri.fromParts("package", packageName, null)
data = uri
}
startActivity(intent)
}
.show()
}
}
else
{
pickedImageUri = Uri.parse("android.resource://otus.gpb.homework.activities/" + R.drawable.cat)
populateImage(pickedImageUri)
}
}

private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
pickedImageUri = uri
populateImage(uri)
Log.d("PhotoPicker", "Selected URI: $uri")
} else {
Log.d("PhotoPicker", "No media selected")
}
}

private val fillFromActivity = registerForActivityResult(ProfileInfoContract()){ result->
findViewById<TextView>(R.id.textview_name).text = result?.getString("name")
findViewById<TextView>(R.id.textview_surname).text = result?.getString("surname")
findViewById<TextView>(R.id.textview_age).text = result?.getString("age")
user.name = result?.getString("name")
user.surname = result?.getString("surname")
user.age = result?.getString("age")
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_profile)
imageView = findViewById(R.id.imageview_photo)
editProfileBtn = findViewById(R.id.button4)

findViewById<Toolbar>(R.id.toolbar).apply {
inflateMenu(R.menu.menu)
Expand All @@ -28,7 +95,36 @@ class EditProfileActivity : AppCompatActivity() {
}
}
}
}

imageView.setOnClickListener{
val listItems = arrayOf("Сделать фото", "Выбрать фото")

MaterialAlertDialogBuilder(this)
.setTitle("Выберите действие")
.setItems(listItems,
DialogInterface.OnClickListener { dialogInterface, i ->
when (i) {
0->resultContract.launch(Manifest.permission.CAMERA)
1->pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
else->{
Toast.makeText(this, "No action", Toast.LENGTH_LONG).show()
}
}
})
.setNegativeButton(android.R.string.cancel) { dialog, which ->
// Respond to neutral button press
}
.setPositiveButton(android.R.string.ok) { dialog, which ->
// Respond to positive button press
resultContract.launch(Manifest.permission.CAMERA)
}
.show()
}

editProfileBtn.setOnClickListener {
fillFromActivity.launch("")
}
}

/**
* Используйте этот метод чтобы отобразить картинку полученную из медиатеки в ImageView
Expand All @@ -39,6 +135,48 @@ class EditProfileActivity : AppCompatActivity() {
}

private fun openSenderApp() {
TODO("В качестве реализации метода отправьте неявный Intent чтобы поделиться профилем. В качестве extras передайте заполненные строки и картинку")
//TODO("В качестве реализации метода отправьте неявный Intent чтобы поделиться профилем. В качестве extras передайте заполненные строки и картинку")

try {
val telegram = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, pickedImageUri)
putExtra(Intent.EXTRA_TEXT, "${user.name}\n${user.surname}\n${user.age}")
type = "image/*"
setPackage("org.telegram.messenger")
}

startActivity(telegram)
}
catch (e :ActivityNotFoundException) {
Toast.makeText(this, "Telegram app is not installed", Toast.LENGTH_LONG).show()
}
catch (e: Exception) {
Toast.makeText(this, "Не указаны необходимые данные", Toast.LENGTH_LONG).show()
}
}

private fun showRationaleDialog() {
val builder: AlertDialog.Builder = AlertDialog.Builder(this)
builder.setTitle(getString(R.string.rationale_title))
.setMessage(getString(R.string.rationale_desc))
.setNegativeButton("Отмена"){dialog, which->
}
.setPositiveButton("Дать доступ") { dialog, which ->
requestPermissions(arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_STATE)
}
builder.create().show()
}

override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)

if ((grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show()
} else {
showRationaleDialog()
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
}
}
}
41 changes: 41 additions & 0 deletions app/src/main/java/otus/gpb/homework/activities/FillFormActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package otus.gpb.homework.activities

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText

class FillFormActivity : AppCompatActivity() {

private lateinit var acceptBtn : Button
private lateinit var nameInput : EditText
private lateinit var surnameInput : EditText
private lateinit var ageInput : EditText

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fill_form)

acceptBtn = findViewById(R.id.accept_btn)
nameInput = findViewById(R.id.input_name)
surnameInput = findViewById(R.id.input_surname)
ageInput = findViewById(R.id.input_age)

acceptBtn.setOnClickListener{

val bundle = Bundle().apply {
putString("name", nameInput.text.toString())
putString("surname", surnameInput.text.toString())
putString("age", ageInput.text.toString())
}

val intent = Intent().apply {
putExtra("data", bundle)
}
setResult(Activity.RESULT_OK, intent)
finish()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package otus.gpb.homework.activities

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContract

class ProfileInfoContract : ActivityResultContract<String, Bundle?>(){

override fun createIntent(context: Context, input: String): Intent {
return Intent(context, FillFormActivity::class.java)
}

override fun parseResult(resultCode: Int, intent: Intent?): Bundle? {
if (intent == null || resultCode != Activity.RESULT_OK) return null

return intent.getBundleExtra("data")
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/otus/gpb/homework/activities/UserData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package otus.gpb.homework.activities

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class UserData(
var name: String?,
var surname: String?,
var age: String?
):Parcelable
46 changes: 46 additions & 0 deletions app/src/main/res/layout/activity_fill_form.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FillFormActivity">

<EditText
android:id="@+id/input_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="name"
android:layout_marginTop="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<EditText
android:id="@+id/input_surname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="surname"
app:layout_constraintBottom_toTopOf="@+id/input_age"
app:layout_constraintStart_toStartOf="@+id/input_name"
app:layout_constraintTop_toBottomOf="@+id/input_name" />

<EditText
android:id="@+id/input_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="age"
app:layout_constraintStart_toStartOf="@+id/input_surname"
app:layout_constraintTop_toBottomOf="@+id/input_surname" />

<Button
android:id="@+id/accept_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Применить"
android:layout_marginTop="104dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/input_age" />

</androidx.constraintlayout.widget.ConstraintLayout>
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<resources>
<string name="app_name">Activities</string>
<string name="title_send">Отправить</string>
<string name="rationale_title">We need permission to your camera</string>
<string name="rationale_desc">This app relies on access to your camera.
We require access to this permission to find your contacts in our database and suggest people you may know.
We will not store any contact info in our data base if they are not a part of our platform.
For further info read our privacy policy.</string>
</resources>
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.2.0' apply false
id 'com.android.library' version '7.2.0' apply false
id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
id 'com.android.application' version '7.2.2' apply false
id 'com.android.library' version '7.2.2' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
id "io.gitlab.arturbosch.detekt" version "1.21.0"
}

Expand Down