@@ -8,40 +8,67 @@ import android.content.Context
8
8
import android.content.Intent
9
9
import android.content.IntentFilter
10
10
import android.os.Build
11
- import android.provider.Settings
12
11
import android.view.accessibility.AccessibilityEvent
13
12
import android.view.accessibility.AccessibilityNodeInfo
14
13
import com.kylecorry.andromeda.notify.Notify
15
14
import com.kylecorry.andromeda.preferences.SharedPreferences
16
15
import com.kylecorry.intervalometer.R
16
+ import com.kylecorry.intervalometer.ui.MainActivity
17
17
import com.kylecorry.luna.timer.CoroutineTimer
18
18
19
19
class IntervalometerService : AccessibilityService () {
20
20
21
21
private val prefs by lazy { SharedPreferences (this ) }
22
+ private val knownShutterButtons = listOf (
23
+ " com.android.camera:id/shutter_button" ,
24
+ " com.android.camera2:id/shutter_button" ,
25
+ " com.google.android.GoogleCamera:id/shutter_button"
26
+ )
22
27
23
28
private var stopReceiver = object : BroadcastReceiver () {
24
29
override fun onReceive (context : Context ? , intent : Intent ? ) {
25
- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N ) {
26
- disableSelf()
27
- } else {
28
- // Open accessibility settings
29
- startActivity(Intent (Settings .ACTION_ACCESSIBILITY_SETTINGS ))
30
- }
31
-
30
+ timer.stop()
31
+ Notify .cancel(this @IntervalometerService, 2 )
32
32
}
33
33
}
34
+
35
+ private var secondsUntilNextPhoto = 0L
34
36
35
37
private val timer = CoroutineTimer {
36
- clickShutterButton()
38
+ // Trigger a notification with the remaining time
39
+ secondsUntilNextPhoto--
40
+ Notify .cancel(this , 2 )
41
+ Notify .send(
42
+ this ,
43
+ 2 ,
44
+ Notify .alert(
45
+ this ,
46
+ " intervalometer" ,
47
+ secondsUntilNextPhoto.toString(),
48
+ null ,
49
+ R .drawable.bubble,
50
+ group = " alerts"
51
+ )
52
+ )
53
+ if (secondsUntilNextPhoto <= 0 ) {
54
+ Notify .cancel(this , 2 )
55
+ clickShutterButton()
56
+ secondsUntilNextPhoto = prefs.getLong(" interval" ) ? : 0
57
+ }
37
58
}
38
59
39
60
override fun onAccessibilityEvent (event : AccessibilityEvent ? ) {
40
- println (event?.packageName)
61
+ // Start the timer when a shutter button is clicked
62
+ if (! timer.isRunning() && knownShutterButtons.contains(
63
+ event?.source?.viewIdResourceName ? : " "
64
+ )
65
+ ) {
66
+ restartTimer()
67
+ }
41
68
}
42
69
43
70
override fun onInterrupt () {
44
- println ( " Interrupted " )
71
+ // Do nothing
45
72
}
46
73
47
74
@SuppressLint(" UnspecifiedRegisterReceiverFlag" )
@@ -58,61 +85,51 @@ class IntervalometerService : AccessibilityService() {
58
85
registerReceiver(stopReceiver, IntentFilter (" com.kylecorry.intervalometer.STOP" ))
59
86
}
60
87
61
- val stopIntent = Intent (" com.kylecorry.intervalometer.STOP" )
62
- val stopPendingIntent = PendingIntent .getBroadcast(
63
- this ,
64
- 0 ,
65
- stopIntent,
66
- PendingIntent .FLAG_IMMUTABLE
67
- )
68
-
69
88
Notify .send(
70
89
this ,
71
90
1 ,
72
91
Notify .persistent(
73
92
this , " intervalometer" , " Intervalometer" , null , R .drawable.bubble,
74
93
actions = listOf (
75
- Notify .action(" Stop" , stopPendingIntent, R .drawable.ic_info),
94
+ Notify .action(
95
+ " Stop" , PendingIntent .getBroadcast(
96
+ this ,
97
+ 0 ,
98
+ Intent (" com.kylecorry.intervalometer.STOP" ),
99
+ PendingIntent .FLAG_IMMUTABLE
100
+ ), R .drawable.ic_info
101
+ ),
102
+ ),
103
+ intent = PendingIntent .getActivity(
104
+ this ,
105
+ 0 ,
106
+ Intent (this , MainActivity ::class .java),
107
+ PendingIntent .FLAG_IMMUTABLE
76
108
)
77
109
),
78
110
)
79
-
80
- restartTimer()
81
-
82
- prefs.onChange.subscribe(this ::onPrefsChanged)
83
111
}
84
112
85
113
override fun onDestroy () {
86
114
super .onDestroy()
87
115
timer.stop()
88
116
Notify .cancel(this , 1 )
117
+ Notify .cancel(this , 2 )
89
118
unregisterReceiver(stopReceiver)
90
- prefs.onChange.unsubscribe(this ::onPrefsChanged)
91
- }
92
-
93
- private fun onPrefsChanged (key : String ): Boolean {
94
- if (key == " interval" ) {
95
- restartTimer()
96
- }
97
- return true
98
119
}
99
120
100
121
private fun restartTimer () {
101
122
val interval = prefs.getLong(" interval" ) ? : 0
123
+ Notify .cancel(this , 2 )
102
124
if (interval > 0 ) {
103
- timer.interval(interval * 1000 )
125
+ secondsUntilNextPhoto = prefs.getLong(" interval" ) ? : 0
126
+ timer.interval(1000 )
104
127
} else {
105
128
timer.stop()
106
129
}
107
130
}
108
131
109
132
private fun clickShutterButton () {
110
- val knownShutterButtons = listOf (
111
- " com.android.camera:id/shutter_button" ,
112
- " com.android.camera2:id/shutter_button" ,
113
- " com.google.android.GoogleCamera:id/shutter_button"
114
- )
115
-
116
133
val nodeInfo = rootInActiveWindow
117
134
for (shutterButton in knownShutterButtons) {
118
135
val nodes = nodeInfo?.findAccessibilityNodeInfosByViewId(shutterButton)
@@ -123,5 +140,8 @@ class IntervalometerService : AccessibilityService() {
123
140
return
124
141
}
125
142
}
143
+
144
+ // If it got this far, no shutter button was found, so stop the timer
145
+ timer.stop()
126
146
}
127
147
}
0 commit comments