mirror of
https://github.com/Matte23/circolapp.git
synced 2025-12-06 07:29:10 +00:00
Add push notifications
This commit is contained in:
@@ -2,6 +2,7 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||
|
||||
android {
|
||||
@@ -39,7 +40,7 @@ dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.3.2'
|
||||
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.3'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
|
||||
@@ -60,4 +61,7 @@ dependencies {
|
||||
implementation 'com.github.tiper:MaterialSpinner:1.4.2'
|
||||
implementation "com.mikepenz:aboutlibraries-core:$about_libs_version"
|
||||
implementation "com.mikepenz:aboutlibraries:$about_libs_version"
|
||||
|
||||
implementation platform('com.google.firebase:firebase-bom:26.0.0')
|
||||
implementation 'com.google.firebase:firebase-messaging-ktx'
|
||||
}
|
||||
|
||||
@@ -37,7 +37,21 @@
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".AlarmBroadcastReceiver" />
|
||||
|
||||
<service
|
||||
android:name=".push.CircolappFirebaseMessagingService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/ic_notification" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -18,12 +18,14 @@
|
||||
|
||||
package net.underdesk.circolapp
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.preference.*
|
||||
import kotlinx.android.synthetic.main.settings_activity.*
|
||||
import net.underdesk.circolapp.push.FirebaseTopicUtils
|
||||
import net.underdesk.circolapp.server.ServerAPI
|
||||
import net.underdesk.circolapp.works.PollWork
|
||||
|
||||
@@ -40,15 +42,19 @@ class SettingsActivity : AppCompatActivity() {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
}
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
class SettingsFragment : PreferenceFragmentCompat(),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
||||
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
val schoolPreference = findPreference<ListPreference>("school")
|
||||
schoolPreference?.let { setSchoolListPreference(it) }
|
||||
val schoolPreferenceListener =
|
||||
Preference.OnPreferenceChangeListener { _, value ->
|
||||
ServerAPI.changeServer(value.toString().toInt())
|
||||
ServerAPI.changeServer(value.toString().toInt(), requireContext())
|
||||
true
|
||||
}
|
||||
schoolPreference?.onPreferenceChangeListener = schoolPreferenceListener
|
||||
@@ -69,17 +75,6 @@ class SettingsActivity : AppCompatActivity() {
|
||||
pollIntervalPreference?.setOnBindEditTextListener { editText ->
|
||||
editText.inputType = InputType.TYPE_CLASS_NUMBER
|
||||
}
|
||||
|
||||
val notificationPreference =
|
||||
findPreference<SwitchPreferenceCompat>("notify_new_circulars")
|
||||
|
||||
val notificationPrefChangedListener =
|
||||
Preference.OnPreferenceChangeListener { _, _ ->
|
||||
activity?.let { PollWork.enqueue(it) }
|
||||
true
|
||||
}
|
||||
pollIntervalPreference?.onPreferenceChangeListener = notificationPrefChangedListener
|
||||
notificationPreference?.onPreferenceChangeListener = notificationPrefChangedListener
|
||||
}
|
||||
|
||||
private fun setSchoolListPreference(listPreference: ListPreference) {
|
||||
@@ -96,5 +91,31 @@ class SettingsActivity : AppCompatActivity() {
|
||||
listPreference.entryValues = entryValues.toTypedArray()
|
||||
listPreference.entries = entryNames.toTypedArray()
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(
|
||||
sharedPreferences: SharedPreferences?,
|
||||
key: String?
|
||||
) {
|
||||
if (key != "notify_new_circulars" && key != "enable_polling" && key != "poll_interval")
|
||||
return
|
||||
|
||||
if (sharedPreferences == null)
|
||||
return
|
||||
|
||||
activity?.let { PollWork.enqueue(it) }
|
||||
|
||||
if (sharedPreferences.getBoolean(
|
||||
"notify_new_circulars",
|
||||
true
|
||||
) && !sharedPreferences.getBoolean("enable_polling", false)
|
||||
) {
|
||||
val serverID = ServerAPI.getInstance(requireContext()).serverID()
|
||||
val serverToken = ServerAPI.Companion.Servers.values()[serverID].toString()
|
||||
|
||||
FirebaseTopicUtils.selectTopic(serverToken, requireContext())
|
||||
} else {
|
||||
FirebaseTopicUtils.unsubscribe(requireContext())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class SchoolSelectionFragment : Fragment(), SlidePolicy, MaterialSpinner.OnItemS
|
||||
editor.putString("school", position.toString())
|
||||
editor.apply()
|
||||
|
||||
ServerAPI.changeServer(position)
|
||||
ServerAPI.changeServer(position, requireContext())
|
||||
schoolSelected = true
|
||||
|
||||
parent.error = null
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.underdesk.circolapp.push
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.google.firebase.messaging.RemoteMessage
|
||||
import net.underdesk.circolapp.works.PollWork
|
||||
|
||||
// We don't need to get an Instance Token for topic notifications
|
||||
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
|
||||
class CircolappFirebaseMessagingService : FirebaseMessagingService() {
|
||||
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
||||
if (remoteMessage.data.isNotEmpty()) {
|
||||
PollWork.runWork(applicationContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.underdesk.circolapp.push
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import com.google.firebase.messaging.ktx.messaging
|
||||
|
||||
class FirebaseTopicUtils {
|
||||
companion object {
|
||||
fun selectTopic(newTopic: String, context: Context) {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
unsubscribeFromTopic(sharedPreferences)
|
||||
|
||||
Firebase.messaging.subscribeToTopic(newTopic)
|
||||
|
||||
sharedPreferences.edit {
|
||||
putString("topic", newTopic)
|
||||
}
|
||||
}
|
||||
|
||||
fun unsubscribe(context: Context) {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
unsubscribeFromTopic(sharedPreferences)
|
||||
|
||||
sharedPreferences.edit {
|
||||
putString("topic", null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun unsubscribeFromTopic(sharedPreferences: SharedPreferences) {
|
||||
val oldTopic = sharedPreferences.getString("topic", null)
|
||||
oldTopic?.let { Firebase.messaging.unsubscribeFromTopic(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package net.underdesk.circolapp.server
|
||||
import android.content.Context
|
||||
import androidx.preference.PreferenceManager
|
||||
import net.underdesk.circolapp.data.Circular
|
||||
import net.underdesk.circolapp.push.FirebaseTopicUtils
|
||||
import net.underdesk.circolapp.server.curie.CurieServer
|
||||
import net.underdesk.circolapp.server.porporato.PorporatoServer
|
||||
|
||||
@@ -84,8 +85,18 @@ class ServerAPI(
|
||||
}
|
||||
}
|
||||
|
||||
fun changeServer(index: Int) {
|
||||
instance?.changeServer(createServer(Servers.values()[index]))
|
||||
fun changeServer(index: Int, context: Context) {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val newServer = Servers.values()[index]
|
||||
|
||||
if (sharedPreferences.getBoolean(
|
||||
"notify_new_circulars",
|
||||
true
|
||||
) && !sharedPreferences.getBoolean("enable_polling", false)
|
||||
)
|
||||
FirebaseTopicUtils.selectTopic(newServer.toString(), context)
|
||||
|
||||
instance?.changeServer(createServer(newServer))
|
||||
}
|
||||
|
||||
private fun createServer(server: Servers) = when (server) {
|
||||
|
||||
@@ -65,7 +65,11 @@ class PollWork(appContext: Context, workerParams: WorkerParameters) :
|
||||
fun enqueue(context: Context) {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
if (sharedPreferences.getBoolean("notify_new_circulars", true)) {
|
||||
if (sharedPreferences.getBoolean(
|
||||
"notify_new_circulars",
|
||||
true
|
||||
) && sharedPreferences.getBoolean("enable_polling", false)
|
||||
) {
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniquePeriodicWork(
|
||||
pollWorkName,
|
||||
@@ -82,6 +86,11 @@ class PollWork(appContext: Context, workerParams: WorkerParameters) :
|
||||
.cancelUniqueWork(pollWorkName)
|
||||
}
|
||||
}
|
||||
|
||||
fun runWork(context: Context) {
|
||||
val oneTimeWork = OneTimeWorkRequestBuilder<PollWork>().build()
|
||||
WorkManager.getInstance(context).enqueue(oneTimeWork)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun doWork(): Result = coroutineScope {
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
<string name="preferences_school">Scuola</string>
|
||||
<string name="preferences_dark_theme">Tema scuro</string>
|
||||
<string name="preferences_notify_new_circulars">Mostra notifiche</string>
|
||||
<string name="preferences_polling">Esegui controllo dal telefono</string>
|
||||
<string name="preferences_poll_interval">Intervallo di sincronizzazione</string>
|
||||
<string name="preferences_notify_new_circulars_summary">Mostra una notifica quando una nuova circolare è pubblicata</string>
|
||||
<string name="preferences_polling_summary">Sconsigliato. Disabilitare questa opzione per utilizzare le notifiche push</string>
|
||||
<string name="preferences_poll_interval_summary">Quanto tempo attendere tra una sincronizzazione ed un altra</string>
|
||||
|
||||
<string name="notification_title">Circolare numero %1$d</string>
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
<string name="preferences_school">School</string>
|
||||
<string name="preferences_dark_theme">Dark theme</string>
|
||||
<string name="preferences_notify_new_circulars">Show notifications</string>
|
||||
<string name="preferences_polling">Run checks from this device</string>
|
||||
<string name="preferences_poll_interval">Synchronization interval</string>
|
||||
<string name="preferences_notify_new_circulars_summary">Show a notification when a new circular is published</string>
|
||||
<string name="preferences_polling_summary">Not recommended. Disable this option to use push notifications</string>
|
||||
<string name="preferences_poll_interval_summary">How long to wait before checking if new circulars are published</string>
|
||||
|
||||
<string name="notification_title">Circular letter number %1$d</string>
|
||||
|
||||
@@ -26,9 +26,16 @@
|
||||
app:key="notify_new_circulars"
|
||||
app:title="@string/preferences_notify_new_circulars" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:summary="@string/preferences_polling_summary"
|
||||
app:dependency="notify_new_circulars"
|
||||
app:key="enable_polling"
|
||||
app:title="@string/preferences_polling" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="15"
|
||||
android:dependency="notify_new_circulars"
|
||||
android:dependency="enable_polling"
|
||||
android:key="poll_interval"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
|
||||
@@ -15,6 +15,7 @@ buildscript {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:$about_libs_version"
|
||||
classpath "org.jlleitschuh.gradle:ktlint-gradle:9.4.0"
|
||||
classpath 'com.google.gms:google-services:4.3.4'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user