Skip to content

Commit 7b76c9b

Browse files
authored
Merge pull request #27 from patjackson52/pj-speech
Add login to Android
2 parents ca47b4e + c865abc commit 7b76c9b

32 files changed

+436
-137
lines changed

android/build.gradle

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ android {
2929
matchingFallbacks = ['release']
3030
}
3131
}
32+
// signingConfigs {
33+
// debug {
34+
// storeFile file("./debug.keystore")
35+
// storePassword 'android'
36+
// keyAlias 'android'
37+
// keyPassword 'android'
38+
// }
39+
// }
3240
packagingOptions {
3341
exclude 'META-INF/*.kotlin_module'
3442
}
@@ -65,6 +73,18 @@ dependencies {
6573
testImplementation 'junit:junit:4.12'
6674
androidTestImplementation 'androidx.test:runner:1.1.1'
6775
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
68-
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
6976

77+
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha4'
78+
implementation 'com.google.firebase:firebase-core:16.0.8'
79+
implementation 'com.google.firebase:firebase-auth:16.2.1'
80+
implementation 'com.firebaseui:firebase-ui-auth:4.3.2'
81+
debugImplementation 'com.willowtreeapps.hyperion:hyperion-core:0.9.27'
82+
releaseImplementation 'com.willowtreeapps.hyperion:hyperion-core-no-op:0.9.27'
83+
debugImplementation 'com.willowtreeapps.hyperion:hyperion-measurement:0.9.27'
84+
debugImplementation 'com.willowtreeapps.hyperion:hyperion-shared-preferences:0.9.27'
85+
debugImplementation 'com.willowtreeapps.hyperion:hyperion-geiger-counter:0.9.27'
86+
debugImplementation 'com.willowtreeapps.hyperion:hyperion-build-config:0.9.27'
87+
debugImplementation 'com.willowtreeapps.hyperion:hyperion-attr:0.9.27'
7088
}
89+
90+
apply plugin: 'com.google.gms.google-services'

android/debug.keystore

2.25 KB
Binary file not shown.

android/google-services.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"project_info": {
3+
"project_number": "1060360359056",
4+
"firebase_url": "https://namegamekotlin.firebaseio.com",
5+
"project_id": "namegamekotlin",
6+
"storage_bucket": "namegamekotlin.appspot.com"
7+
},
8+
"client": [
9+
{
10+
"client_info": {
11+
"mobilesdk_app_id": "1:1060360359056:android:e41adf9f4239973b",
12+
"android_client_info": {
13+
"package_name": "com.willowtreeapps.namegame"
14+
}
15+
},
16+
"oauth_client": [
17+
{
18+
"client_id": "1060360359056-jg12tcoe1i1pi66u90ed0fths0o6p54q.apps.googleusercontent.com",
19+
"client_type": 1,
20+
"android_info": {
21+
"package_name": "com.willowtreeapps.namegame",
22+
"certificate_hash": "d92149ce680e55fcc9c0c4e12732362dad84a718"
23+
}
24+
},
25+
{
26+
"client_id": "1060360359056-99i0vklp7js0vpahpetks2njas0srsfd.apps.googleusercontent.com",
27+
"client_type": 3
28+
}
29+
],
30+
"api_key": [
31+
{
32+
"current_key": "AIzaSyA--LTJY3hBLRCyvTDwnqmCTKssXDkl0jo"
33+
}
34+
],
35+
"services": {
36+
"appinvite_service": {
37+
"other_platform_oauth_client": [
38+
{
39+
"client_id": "1060360359056-99i0vklp7js0vpahpetks2njas0srsfd.apps.googleusercontent.com",
40+
"client_type": 3
41+
}
42+
]
43+
}
44+
}
45+
}
46+
],
47+
"configuration_version": "1"
48+
}

android/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
android:label="@string/app_name"
1313
android:roundIcon="@mipmap/ic_launcher_round"
1414
android:supportsRtl="true"
15-
android:theme="@style/AppTheme">
15+
android:theme="@style/NameGameAppTheme">
1616
<activity
1717
android:name="com.willowtreeapps.namegame.MainActivity"
1818
android:label="@string/app_name"
1919
android:screenOrientation="portrait"
20-
android:theme="@style/AppTheme">
20+
android:theme="@style/NameGameAppTheme">
2121
<intent-filter>
2222
<action android:name="android.intent.action.MAIN" />
2323

android/src/main/java/com/willowtreeapps/namegame/AndroidNavigator.kt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import android.app.Application
55
import android.os.Bundle
66
import androidx.appcompat.app.AppCompatActivity
77
import androidx.navigation.findNavController
8+
import com.willowtreeapps.common.Logger
89
import com.willowtreeapps.common.middleware.Navigator
910
import com.willowtreeapps.common.middleware.Screen
1011
import com.willowtreeapps.namegame.store.SettingsDialogFragment
12+
import java.lang.Exception
1113

