/
ActivityHandler.kt
141 lines (128 loc) · 5.12 KB
/
ActivityHandler.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* Copyright © 2020 - present | Handwashing reminder by Javinator9889
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*
* Created by Javinator9889 on 15/03/20 - Handwashing reminder.
*/
package com.javinator9889.handwashingreminder.gms.activity
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager
import com.google.android.gms.location.ActivityRecognition
import com.google.android.gms.location.ActivityTransition
import com.google.android.gms.location.ActivityTransitionRequest
import com.google.android.gms.tasks.Task
import com.javinator9889.handwashingreminder.BuildConfig
import com.javinator9889.handwashingreminder.utils.Preferences
import timber.log.Timber
internal const val ACTIVITY_REQUEST_CODE = 64
internal const val TRANSITIONS_RECEIVER_ACTION =
"${BuildConfig.APPLICATION_ID}/TRANSITIONS_RECEIVER_ACTION"
class ActivityHandler private constructor(private val context: Context) {
private val transitions: MutableList<ActivityTransition> = mutableListOf()
private var pendingIntent: PendingIntent
private var activityRegistered = false
private val transitionsReceiver = ActivityReceiver()
init {
val activitiesSet = createSetOfTransitions()
addTransitions(activitiesSet, transitions)
registerActivityReceiver()
pendingIntent = createPendingIntent()
}
companion object {
private var instance: ActivityHandler? = null
fun getInstance(context: Context): ActivityHandler {
instance?.let { return it }
instance = ActivityHandler(context)
return instance!!
}
}
fun startTrackingActivity() {
if (transitions.size == 0)
return
Timber.d("Starting activity recognition")
with(ActivityTransitionRequest(transitions)) {
ActivityRecognition.getClient(context)
.requestActivityTransitionUpdates(this, pendingIntent).apply {
addOnSuccessListener { activityRegistered = true }
addOnFailureListener { activityRegistered = false }
}
}
}
fun disableActivityTracker(): Task<Void>? {
Timber.d("Stopping activity recognition")
if (!activityRegistered)
return null
return ActivityRecognition.getClient(context)
.removeActivityTransitionUpdates(pendingIntent).also {
it.addOnSuccessListener {
pendingIntent.cancel(); activityRegistered = false
}
it.addOnFailureListener { e: Exception -> Timber.e(e) }
}
}
fun reload() = with(createSetOfTransitions()) {
transitions.clear()
addTransitions(this, transitions)
Timber.d("Reloading activity recognition - transitions: $transitions")
disableActivityTracker()?.let {
it.addOnCompleteListener {
pendingIntent = createPendingIntent()
startTrackingActivity()
}
}
}
private fun createSetOfTransitions(): Set<Int> {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
with(mutableSetOf<Int>()) {
preferences.getStringSet(
Preferences.ACTIVITIES_ENABLED,
Preferences.DEFAULT_ACTIVITY_SET
)!!.run {
forEach { this@with += Integer.parseInt(it) }
}
return this
}
}
private fun addTransitions(
activitiesSet: Set<Int>,
transitions: MutableList<ActivityTransition>,
activityTransition: Int = ActivityTransition.ACTIVITY_TRANSITION_EXIT
) {
for (activity in activitiesSet) {
transitions += ActivityTransition.Builder()
.setActivityType(activity)
.setActivityTransition(activityTransition)
.build()
}
}
private fun createPendingIntent(): PendingIntent =
with(Intent(TRANSITIONS_RECEIVER_ACTION)) {
PendingIntent.getBroadcast(
context,
ACTIVITY_REQUEST_CODE,
this,
FLAG_UPDATE_CURRENT
)
}
private fun registerActivityReceiver() =
LocalBroadcastManager.getInstance(context).registerReceiver(
transitionsReceiver, IntentFilter(TRANSITIONS_RECEIVER_ACTION)
)
}