Adds image picking from library and fixes stuff

realmasync
Laurent 3 years ago
parent b0e88d08b1
commit 1c456ab796
  1. 4
      app/build.gradle
  2. 1
      app/src/main/AndroidManifest.xml
  3. 6
      app/src/main/java/net/pokeranalytics/android/model/realm/Player.kt
  4. 9
      app/src/main/java/net/pokeranalytics/android/ui/activity/components/CameraActivity.kt
  5. 21
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/PlayerDataFragment.kt
  6. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsViewModel.kt
  7. 36
      app/src/main/java/net/pokeranalytics/android/ui/view/PlayerImageView.kt
  8. 15
      app/src/main/res/drawable/circle_border.xml
  9. 21
      app/src/main/res/layout/activity_camera.xml
  10. 7
      app/src/main/res/layout/view_player_image.xml
  11. 7
      app/src/main/res/values/styles.xml

@ -151,6 +151,10 @@ dependencies {
implementation "androidx.camera:camera-view:${camerax_version}" implementation "androidx.camera:camera-view:${camerax_version}"
implementation "androidx.camera:camera-extensions:${camerax_version}" implementation "androidx.camera:camera-extensions:${camerax_version}"
// Image picking and registerForActivityResult
implementation 'androidx.activity:activity-ktx:1.6.1'
implementation "androidx.fragment:fragment-ktx:1.4.1"
// Instrumented Tests // Instrumented Tests
androidTestImplementation 'androidx.test:core:1.3.0' androidTestImplementation 'androidx.test:core:1.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test:runner:1.3.0'

@ -4,7 +4,6 @@
package="net.pokeranalytics.android"> package="net.pokeranalytics.android">
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

@ -1,7 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import android.content.Context import android.content.Context
import android.net.Uri
import io.realm.Realm import io.realm.Realm
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
@ -32,9 +31,6 @@ open class Player : RealmObject(), NameManageable, Savable, Deletable, RowRepres
var picture: String? = null var picture: String? = null
var comments: RealmList<Comment> = RealmList() var comments: RealmList<Comment> = RealmList()
@Ignore
var pictureUri: Uri? = null
@Ignore @Ignore
override val realmObjectClass: Class<out Identifiable> = Player::class.java override val realmObjectClass: Class<out Identifiable> = Player::class.java
@ -67,7 +63,7 @@ open class Player : RealmObject(), NameManageable, Savable, Deletable, RowRepres
when (row) { when (row) {
PlayerPropertiesRow.NAME -> this.name = value as String? ?: "" PlayerPropertiesRow.NAME -> this.name = value as String? ?: ""
PlayerPropertiesRow.SUMMARY -> this.summary = value as String? ?: "" PlayerPropertiesRow.SUMMARY -> this.summary = value as String? ?: ""
PlayerPropertiesRow.IMAGE -> this.pictureUri = value as? Uri PlayerPropertiesRow.IMAGE -> this.picture = value as? String
} }
} }

