@@ -4,21 +4,32 @@ import android.content.ContentValues
44import android.content.Intent
55import android.graphics.Bitmap
66import android.graphics.Canvas
7+ import android.graphics.drawable.Drawable
8+ import android.os.Build
79import android.os.Bundle
810import android.os.Environment
911import android.provider.MediaStore.Images.Media
1012import android.util.Log
1113import android.view.View
1214import androidx.activity.viewModels
15+ import androidx.annotation.RequiresApi
1316import androidx.appcompat.app.AppCompatActivity
14- import androidx.appcompat.content.res.AppCompatResources
17+ import androidx.lifecycle.lifecycleScope
1518import com.bumptech.glide.Glide
19+ import com.bumptech.glide.load.DataSource
20+ import com.bumptech.glide.load.engine.GlideException
21+ import com.bumptech.glide.request.RequestListener
22+ import com.bumptech.glide.request.target.Target
1623import com.klee.sapio.R
1724import com.klee.sapio.data.EvaluationService
1825import com.klee.sapio.data.Rating
1926import com.klee.sapio.databinding.ActivityEvaluationsBinding
2027import com.klee.sapio.ui.viewmodel.AppEvaluationsViewModel
2128import dagger.hilt.android.AndroidEntryPoint
29+ import kotlinx.coroutines.flow.MutableSharedFlow
30+ import kotlinx.coroutines.flow.combine
31+ import kotlinx.coroutines.flow.launchIn
32+ import kotlinx.coroutines.launch
2233import java.io.IOException
2334
2435@AndroidEntryPoint
@@ -27,19 +38,28 @@ class EvaluationsActivity : AppCompatActivity() {
2738 private lateinit var mBinding: ActivityEvaluationsBinding
2839 private val mViewModel by viewModels<AppEvaluationsViewModel >()
2940
41+ private val microgUserReceived = MutableSharedFlow <Boolean >()
42+ private val microgRootReceived = MutableSharedFlow <Boolean >()
43+ private val bareAospUserReceived = MutableSharedFlow <Boolean >()
44+ private val bareAospRootReceived = MutableSharedFlow <Boolean >()
45+ private val iconReceived = MutableSharedFlow <Boolean >()
46+
3047 companion object {
3148 const val TAG = " EvaluationsActivity"
3249 const val NO_EVALUATION_CHAR = " "
3350 const val COMPRESSION_QUALITY = 100
51+ const val EXTRA_PACKAGE_NAME = " packageName"
52+ const val EXTRA_APP_NAME = " appName"
53+ const val EXTRA_SHARE_IMMEDIATELY = " shareImmediately"
3454 }
3555
56+ @RequiresApi(Build .VERSION_CODES .O )
3657 override fun onCreate (savedInstanceState : Bundle ? ) {
3758 super .onCreate(savedInstanceState)
3859
3960 mBinding = ActivityEvaluationsBinding .inflate(layoutInflater)
4061 setContentView(mBinding.root)
4162
42-
4363 mViewModel.microgUserEvaluation.observe(this ) {
4464 mBinding.microgUser.text = it?.let {
4565 Rating .create(it.rating).text
@@ -48,6 +68,10 @@ class EvaluationsActivity : AppCompatActivity() {
4868 mBinding.microgUser.tooltipText = it?.let {
4969 computeTooltip(it.rating)
5070 }
71+
72+ lifecycleScope.launch {
73+ microgUserReceived.emit(true )
74+ }
5175 }
5276
5377 mViewModel.microgRootEvaluation.observe(this ) {
@@ -58,6 +82,10 @@ class EvaluationsActivity : AppCompatActivity() {
5882 mBinding.microgRoot.tooltipText = it?.let {
5983 computeTooltip(it.rating)
6084 }
85+
86+ lifecycleScope.launch {
87+ microgRootReceived.emit(true )
88+ }
6189 }
6290
6391 mViewModel.bareAospUserEvaluation.observe(this ) {
@@ -68,6 +96,10 @@ class EvaluationsActivity : AppCompatActivity() {
6896 mBinding.bareAospUser.tooltipText = it?.let {
6997 computeTooltip(it.rating)
7098 }
99+
100+ lifecycleScope.launch {
101+ bareAospUserReceived.emit(true )
102+ }
71103 }
72104
73105 mViewModel.bareAsopRootEvaluation.observe(this ) {
@@ -78,18 +110,23 @@ class EvaluationsActivity : AppCompatActivity() {
78110 mBinding.bareAospRoot.tooltipText = it?.let {
79111 computeTooltip(it.rating)
80112 }
113+
114+ lifecycleScope.launch {
115+ bareAospRootReceived.emit(true )
116+ }
81117 }
82118
83119 mViewModel.iconUrl.observe(this ) {
84120 Glide .with (this .applicationContext)
85121 .load(EvaluationService .BASE_URL + it)
122+ .listener(glideListener)
86123 .into(mBinding.image)
87124 }
88125
89- val packageName = intent.getStringExtra(" packageName " ).toString()
126+ val packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME ).toString()
90127 mBinding.packageName.text = packageName
91128
92- val appName = intent.getStringExtra(" appName " ).toString()
129+ val appName = intent.getStringExtra(EXTRA_APP_NAME ).toString()
93130 mBinding.applicationName.text = appName
94131
95132 mBinding.shareButton.setOnClickListener {
@@ -102,6 +139,14 @@ class EvaluationsActivity : AppCompatActivity() {
102139 }
103140
104141 mViewModel.listEvaluations(packageName)
142+
143+ val shareImmediately = intent.getBooleanExtra(EXTRA_SHARE_IMMEDIATELY , false )
144+ if (shareImmediately) {
145+ combine(microgUserReceived, microgRootReceived, bareAospUserReceived,
146+ bareAospRootReceived, iconReceived) { _, _, _, _, _ ->
147+ share(takeScreenshot(mBinding.card), appName)
148+ }.launchIn(lifecycleScope)
149+ }
105150 }
106151
107152 private fun computeTooltip (rating : Int ): String {
@@ -126,10 +171,12 @@ class EvaluationsActivity : AppCompatActivity() {
126171 put(Media .DISPLAY_NAME , " screenshot_${System .currentTimeMillis()} " )
127172 put(Media .DESCRIPTION , " $appName Android Compatibility Matrix" )
128173 put(Media .MIME_TYPE , " image/jpeg" )
129- put(
130- Media .RELATIVE_PATH ,
131- " ${Environment .DIRECTORY_PICTURES } /${Environment .DIRECTORY_SCREENSHOTS } "
132- )
174+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
175+ put(
176+ Media .RELATIVE_PATH ,
177+ " ${Environment .DIRECTORY_PICTURES } /${Environment .DIRECTORY_SCREENSHOTS } "
178+ )
179+ }
133180 }
134181
135182 val imageUri =
@@ -156,4 +203,28 @@ class EvaluationsActivity : AppCompatActivity() {
156203
157204 startActivity(Intent .createChooser(shareIntent, " Share" ))
158205 }
206+
207+ private val glideListener = object : RequestListener <Drawable > {
208+ override fun onLoadFailed (
209+ e : GlideException ? ,
210+ model : Any? ,
211+ target : Target <Drawable >? ,
212+ isFirstResource : Boolean
213+ ): Boolean {
214+ TODO (" Not yet implemented" )
215+ }
216+
217+ override fun onResourceReady (
218+ resource : Drawable ? ,
219+ model : Any? ,
220+ target : Target <Drawable >? ,
221+ dataSource : DataSource ? ,
222+ isFirstResource : Boolean
223+ ): Boolean {
224+ lifecycleScope.launch {
225+ iconReceived.emit(true )
226+ }
227+ return false
228+ }
229+ }
159230}
0 commit comments