Skip to content

Commit ef7766c

Browse files
committed
Add menu to test app for selecting feedback trigger
1 parent feab0b3 commit ef7766c

File tree

8 files changed

+193
-56
lines changed

8 files changed

+193
-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: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,21 @@ 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.content.ContentProviderCompat.requireContext
21+
import androidx.core.widget.addTextChangedListener
22+
import androidx.core.widget.doOnTextChanged
1523
import com.google.android.gms.tasks.Task
24+
import com.google.android.material.textfield.TextInputLayout
1625
import com.google.firebase.appdistribution.AppDistributionRelease
1726
import com.google.firebase.appdistribution.UpdateProgress
1827
import com.google.firebase.appdistribution.ktx.appDistribution
@@ -36,34 +45,33 @@ class MainActivity : AppCompatActivity() {
3645
lateinit var signOutButtonBackground: AppCompatButton
3746
lateinit var checkForUpdateButtonBackground: AppCompatButton
3847
lateinit var updateAppButtonBackground: AppCompatButton
39-
lateinit var feedbackButton: AppCompatButton
40-
lateinit var progressPercentage: TextView
48+
lateinit var secondActivityButton: AppCompatButton
4149
lateinit var signInStatus: TextView
4250
lateinit var progressPercent: TextView
4351
lateinit var progressBar: ProgressBar
52+
lateinit var feedbackTriggerMenu: TextInputLayout
4453

4554
private lateinit var screenshotTriggerThread: HandlerThread
4655
private lateinit var screenshotTrigger: ScreenshotDetectionFeedbackTrigger
4756

4857
override fun onCreate(savedInstanceState: Bundle?) {
4958
super.onCreate(savedInstanceState)
5059
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)
60+
signInButton = findViewById(R.id.sign_in_button)
61+
signOutButton = findViewById(R.id.sign_out)
62+
checkForUpdateButton = findViewById(R.id.check_for_update)
63+
updateAppButton = findViewById(R.id.update_app)
64+
updateIfNewReleaseAvailableButton = findViewById(R.id.basic_config)
5665
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)
66+
findViewById(R.id.basic_config2)
67+
signInButtonBackground = findViewById(R.id.sign_in_button2)
68+
signOutButtonBackground = findViewById(R.id.sign_out2)
69+
checkForUpdateButtonBackground = findViewById(R.id.check_for_update2)
70+
updateAppButtonBackground = findViewById(R.id.update_app2)
71+
secondActivityButton = findViewById(R.id.secondActivityButton)
72+
progressPercent = findViewById(R.id.progress_percentage)
73+
signInStatus = findViewById(R.id.sign_in_status)
74+
progressBar = findViewById(R.id.progress_bar)
6775

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

78123
override fun onDestroy() {
@@ -195,23 +240,21 @@ class MainActivity : AppCompatActivity() {
195240
}
196241
}
197242

198-
feedbackButton.setOnClickListener {
199-
firebaseAppDistribution.startFeedback(R.string.terms_and_conditions)
200-
}
243+
secondActivityButton.setOnClickListener { startSecondActivity() }
201244
}
202245

203-
fun startSecondActivity() {
246+
private fun startSecondActivity() {
204247
val intent = Intent(this, SecondActivity::class.java)
205248
startActivity(intent)
206249
}
207250

208-
fun setProgressBar() {
251+
private fun setProgressBar() {
209252
progressBar.visibility = View.VISIBLE
210253
progressPercent.visibility = View.VISIBLE
211254
progressBar.isIndeterminate = false
212255
}
213256

214-
fun failureListener(exception: Exception) {
257+
private fun failureListener(exception: Exception) {
215258
val ex = exception as com.google.firebase.appdistribution.FirebaseAppDistributionException
216259
Log.d("FirebaseAppDistribution", "MAINACTIVITY:ERROR ERROR. CODE: " + exception.errorCode)
217260
AlertDialog.Builder(this)
@@ -221,7 +264,7 @@ class MainActivity : AppCompatActivity() {
221264
.show()
222265
}
223266

224-
fun progressListener(updateProgress: UpdateProgress) {
267+
private fun progressListener(updateProgress: UpdateProgress) {
225268
val percentage =
226269
((updateProgress.apkBytesDownloaded * 100) / updateProgress.apkFileTotalBytes).toInt()
227270
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -236,7 +279,7 @@ class MainActivity : AppCompatActivity() {
236279
release: AppDistributionRelease? = null
237280
) {
238281
progressBar.visibility = View.GONE
239-
progressPercentage.visibility = View.GONE
282+
progressPercent.visibility = View.GONE
240283
if (isUpdateAvailable) {
241284
signInStatus.text =
242285
"Release available - ${release?.displayVersion} (${release?.versionCode})"
@@ -264,4 +307,12 @@ class MainActivity : AppCompatActivity() {
264307
updateAppButton.visibility = View.GONE
265308
updateAppButtonBackground.visibility = View.GONE
266309
}
310+
311+
companion object {
312+
const val TAG = "MainActivity"
313+
const val TRIGGER_NONE = "None"
314+
const val TRIGGER_SHAKE = "Shake the device"
315+
const val TRIGGER_SCREENSHOT = "Take a screenshot"
316+
const val TRIGGER_NOTIFICATION = "Click the notification"
317+
}
267318
}

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: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,46 @@ 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) = enable(application, null)
19+
20+
fun enable(application: Application, currentActivity: Activity?) {
21+
synchronized(this) {
22+
if (!isEnabled) {
23+
application.registerActivityLifecycleCallbacks(this)
24+
Log.i(TAG, "Shake detector registered")
25+
if (currentActivity != null) {
26+
listenForShakes(currentActivity)
27+
}
28+
isEnabled = true
29+
}
30+
}
31+
}
32+
33+
fun disable(application: Application) {
34+
synchronized(this) {
35+
if (isEnabled) {
36+
stopListeningForShakes()
37+
application.unregisterActivityLifecycleCallbacks(this)
38+
Log.i(TAG, "Shake detector unregistered")
39+
isEnabled = false
40+
}
41+
}
42+
}
43+
44+
private fun listenForShakes(activity: Activity) {
45+
val sensorManager = activity.getSystemService(Activity.SENSOR_SERVICE) as SensorManager
46+
shakeDetector.start(sensorManager, SensorManager.SENSOR_DELAY_NORMAL)
47+
}
48+
49+
private fun stopListeningForShakes() {
50+
shakeDetector.stop()
51+
}
1552

1653
override fun hearShake() {
1754
Log.i(TAG, "Shake detected")
@@ -20,13 +57,12 @@ class ShakeForFeedback private constructor() : ShakeDetector.Listener,
2057

2158
override fun onActivityResumed(activity: Activity) {
2259
Log.i(TAG, "Shake detection started")
23-
val sensorManager = activity.getSystemService(Activity.SENSOR_SERVICE) as SensorManager
24-
shakeDetector.start(sensorManager, SensorManager.SENSOR_DELAY_NORMAL)
60+
listenForShakes(activity)
2561
}
2662

2763
override fun onActivityPaused(activity: Activity) {
2864
Log.i(TAG, "Shake detection stopped")
29-
shakeDetector.stop()
65+
stopListeningForShakes()
3066
}
3167

3268
// Other lifecycle methods
@@ -35,13 +71,4 @@ class ShakeForFeedback private constructor() : ShakeDetector.Listener,
3571
override fun onActivityStopped(activity: Activity) {}
3672
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
3773
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-
}
4774
}

0 commit comments

Comments
 (0)