@ -39,8 +39,7 @@ class CameraActivity : BaseActivity() {
private const val REQUEST_CODE_PERMISSIONS = 10 private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = private val REQUIRED_PERMISSIONS =
mutableListOf ( mutableListOf (
Manifest.permission.CAMERA, Manifest.permission.CAMERA
Manifest.permission.RECORD_AUDIO
).apply { ).apply {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
add(Manifest.permission.WRITE_EXTERNAL_STORAGE) add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@ -171,9 +170,9 @@ class CameraActivity : BaseActivity() {
override fun onImageSaved(output: ImageCapture.OutputFileResults) { override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val msg = "Photo capture succeeded: ${output.savedUri}" // val msg = "Photo capture succeeded: ${output.savedUri}"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() // Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Timber.d(msg) // Timber.d(msg)
val intent = Intent() val intent = Intent()
intent.putExtra(IMAGE_URI, output.savedUri.toString()) intent.putExtra(IMAGE_URI, output.savedUri.toString())

@ -9,6 +9,9 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -33,6 +36,7 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rows.PlayerPropertiesRow import net.pokeranalytics.android.ui.view.rows.PlayerPropertiesRow
import net.pokeranalytics.android.ui.viewmodel.DataManagerViewModel import net.pokeranalytics.android.ui.viewmodel.DataManagerViewModel
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber
import java.io.File import java.io.File
/** /**
@ -93,6 +97,8 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
_binding = null _binding = null
} }
var pickVisualMediaRequest: ActivityResultLauncher<PickVisualMediaRequest>? = null
/** /**
* Init UI * Init UI
*/ */
@ -110,6 +116,16 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
rowRepresentableAdapter.notifyDataSetChanged() rowRepresentableAdapter.notifyDataSetChanged()
onRowSelected(-1, comment) onRowSelected(-1, comment)
} }
this.pickVisualMediaRequest = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
this.player.picture = uri.toString()
if (uri != null) {
Timber.d("Selected URI: $uri")
} else {
Timber.d("No media selected")
}
rowRepresentableAdapter.refreshRow(PlayerPropertiesRow.IMAGE)
}
} }
override fun getPhotos(files: ArrayList<File>) { override fun getPhotos(files: ArrayList<File>) {
@ -232,7 +248,10 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
// mediaActivity?.takePicture() // mediaActivity?.takePicture()
} // mediaActivity?.openImageCaptureIntent(false) } // mediaActivity?.openImageCaptureIntent(false)
getString(R.string.library) -> mediaActivity?.openImageGalleryIntent(false) getString(R.string.library) -> {
pickVisualMediaRequest?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
// mediaActivity?.openImageGalleryIntent(false)
getString(R.string.select_a_color) -> { getString(R.string.select_a_color) -> {
ColorPickerActivity.newInstanceForResult(this, REQUEST_CODE_PICK_COLOR) ColorPickerActivity.newInstanceForResult(this, REQUEST_CODE_PICK_COLOR)
} }

@ -15,7 +15,7 @@ import timber.log.Timber
class FilterDetailsViewModelFactory(var filter: Filter, private var categoryRow: FilterCategoryRow): ViewModelProvider.Factory { class FilterDetailsViewModelFactory(var filter: Filter, private var categoryRow: FilterCategoryRow): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T { override fun <T : ViewModel> create(modelClass: Class<T>): T {
return FilterDetailsViewModel(categoryRow, filter) as T return FilterDetailsViewModel(categoryRow, filter) as T
} }

@ -2,10 +2,7 @@ package net.pokeranalytics.android.ui.view
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.ImageDecoder
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.provider.MediaStore
import android.util.AttributeSet import android.util.AttributeSet
import android.util.TypedValue import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
@ -16,7 +13,6 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.getColor import androidx.core.content.ContextCompat.getColor
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import androidx.core.net.toUri import androidx.core.net.toUri
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Player import net.pokeranalytics.android.model.realm.Player
@ -96,41 +92,13 @@ class PlayerImageView : FrameLayout {
// Picture // Picture
player.picture?.let { picture -> player.picture?.let { picture ->
Timber.d("picture = $picture") Timber.d("picture = $picture")
this.playerImage.setImageURI(picture.toUri())
val uri = picture.toUri() } ?: run { // no pic
context?.contentResolver?.let { resolver ->
val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(resolver, uri))
} else {
MediaStore.Images.Media.getBitmap(resolver, uri)
}
val rDrawable = RoundedBitmapDrawableFactory.create(resources, bitmap)
rDrawable.isCircular = true
this.playerImage.setImageDrawable(rDrawable)
}
// player.picture?.let { pic ->
// pic.toUri().path?.let {
// val rDrawable = RoundedBitmapDrawableFactory.create(resources, it)
// rDrawable.isCircular = true
// this.playerImage.setImageDrawable(rDrawable)
// }
//
// this.playerImage.setImageURI(uri)
// }
} ?: run {
this.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null) this.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null)
this.playerImage.setImageDrawable(null) this.playerImage.setImageDrawable(null)
this.playerInitial.text = player.initials this.playerInitial.text = player.initials
this.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize()) this.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
} }
// Player color // Player color

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- <solid android:color="@color/black" />-->
<stroke android:color="@color/black" android:width="3dp"/>
<solid android:color="@color/white"/>
<size
android:width="80dp"
android:height="80dp"/>
</shape>

@ -2,24 +2,27 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.camera.view.PreviewView <androidx.camera.view.PreviewView
android:id="@+id/viewFinder" android:id="@+id/viewFinder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp" />
<Button <ImageButton
android:id="@+id/image_capture_button" android:id="@+id/image_capture_button"
android:layout_width="110dp" android:src="@drawable/circle_border"
android:layout_height="110dp" style="@style/PokerAnalyticsTheme.TransparentButton"
android:layout_marginBottom="50dp" android:layout_width="80dp"
android:layout_marginEnd="50dp" android:layout_height="80dp"
android:elevation="2dp" android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@id/vertical_centerline" /> app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Guideline <androidx.constraintlayout.widget.Guideline
android:id="@+id/vertical_centerline" android:id="@+id/vertical_centerline"

@ -18,12 +18,15 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="AH" /> tools:text="AH" />
<androidx.appcompat.widget.AppCompatImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/player_image" android:id="@+id/player_image"
app:shapeAppearanceOverlay="@style/roundedImageViewRounded"
android:scaleType="centerCrop"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1" android:background="@color/white"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />

@ -349,6 +349,13 @@
<item name="android:textSize">16sp</item> <item name="android:textSize">16sp</item>
</style> </style>
<!-- Image -->
<style name="roundedImageViewRounded">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
<!-- Button --> <!-- Button -->
<style name="PokerAnalyticsTheme.ToolbarButton" parent="Widget.MaterialComponents.Button"> <style name="PokerAnalyticsTheme.ToolbarButton" parent="Widget.MaterialComponents.Button">

Loading…
Cancel
Save