diff --git a/app/build.gradle b/app/build.gradle
index e554faf..1fee1e8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6de74d8..06e2848 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -37,7 +37,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/net/underdesk/circolapp/SettingsActivity.kt b/app/src/main/java/net/underdesk/circolapp/SettingsActivity.kt
index 1ec04d0..9c0d239 100644
--- a/app/src/main/java/net/underdesk/circolapp/SettingsActivity.kt
+++ b/app/src/main/java/net/underdesk/circolapp/SettingsActivity.kt
@@ -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("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("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())
+ }
+ }
}
}
diff --git a/app/src/main/java/net/underdesk/circolapp/fragments/intro/SchoolSelectionFragment.kt b/app/src/main/java/net/underdesk/circolapp/fragments/intro/SchoolSelectionFragment.kt
index 47ca124..629ab88 100644
--- a/app/src/main/java/net/underdesk/circolapp/fragments/intro/SchoolSelectionFragment.kt
+++ b/app/src/main/java/net/underdesk/circolapp/fragments/intro/SchoolSelectionFragment.kt
@@ -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
diff --git a/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt b/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt
new file mode 100644
index 0000000..9d4cc3c
--- /dev/null
+++ b/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt
@@ -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)
+ }
+ }
+}
diff --git a/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt b/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt
new file mode 100644
index 0000000..aec89ed
--- /dev/null
+++ b/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt
@@ -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) }
+ }
+ }
+}
diff --git a/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt b/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt
index 9577509..503ae9f 100644
--- a/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt
+++ b/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt
@@ -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) {
diff --git a/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt b/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt
index ce1f13d..8e61ef6 100644
--- a/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt
+++ b/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt
@@ -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().build()
+ WorkManager.getInstance(context).enqueue(oneTimeWork)
+ }
}
override suspend fun doWork(): Result = coroutineScope {
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index b1d8eed..b82a60e 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -15,8 +15,10 @@
Scuola
Tema scuro
Mostra notifiche
+ Esegui controllo dal telefono
Intervallo di sincronizzazione
Mostra una notifica quando una nuova circolare รจ pubblicata
+ Sconsigliato. Disabilitare questa opzione per utilizzare le notifiche push
Quanto tempo attendere tra una sincronizzazione ed un altra
Circolare numero %1$d
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4a031b0..0644e4f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,8 +15,10 @@
School
Dark theme
Show notifications
+ Run checks from this device
Synchronization interval
Show a notification when a new circular is published
+ Not recommended. Disable this option to use push notifications
How long to wait before checking if new circulars are published
Circular letter number %1$d
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index 9c3cb6c..8db44a9 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -26,9 +26,16 @@
app:key="notify_new_circulars"
app:title="@string/preferences_notify_new_circulars" />
+
+