Skip to content

Commit 0b0a669

Browse files
committed
Add sticky notification service
1 parent 01ace38 commit 0b0a669

4 files changed

Lines changed: 125 additions & 1 deletion

File tree

android/app/src/main/AndroidManifest.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
<uses-permission android:name="android.permission.INTERNET" />
1313
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1414
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
15-
15+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
16+
<uses-permission android:name="android.permission.WAKE_LOCK" />
17+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
1618

1719
<application
1820
android:allowBackup="true"
@@ -38,6 +40,12 @@
3840
<activity android:name=".LoginActivity" android:screenOrientation="portrait"
3941
tools:ignore="LockedOrientationActivity" />
4042

43+
<service
44+
android:name=".services.StickyNotificationService"
45+
android:enabled="true"
46+
android:exported="false">
47+
</service>
48+
4149
<service
4250
android:name=".MyFirebaseMessagingService"
4351
android:exported="false">
@@ -53,6 +61,14 @@
5361
</intent-filter>
5462
</receiver>
5563

64+
<receiver android:enabled="true" android:name=".receivers.BootReceiver"
65+
android:exported="true">
66+
<intent-filter>
67+
<action android:name="android.intent.action.BOOT_COMPLETED"/>
68+
</intent-filter>
69+
</receiver>
70+
71+
5672
<meta-data
5773
android:name="com.google.firebase.messaging.default_notification_channel_id"
5874
android:value="@string/notification_channel_default" />

android/app/src/main/java/com/httpsms/MainActivity.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity
1818
import androidx.core.app.ActivityCompat
1919
import com.google.android.material.button.MaterialButton
2020
import com.google.android.material.switchmaterial.SwitchMaterial
21+
import com.httpsms.services.StickyNotificationService
2122
import timber.log.Timber
2223
import java.util.*
2324

@@ -43,6 +44,8 @@ class MainActivity : AppCompatActivity() {
4344
setActiveStatus(this)
4445
registerListeners()
4546
refreshToken(this)
47+
48+
startStickyNotification(this)
4649
}
4750

4851
override fun onResume() {
@@ -52,6 +55,13 @@ class MainActivity : AppCompatActivity() {
5255
refreshToken(this)
5356
}
5457

58+
private fun startStickyNotification(context: Context) {
59+
Timber.d("starting foreground service")
60+
val notificationIntent = Intent(context, StickyNotificationService::class.java)
61+
val service = context.startForegroundService(notificationIntent)
62+
Timber.d("foreground service started [${service?.className}]")
63+
}
64+
5565
private fun refreshToken(context: Context) {
5666
if(!Settings.isLoggedIn(context)) {
5767
Timber.w("cannot refresh token because owner is not logged in")
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.httpsms.receivers
2+
3+
import android.content.BroadcastReceiver
4+
import android.content.Context
5+
import android.content.Intent
6+
import com.httpsms.services.StickyNotificationService
7+
import timber.log.Timber
8+
9+
10+
class BootReceiver : BroadcastReceiver() {
11+
override fun onReceive(context: Context, intent: Intent) {
12+
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
13+
Intent(context, StickyNotificationService::class.java).also {
14+
context.startForegroundService(it)
15+
}
16+
} else {
17+
Timber.e("invalid intent [${intent.action}]")
18+
}
19+
}
20+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.httpsms.services
2+
3+
import android.app.*
4+
import android.content.Context
5+
import android.content.Intent
6+
import android.graphics.Color
7+
import android.os.IBinder
8+
import android.widget.Toast
9+
import com.httpsms.MainActivity
10+
import com.httpsms.R
11+
import timber.log.Timber
12+
13+
class StickyNotificationService: Service() {
14+
override fun onBind(intent: Intent?): IBinder? {
15+
Timber.d("Some component want to bind with the service [${intent?.action}]")
16+
return null
17+
}
18+
19+
override fun onCreate() {
20+
Timber.d("The service has been created")
21+
super.onCreate()
22+
val notification = createNotification()
23+
startForeground(1, notification)
24+
}
25+
26+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
27+
Timber.d("onStartCommand executed with startId: $startId")
28+
// by returning this we make sure the service is restarted if the system kills the service
29+
return START_STICKY
30+
}
31+
32+
override fun onDestroy() {
33+
super.onDestroy()
34+
Timber.d("The service has been destroyed")
35+
Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show()
36+
}
37+
38+
39+
private fun createNotification(): Notification {
40+
val notificationChannelId = "sticky_notification_channel"
41+
42+
// depending on the Android API that we're dealing with we will have
43+
// to use a specific method to create the notification
44+
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
45+
val channel = NotificationChannel(
46+
notificationChannelId,
47+
notificationChannelId,
48+
NotificationManager.IMPORTANCE_HIGH
49+
).let {
50+
it.enableLights(true)
51+
it.enableVibration(false)
52+
it.lightColor = Color.RED
53+
it
54+
}
55+
notificationManager.createNotificationChannel(channel)
56+
57+
val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let {
58+
notificationIntent -> PendingIntent.getActivity(
59+
this,
60+
0,
61+
notificationIntent,
62+
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
63+
}
64+
65+
val builder: Notification.Builder = Notification.Builder(
66+
this,
67+
notificationChannelId
68+
)
69+
70+
return builder
71+
.setContentTitle("HTTP SMS")
72+
.setContentText("Service running in background")
73+
.setContentIntent(pendingIntent)
74+
.setSmallIcon(R.mipmap.ic_launcher)
75+
.setTicker("Ticker text")
76+
.build()
77+
}
78+
}

0 commit comments

Comments
 (0)