Skip to content

Commit 831385b

Browse files
authored
Add menu to test app for selecting feedback trigger (#4150)
* Add menu to test app for selecting feedback trigger * Address Kai's feedback
1 parent feab0b3 commit 831385b

File tree

8 files changed

+192
-56
lines changed

8 files changed

+192
-56
lines changed

firebase-appdistribution/test-app/src/main/java/com/googletest/firebase/appdistribution/testapp/AppDistroTestApplication.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import android.app.Application
55
class AppDistroTestApplication : Application() {
66
override fun onCreate() {
77
super.onCreate()
8-
ShakeForFeedback.enable(this)
8+
9+
// Default feedback triggers can also be initialized here
10+
// ShakeForFeedback.enable(this)
911
}
1012
}

firebase-appdistribution/test-app/src/main/java/com/googletest/firebase/appdistribution/testapp/MainActivity.kt

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ import android.os.Bundle
77
import android.os.Handler
88
import android.os.HandlerThread
99
import android.util.Log
10+
import android.view.Menu
11+
import android.view.MenuInflater
12+
import android.view.MenuItem
1013
import android.view.View
14+
import android.widget.ArrayAdapter
15+
import android.widget.AutoCompleteTextView
1116
import android.widget.ProgressBar
1217
import android.widget.TextView
1318
import androidx.appcompat.app.AppCompatActivity
1419
import androidx.appcompat.widget.AppCompatButton
20+
import androidx.core.widget.doOnTextChanged
1521
import com.google.android.gms.tasks.Task
22+
import com.google.android.material.textfield.TextInputLayout
1623
import com.google.firebase.appdistribution.AppDistributionRelease
1724
import com.google.firebase.appdistribution.UpdateProgress
1825
import com.google.firebase.appdistribution.ktx.appDistribution
@@ -36,34 +43,33 @@ class MainActivity : AppCompatActivity() {
3643
lateinit var signOutButtonBackground: AppCompatButton
3744
lateinit var checkForUpdateButtonBackground: AppCompatButton
3845
lateinit var updateAppButtonBackground: AppCompatButton
39-
lateinit var feedbackButton: AppCompatButton
40-
lateinit var progressPercentage: TextView
46+
lateinit var secondActivityButton: AppCompatButton
4147
lateinit var signInStatus: TextView
4248
lateinit var progressPercent: TextView
4349
lateinit var progressBar: ProgressBar
50+
lateinit var feedbackTriggerMenu: TextInputLayout
4451

4552
private lateinit var screenshotTriggerThread: HandlerThread
4653
private lateinit var screenshotTrigger: ScreenshotDetectionFeedbackTrigger
4754

4855
override fun onCreate(savedInstanceState: Bundle?) {
4956
super.onCreate(savedInstanceState)
5057
setContentView(R.layout.activity_main)
51-
signInButton = findViewById<AppCompatButton>(R.id.sign_in_button)
52-
signOutButton = findViewById<AppCompatButton>(R.id.sign_out)
53-
checkForUpdateButton = findViewById<AppCompatButton>(R.id.check_for_update)
54-
updateAppButton = findViewById<AppCompatButton>(R.id.update_app)
55-
updateIfNewReleaseAvailableButton = findViewById<AppCompatButton>(R.id.basic_config)
58+
signInButton = findViewById(R.id.sign_in_button)
59+
signOutButton = findViewById(R.id.sign_out)
60+
checkForUpdateButton = findViewById(R.id.check_for_update)
61+
updateAppButton = findViewById(R.id.update_app)
62+
updateIfNewReleaseAvailableButton = findViewById(R.id.basic_config)
5663
updateIfNewReleaseAvailableButtonBackground =
57-
findViewById<AppCompatButton>(R.id.basic_config2)
58-
signInButtonBackground = findViewById<AppCompatButton>(R.id.sign_in_button2)
59-
signOutButtonBackground = findViewById<AppCompatButton>(R.id.sign_out2)
60-
checkForUpdateButtonBackground = findViewById<AppCompatButton>(R.id.check_for_update2)
61-
updateAppButtonBackground = findViewById<AppCompatButton>(R.id.update_app2)
62-
feedbackButton = findViewById<AppCompatButton>(R.id.feedbackButton)
63-
progressPercentage = findViewById<TextView>(R.id.progress_percentage)
64-
signInStatus = findViewById<TextView>(R.id.sign_in_status)
65-
progressPercent = findViewById<TextView>(R.id.progress_percentage)
66-
progressBar = findViewById<ProgressBar>(R.id.progress_bar)
64+
findViewById(R.id.basic_config2)
65+
signInButtonBackground = findViewById(R.id.sign_in_button2)
66+
signOutButtonBackground = findViewById(R.id.sign_out2)
67+
checkForUpdateButtonBackground = findViewById(R.id.check_for_update2)
68+
updateAppButtonBackground = findViewById(R.id.update_app2)
69+
secondActivityButton = findViewById(R.id.secondActivityButton)
70+
progressPercent = findViewById(R.id.progress_percentage)
71+
signInStatus = findViewById(R.id.sign_in_status)
72+
progressBar = findViewById(R.id.progress_bar)
6773

6874
screenshotTriggerThread = HandlerThread("AppDistroFeedbackTrigger")
6975
screenshotTriggerThread.start()
@@ -73,6 +79,43 @@ class MainActivity : AppCompatActivity() {
7379
R.string.terms_and_conditions,
7480
Handler(screenshotTriggerThread.looper)
7581
)
82+
83+
// Set up feedback trigger menu
84+
feedbackTriggerMenu = findViewById(R.id.feedbackTriggerMenu)
85+
val items = listOf(FeedbackTrigger.NONE.label, FeedbackTrigger.SHAKE.label)
86+
val adapter = ArrayAdapter(this, R.layout.list_item, items)
87+
val autoCompleteTextView = feedbackTriggerMenu.editText!! as AutoCompleteTextView
88+
autoCompleteTextView.setAdapter(adapter)
89+
autoCompleteTextView.setText(FeedbackTrigger.NONE.label, false)
90+
autoCompleteTextView.doOnTextChanged { text, start, before, count ->
91+
// TODO: support enabling/disabling other triggers
92+
when(text.toString()) {
93+
FeedbackTrigger.NONE.label -> {
94+
Log.i(TAG, "Disabling shake")
95+
ShakeForFeedback.disable(application)
96+
}
97+
FeedbackTrigger.SHAKE.label -> {
98+
Log.i(TAG, "Enabling shake")
99+
ShakeForFeedback.enable(application, this)
100+
}
101+
}
102+
}
103+
}
104+
105+
override fun onCreateOptionsMenu(menu: Menu): Boolean {
106+
val inflater: MenuInflater = menuInflater
107+
inflater.inflate(R.menu.action_menu, menu)
108+
return true
109+
}
110+
111+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
112+
return when (item.itemId) {
113+
R.id.startFeedbackMenuItem -> {
114+
Firebase.appDistribution.startFeedback(R.string.terms_and_conditions)
115+
true
116+
}
117+
else -> super.onOptionsItemSelected(item)
118+
}
76119
}
77120

78121
override fun onDestroy() {
@@ -195,23 +238,21 @@ class MainActivity : AppCompatActivity() {
195238
}
196239
}
197240

198-
feedbackButton.setOnClickListener {
199-
firebaseAppDistribution.startFeedback(R.string.terms_and_conditions)
200-
}
241+
secondActivityButton.setOnClickListener { startSecondActivity() }
201242
}
202243

