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-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
androidTestImplementation 'androidx.test:core:1.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0'

@ -4,7 +4,6 @@
package="net.pokeranalytics.android">
<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.ACCESS_COARSE_LOCATION" />

@ -1,7 +1,6 @@
package net.pokeranalytics.android.model.realm
import android.content.Context
import android.net.Uri
import io.realm.Realm
import io.realm.RealmList
import io.realm.RealmObject
@ -32,9 +31,6 @@ open class Player : RealmObject(), NameManageable, Savable, Deletable, RowRepres
var picture: String? = null
var comments: RealmList<Comment> = RealmList()
@Ignore
var pictureUri: Uri? = null
@Ignore
override val realmObjectClass: Class<out Identifiable> = Player::class.java
@ -67,7 +63,7 @@ open class Player : RealmObject(), NameManageable, Savable, Deletable, RowRepres
when (row) {
PlayerPropertiesRow.NAME -> this.name = 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 val REQUIRED_PERMISSIONS =
mutableListOf (
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO
Manifest.permission.CAMERA
).apply {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@ -171,9 +170,9 @@ class CameraActivity : BaseActivity() {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val msg = "Photo capture succeeded: ${output.savedUri}"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Timber.d(msg)
// val msg = "Photo capture succeeded: ${output.savedUri}"
// Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
// Timber.d(msg)
val intent = Intent()
intent.putExtra(IMAGE_URI, output.savedUri.toString())

@ -9,6 +9,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
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 kotlinx.coroutines.Dispatchers
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.viewmodel.DataManagerViewModel
import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber
import java.io.File
/**
@ -93,6 +97,8 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
_binding = null
}
var pickVisualMediaRequest: ActivityResultLauncher<PickVisualMediaRequest>? = null
/**
* Init UI
*/
@ -110,6 +116,16 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
rowRepresentableAdapter.notifyDataSetChanged()
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>) {
@ -232,7 +248,10 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
// mediaActivity?.takePicture()
} // 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) -> {
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 {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return FilterDetailsViewModel(categoryRow, filter) as T
}

@ -2,10 +2,7 @@ package net.pokeranalytics.android.ui.view
import android.content.Context
import android.graphics.Color
import android.graphics.ImageDecoder
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.provider.MediaStore
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
@ -16,7 +13,6 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.getColor
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import androidx.core.net.toUri
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Player
@ -96,41 +92,13 @@ class PlayerImageView : FrameLayout {
// Picture
player.picture?.let { picture ->
Timber.d("picture = $picture")
val uri = picture.toUri()
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.playerImage.setImageURI(picture.toUri())
} ?: run { // no pic
this.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null)
this.playerImage.setImageDrawable(null)
this.playerInitial.text = player.initials
this.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
}
// 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
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">
<androidx.camera.view.PreviewView
android:id="@+id/viewFinder"
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:layout_width="110dp"
android:layout_height="110dp"
android:layout_marginBottom="50dp"
android:layout_marginEnd="50dp"
android:elevation="2dp"
android:src="@drawable/circle_border"
style="@style/PokerAnalyticsTheme.TransparentButton"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintEnd_toStartOf="@id/vertical_centerline" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/vertical_centerline"

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

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

Loading…
Cancel
Save