1214
/**
1315
* Android implementation of Navigator interface. This will load the appropriate Activity or Fragment
@@ -29,8 +31,8 @@ class AndroidNavigator : Navigator, Application.ActivityLifecycleCallbacks {
2931
when (screen) {
3032
Screen.QUESTION -> navController.navigate(R.id.action_startScreen_to_questionScreen)
3133
Screen.GAME_COMPLETE -> navController.navigate(R.id.action_questionScreen_to_resultsFragment)
32-
// Screen.START -> navController.navigate(R.id.startScreen)
33-
Screen.START -> navController.navigate(R.id.action_resultsFragment_to_startScreen)
34+
Screen.START -> navController.navigate(R.id.startScreen)
35+
// Screen.START -> navController.navigate(R.id.action_resultsFragment_to_startScreen)
3436
Screen.SETTINGS -> {
3537
val dialog = SettingsDialogFragment.newInstance()
3638
dialog.show(currentActivity!!.supportFragmentManager, "SettingsFragment")
@@ -44,15 +46,23 @@ class AndroidNavigator : Navigator, Application.ActivityLifecycleCallbacks {
4446
}
4547

4648
override fun onActivityResumed(activity: Activity?) {
47-
if (cachedNavigationScreen!= null) {
49+
if (cachedNavigationScreen != null) {
4850
goto(cachedNavigationScreen!!)
4951
cachedNavigationScreen = null
5052
}
53+
attachActivity(activity)
5154
}
5255

53-
override fun onActivityStarted(activity: Activity?) {
54-
currentActivity = activity as AppCompatActivity?
56+
private fun attachActivity(activity: Activity?) {
57+
try {
58+
currentActivity = activity as AppCompatActivity?
59+
} catch (e: Exception) {
60+
Logger.d("Exception casting activity to AppCompatActivity. $e")
61+
}
62+
}
5563

64+
override fun onActivityStarted(activity: Activity?) {
65+
attachActivity(activity)
5666
}
5767

5868
override fun onActivityDestroyed(activity: Activity?) {
@@ -62,7 +72,9 @@ class AndroidNavigator : Navigator, Application.ActivityLifecycleCallbacks {
6272
}
6373

6474
override fun onActivityStopped(activity: Activity?) {
65-
currentActivity = null
75+
if (activity == currentActivity) {
76+
currentActivity = null
77+
}
6678
}
6779

6880
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {

android/src/main/java/com/willowtreeapps/namegame/MainActivity.kt

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.willowtreeapps.namegame
22

33
import android.os.Bundle
4-
import androidx.appcompat.app.AppCompatActivity
4+
import android.os.Handler
5+
import android.view.MotionEvent
56
import android.view.View
6-
import androidx.navigation.Navigation
7+
import android.view.ViewConfiguration
8+
import androidx.appcompat.app.AppCompatActivity
79
import com.bumptech.glide.annotation.GlideModule
810
import com.bumptech.glide.module.AppGlideModule
11+
import com.willowtreeapps.hyperion.core.Hyperion
912
import kotlinx.android.synthetic.main.app_bar_main.*
13+
import kotlinx.android.synthetic.main.activity_main.*
1014

1115

1216
@GlideModule
@@ -29,18 +33,63 @@ class MainActivity : AppCompatActivity() {
2933
scrimLayout.setOnInsetsCallback {
3034
rootContent.setPadding(0, -it.top, 0, 0)
3135
}
36+
drawer_layout.setOnTouchListener(tripleTapDetector)
37+
3238
}
3339

34-
override fun onSupportNavigateUp(): Boolean = Navigation.findNavController(this, R.id.nav_host_fragment).navigateUp()
40+
// override fun onSupportNavigateUp(): Boolean = Navigation.findNavController(this, R.id.nav_host_fragment).navigateUp()
3541

3642
override fun onBackPressed() {
37-
// val navHostFragment =
38-
// this.supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
39-
// val currentFragment = navHostFragment?.childFragmentManager?.fragments?.get(0)
40-
// if (currentFragment is IOnBackPressed)
41-
// (currentFragment as IOnBackPressed).onBackPressed()
43+
val navHostFragment =
44+
this.supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
45+
val currentFragment = navHostFragment?.childFragmentManager?.fragments?.get(0)
46+
if (currentFragment is IOnBackPressed)
47+
(currentFragment as IOnBackPressed).onBackPressed()
4248
super.onBackPressed()
4349
}
4450

51+
var tripleTapDetector: View.OnTouchListener = object : View.OnTouchListener {
52+
internal var handler = Handler()
53+
54+
internal var numberOfTaps = 0
55+
internal var lastTapTimeMs: Long = 0
56+
internal var touchDownMs: Long = 0
57+
58+
override fun onTouch(v: View, event: MotionEvent): Boolean {
59+
60+
when (event.action) {
61+
MotionEvent.ACTION_DOWN -> touchDownMs = System.currentTimeMillis()
62+
MotionEvent.ACTION_UP -> {
63+
handler.removeCallbacksAndMessages(null)
64+
65+
if (System.currentTimeMillis() - touchDownMs > ViewConfiguration.getTapTimeout()) {
66+
//it was not a tap
4567

68+
numberOfTaps = 0
69+
lastTapTimeMs = 0
70+
return true
71+
}
72+
73+
if (numberOfTaps > 0 && System.currentTimeMillis() - lastTapTimeMs < ViewConfiguration.getDoubleTapTimeout()) {
74+
numberOfTaps += 1
75+
} else {
76+
numberOfTaps = 1
77+
}
78+
79+
lastTapTimeMs = System.currentTimeMillis()
80+
81+
if (numberOfTaps == 3) {
82+
Hyperion.open()
83+
//handle triple tap
84+
} else if (numberOfTaps == 2) {
85+
handler.postDelayed({
86+
//handle double tap
87+
}, ViewConfiguration.getDoubleTapTimeout().toLong())
88+
}
89+
}
90+
}
91+
92+
return true
93+
}
94+
}
4695
}

android/src/main/java/com/willowtreeapps/namegame/NameGameApp.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.willowtreeapps.namegame
22

3+
import android.app.Activity
34
import android.app.Application
5+
import android.os.Bundle
6+
import com.google.firebase.FirebaseApp
47
import com.willowtreeapps.common.GameEngine
8+
import com.willowtreeapps.common.Logger
59
import kotlinx.coroutines.Dispatchers
610

711
class NameGameApp : Application() {
@@ -10,16 +14,49 @@ class NameGameApp : Application() {
1014

1115
override fun onCreate() {
1216
super.onCreate()
17+
FirebaseApp.initializeApp(this)
1318
instance = this
1419
val navigator = AndroidNavigator()
1520
gameEngine = GameEngine(navigator, this, Dispatchers.IO, Dispatchers.Main)
1621

1722
registerActivityLifecycleCallbacks(navigator)
23+
registerActivityLifecycleCallbacks(LifeCycleLogger)
1824
}
1925

2026
companion object {
2127
lateinit var instance: NameGameApp
2228

2329
fun gameEngine() = instance.gameEngine
2430
}
31+
}
32+
33+
object LifeCycleLogger: Application.ActivityLifecycleCallbacks {
34+
override fun onActivityPaused(activity: Activity?) {
35+
Logger.d(activity?.javaClass?.simpleName + ": onActivityPaused")
36+
}
37+
38+
override fun onActivityResumed(activity: Activity?) {
39+
Logger.d(activity?.javaClass?.simpleName + ": onActivityResumed")
40+
}
41+
42+
override fun onActivityStarted(activity: Activity?) {
43+
Logger.d(activity?.javaClass?.simpleName + ": onActivityStarted")
44+
}
45+
46+
override fun onActivityDestroyed(activity: Activity?) {
47+
Logger.d(activity?.javaClass?.simpleName + ": onActivityDestroyed")
48+
}
49+
50+
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
51+
Logger.d(activity?.javaClass?.simpleName + ": onActivitySaveInstanceState")
52+
}
53+
54+
override fun onActivityStopped(activity: Activity?) {
55+
Logger.d(activity?.javaClass?.simpleName + ": onActivityStopped")
56+
}
57+
58+
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
59+
Logger.d(activity?.javaClass?.simpleName + ": onActivityCreated")
60+
}
61+
2562
}

android/src/main/java/com/willowtreeapps/namegame/Utils.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import android.animation.Animator
44
import android.animation.AnimatorListenerAdapter
55
import android.animation.AnimatorSet
66
import android.content.res.Resources
7-
import android.graphics.drawable.Drawable
87
import com.bumptech.glide.load.DataSource
98
import com.bumptech.glide.load.engine.GlideException
109
import com.bumptech.glide.request.RequestListener
1110
import com.bumptech.glide.request.target.Target
11+
import com.willowtreeapps.common.util.TimeUtil
12+
import kotlin.math.abs
13+
import kotlin.random.Random
1214

1315
val Int.dp: Int
1416
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
@@ -40,4 +42,7 @@ fun <T: Any> GlideRequest<T>.onComplete(after: () -> Unit): GlideRequest<T> {
4042
}
4143

4244
})
43-
}
45+
}
46+
47+
48+

android/src/main/java/com/willowtreeapps/namegame/store/QuestionFragment.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class QuestionFragment : BaseNameGameViewFragment<QuestionPresenter>(), Question
6666
}
6767

6868
override fun onError(error: Int) {
69+
Logger.d("Error with speech recognizer: code =$error")
6970
}
7071

7172
override fun onResults(results: Bundle) {

0 commit comments

Comments
 (0)