@@ -7,9 +7,8 @@ import android.content.Intent
77import android.content.IntentFilter
88import android.content.res.Configuration
99import android.os.Build
10- import android.os.Bundle
1110import android.os.IBinder
12- import android.view.WindowManager
11+ import android.util.Log
1312import androidx.core.app.NotificationCompat
1413import kotlinx.coroutines.CoroutineScope
1514import kotlinx.coroutines.Dispatchers
@@ -26,98 +25,49 @@ class MainService : Service() {
2625 val edges: MutableList <Edge > = mutableListOf ()
2726
2827 override fun onBind (intent : Intent ? ): IBinder ? = null
28+ override fun onStartCommand (intent : Intent ? , flags : Int , startId : Int ): Int = START_STICKY
2929
3030 override fun onCreate () {
3131 super .onCreate()
3232 startForeground()
33- updateAppData()
34- detectDeactivation()
3533 observeAppData()
36- createEdges()
37- registerBroadcastReceivers()
38- }
39-
40- override fun onStartCommand (intent : Intent ? , flags : Int , startId : Int ): Int {
41- updateAppData()
42- detectDeactivation()
43- return START_STICKY
4434 }
4535
4636 override fun onDestroy () {
4737 super .onDestroy()
48- destroyEdges()
49- unregisterBroadcastReceivers()
38+ shutdownSequence()
5039 }
5140
5241 override fun onConfigurationChanged (newConfig : Configuration ) {
5342 super .onConfigurationChanged(newConfig)
54- updateEdges ()
43+ updateSequence ()
5544 }
5645
5746 fun onDataChange () {
58- updateAppData()
59- detectDeactivation()
60- updateEdges()
47+ updateSequence()
6148 }
6249
63- fun startForeground () {
64- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
65- val title = " Running In Background"
66- val description = """
67- Allows the application to work in background.
68- Recommended disabling this notification since it has no real value
69- """ .trimIndent()
70-
71- val channel = NotificationChannel (" main" , title, NotificationManager .IMPORTANCE_MIN )
72- channel.description = description
73- this .getSystemService(NotificationManager ::class .java)
74- .createNotificationChannel(channel)
75- val notification = NotificationCompat .Builder (this , channel.id)
76- .setContentTitle(title)
77- .setContentText(description)
78- .setSmallIcon(R .drawable.ic_sync)
79- .build()
80- this .startForeground(1 , notification)
81- }
82- }
83-
84- fun observeAppData () {
85- appDataStore.data
86- .onEach { onDataChange() }
87- .launchIn(CoroutineScope (Dispatchers .IO ))
88- }
50+ fun updateSequence () {
51+ data = applicationData().value
8952
90- fun detectDeactivation () {
9153 if (! data.activated) {
92- stopSelf()
54+ shutdownSequence()
55+ } else {
56+ startupSequence()
9357 }
9458 }
9559
96- fun updateAppData () {
97- data = applicationData().value
60+ fun startupSequence () {
61+ registerBroadcastReceivers()
62+ createEdges()
9863 }
9964
100- fun createEdges () {
101- val manager = getSystemService(WindowManager ::class .java)
102- val context = when {
103- false && Build .VERSION .SDK_INT >= Build .VERSION_CODES .S -> {
104- createWindowContext(
105- manager.defaultDisplay,
106- WindowManager .LayoutParams .TYPE_APPLICATION_OVERLAY ,
107- Bundle ()
108- )
109- }
110- else -> this
111- }
112-
113- CoroutineScope (Dispatchers .Main ).launch {
114- edges.clear()
115- edges + = data.edges.map { Edge (context, it) }
116- edges.forEach { it.start() }
117- }
65+ fun shutdownSequence () {
66+ unregisterBroadcastReceivers()
67+ destroyEdges()
11868 }
11969
120- fun updateEdges () {
70+ fun createEdges () {
12171 val context = this
12272
12373 CoroutineScope (Dispatchers .Main ).launch {
@@ -140,6 +90,7 @@ class MainService : Service() {
14090
14191 fun destroyEdges () {
14292 CoroutineScope (Dispatchers .Main ).launch {
93+ Log .d(" LALA_LAND" , " Destroying Edges ${edges.size} " )
14394 edges.forEach { it.stop() }
14495 edges.clear()
14596 }
@@ -150,6 +101,35 @@ class MainService : Service() {
150101 }
151102
152103 fun unregisterBroadcastReceivers () {
153- unregisterReceiver(ScreenOffBroadCastReceiver )
104+ runCatching {
105+ unregisterReceiver(ScreenOffBroadCastReceiver )
106+ }
107+ }
108+
109+ fun startForeground () {
110+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
111+ val title = " Running In Background"
112+ val description = """
113+ Allows the application to work in background.
114+ Recommended disabling this notification since it has no real value
115+ """ .trimIndent()
116+
117+ val channel = NotificationChannel (" main" , title, NotificationManager .IMPORTANCE_MIN )
118+ channel.description = description
119+ this .getSystemService(NotificationManager ::class .java)
120+ .createNotificationChannel(channel)
121+ val notification = NotificationCompat .Builder (this , channel.id)
122+ .setContentTitle(title)
123+ .setContentText(description)
124+ .setSmallIcon(R .drawable.ic_sync)
125+ .build()
126+ this .startForeground(1 , notification)
127+ }
128+ }
129+
130+ fun observeAppData () {
131+ appDataStore.data
132+ .onEach { onDataChange() }
133+ .launchIn(CoroutineScope (Dispatchers .IO ))
154134 }
155135}
0 commit comments