203-
fun startSecondActivity() {
244+
private fun startSecondActivity() {
204245
val intent = Intent(this, SecondActivity::class.java)
205246
startActivity(intent)
206247
}
207248

208-
fun setProgressBar() {
249+
private fun setProgressBar() {
209250
progressBar.visibility = View.VISIBLE
210251
progressPercent.visibility = View.VISIBLE
211252
progressBar.isIndeterminate = false
212253
}
213254

214-
fun failureListener(exception: Exception) {
255+
private fun failureListener(exception: Exception) {
215256
val ex = exception as com.google.firebase.appdistribution.FirebaseAppDistributionException
216257
Log.d("FirebaseAppDistribution", "MAINACTIVITY:ERROR ERROR. CODE: " + exception.errorCode)
217258
AlertDialog.Builder(this)
@@ -221,7 +262,7 @@ class MainActivity : AppCompatActivity() {
221262
.show()
222263
}
223264

224-
fun progressListener(updateProgress: UpdateProgress) {
265+
private fun progressListener(updateProgress: UpdateProgress) {
225266
val percentage =
226267
((updateProgress.apkBytesDownloaded * 100) / updateProgress.apkFileTotalBytes).toInt()
227268
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -236,7 +277,7 @@ class MainActivity : AppCompatActivity() {
236277
release: AppDistributionRelease? = null
237278
) {
238279
progressBar.visibility = View.GONE
239-
progressPercentage.visibility = View.GONE
280+
progressPercent.visibility = View.GONE
240281
if (isUpdateAvailable) {
241282
signInStatus.text =
242283
"Release available - ${release?.displayVersion} (${release?.versionCode})"
@@ -264,4 +305,15 @@ class MainActivity : AppCompatActivity() {
264305
updateAppButton.visibility = View.GONE
265306
updateAppButtonBackground.visibility = View.GONE
266307
}
308+
309+
companion object {
310+
const val TAG = "MainActivity"
311+
312+
enum class FeedbackTrigger(val label: String) {
313+
NONE("None"),
314+
SHAKE("Shake the device"),
315+
SCREENSHOT("Take a screenshot"),
316+
NOTIFICATION("Click the notification")
317+
}
318+
}
267319
}

firebase-appdistribution/test-app/src/main/java/com/googletest/firebase/appdistribution/testapp/SecondActivity.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ package com.googletest.firebase.appdistribution.testapp
22

33
import android.content.Intent
44
import android.os.Bundle
5+
import android.view.Menu
6+
import android.view.MenuInflater
7+
import android.view.MenuItem
58
import androidx.appcompat.app.AppCompatActivity
69
import androidx.appcompat.widget.AppCompatButton
10+
import com.google.firebase.appdistribution.ktx.appDistribution
11+
import com.google.firebase.ktx.Firebase
712

813
class SecondActivity : AppCompatActivity() {
914

@@ -20,6 +25,22 @@ class SecondActivity : AppCompatActivity() {
2025
}
2126
}
2227

28+
override fun onCreateOptionsMenu(menu: Menu): Boolean {
29+
val inflater: MenuInflater = menuInflater
30+
inflater.inflate(R.menu.action_menu, menu)
31+
return true
32+
}
33+
34+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
35+
return when (item.itemId) {
36+
R.id.startFeedbackMenuItem -> {
37+
Firebase.appDistribution.startFeedback(R.string.terms_and_conditions)
38+
true
39+
}
40+
else -> super.onOptionsItemSelected(item)
41+
}
42+
}
43+
2344
private fun startMainActivity() {
2445
val intent = Intent(this, MainActivity::class.java)
2546
startActivity(intent)

firebase-appdistribution/test-app/src/main/java/com/googletest/firebase/appdistribution/testapp/ShakeForFeedback.kt

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,44 @@ import com.google.firebase.appdistribution.ktx.appDistribution
99
import com.google.firebase.ktx.Firebase
1010
import com.squareup.seismic.ShakeDetector
1111

12-
class ShakeForFeedback private constructor() : ShakeDetector.Listener,
13-
Application.ActivityLifecycleCallbacks {
12+
object ShakeForFeedback : ShakeDetector.Listener, Application.ActivityLifecycleCallbacks {
13+
const val TAG: String = "ShakeForFeedback"
14+
1415
private val shakeDetector = ShakeDetector(this)
16+
private var isEnabled = false
17+
18+
fun enable(application: Application, currentActivity: Activity? = null) {
19+
synchronized(this) {
20+
if (!isEnabled) {
21+
application.registerActivityLifecycleCallbacks(this)
22+
Log.i(TAG, "Shake detector registered")
23+
if (currentActivity != null) {
24+
listenForShakes(currentActivity)
25+
}
26+
isEnabled = true
27+
}
28+
}
29+
}
30+
31+
fun disable(application: Application) {
32+
synchronized(this) {
33+
if (isEnabled) {
34+
stopListeningForShakes()
35+
application.unregisterActivityLifecycleCallbacks(this)
36+
Log.i(TAG, "Shake detector unregistered")
37+
isEnabled = false
38+
}
39+
}
40+
}
41+
42+
private fun listenForShakes(activity: Activity) {
43+
val sensorManager = activity.getSystemService(Activity.SENSOR_SERVICE) as SensorManager
44+
shakeDetector.start(sensorManager, SensorManager.SENSOR_DELAY_NORMAL)
45+
}
46+
47+
private fun stopListeningForShakes() {
48+
shakeDetector.stop()
49+
}
1550

1651
override fun hearShake() {
1752
Log.i(TAG, "Shake detected")
@@ -20,13 +55,12 @@ class ShakeForFeedback private constructor() : ShakeDetector.Listener,
2055

2156
override fun onActivityResumed(activity: Activity) {
2257
Log.i(TAG, "Shake detection started")
23-
val sensorManager = activity.getSystemService(Activity.SENSOR_SERVICE) as SensorManager
24-
shakeDetector.start(sensorManager, SensorManager.SENSOR_DELAY_NORMAL)
58+
listenForShakes(activity)
2559
}
2660

2761
override fun onActivityPaused(activity: Activity) {
2862
Log.i(TAG, "Shake detection stopped")
29-
shakeDetector.stop()
63+
stopListeningForShakes()
3064
}
3165

3266
// Other lifecycle methods
@@ -35,13 +69,4 @@ class ShakeForFeedback private constructor() : ShakeDetector.Listener,
3569
override fun onActivityStopped(activity: Activity) {}
3670
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
3771
override fun onActivityDestroyed(activity: Activity) {}
38-
39-
companion object {
40-
const val TAG: String = "ShakeForFeedback"
41-
42-
fun enable(application: Application) {
43-
application.registerActivityLifecycleCallbacks(ShakeForFeedback())
44-
Log.i(TAG, "Shake detector registered")
45-
}
46-
}
4772
}

0 commit comments

Comments
 (0)