diff --git a/app/build.gradle b/app/build.gradle
index 90dc1edb1e394d81e58d1843e02b45cfec6d41a4..f2296189ed9aaf65089ae40c135c41dcceda5b60 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,7 +11,7 @@ android {
defaultConfig {
applicationId "io.heckel.ntfy"
- minSdkVersion 21
+ minSdkVersion 23
targetSdkVersion 33
versionCode 33
@@ -27,6 +27,10 @@ android {
}
}
+ buildFeatures {
+ viewBinding = true
+ }
+
buildTypes {
release {
minifyEnabled true
@@ -128,4 +132,6 @@ dependencies {
// Image viewer
implementation 'com.github.stfalcon-studio:StfalconImageViewer:v1.0.1'
+
+ implementation 'foundation.e:elib:0.0.1-alpha11'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0950b404e8f7b24ac9a876a7fb9dde05e90b2f66..3fbe55942c7878d0f1b41ae1b8ea2c56e7632a39 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,7 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ package="io.heckel.ntfy">
@@ -25,6 +26,7 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
+ android:persistent="true"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme"
@@ -35,10 +37,10 @@
+ android:excludeFromRecents="true"
+ android:exported="true">
-
@@ -175,5 +177,27 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt b/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt
index 192cfc9ff92c5440d4a78c4a114b7fa7cc58817c..a70acf091579a31886869bde6f98c6c69b6cd534 100644
--- a/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt
+++ b/app/src/main/java/io/heckel/ntfy/service/SubscriberService.kt
@@ -10,6 +10,7 @@ import android.os.PowerManager
import android.os.SystemClock
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
+import androidx.preference.PreferenceManager
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
@@ -88,23 +89,16 @@ class SubscriberService : Service() {
Log.init(this) // Init logs in all entry points
Log.d(TAG, "Subscriber service has been created")
-
- val title = getString(R.string.channel_subscriber_notification_title)
- val text = if (BuildConfig.FIREBASE_AVAILABLE) {
- getString(R.string.channel_subscriber_notification_instant_text)
- } else {
- getString(R.string.channel_subscriber_notification_noinstant_text)
- }
- notificationManager = createNotificationChannel()
- serviceNotification = createNotification(title, text)
-
- startForeground(NOTIFICATION_SERVICE_ID, serviceNotification)
}
override fun onDestroy() {
Log.d(TAG, "Subscriber service has been destroyed")
stopService()
- sendBroadcast(Intent(this, AutoRestartReceiver::class.java)) // Restart it if necessary!
+ val preferenceKey = getString(R.string.eos_preference_key_is_enabled)
+ if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(preferenceKey, false)) {
+ sendBroadcast(Intent(this, AutoRestartReceiver::class.java))
+ }
+
super.onDestroy()
}
@@ -138,7 +132,6 @@ class SubscriberService : Service() {
}
}
wakeLock = null
- stopForeground(true)
stopSelf()
} catch (e: Exception) {
Log.d(TAG, "Service stopped without being started: ${e.message}")
diff --git a/app/src/main/java/io/heckel/ntfy/service/SubscriberServiceManager.kt b/app/src/main/java/io/heckel/ntfy/service/SubscriberServiceManager.kt
index ed4dfda755aa6f1007335437b32c7c46a5969438..18ed4f947a02cc5e22e8cc0619e804b8816cbb7b 100644
--- a/app/src/main/java/io/heckel/ntfy/service/SubscriberServiceManager.kt
+++ b/app/src/main/java/io/heckel/ntfy/service/SubscriberServiceManager.kt
@@ -2,10 +2,11 @@ package io.heckel.ntfy.service
import android.content.Context
import android.content.Intent
-import androidx.core.content.ContextCompat
+import androidx.preference.PreferenceManager
import androidx.work.*
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.util.Log
+import io.heckel.ntfy.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -43,11 +44,17 @@ class SubscriberServiceManager(private val context: Context) {
Log.d(TAG, "ServiceStartWorker: Failed, no application found (work ID: ${id})")
return Result.failure()
}
+
withContext(Dispatchers.IO) {
val app = context.applicationContext as Application
- val subscriptionIdsWithInstantStatus = app.repository.getSubscriptionIdsWithInstantStatus()
- val instantSubscriptions = subscriptionIdsWithInstantStatus.toList().filter { (_, instant) -> instant }.size
- val action = if (instantSubscriptions > 0) SubscriberService.Action.START else SubscriberService.Action.STOP
+ val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(app)
+ val preferenceKey = context.getString(R.string.eos_preference_key_is_enabled)
+ val action = if (sharedPreferences.getBoolean(preferenceKey, false)) {
+ SubscriberService.Action.START
+ } else {
+ SubscriberService.Action.STOP
+ }
+
val serviceState = SubscriberService.readServiceState(context)
if (serviceState == SubscriberService.ServiceState.STOPPED && action == SubscriberService.Action.STOP) {
return@withContext Result.success()
@@ -55,7 +62,7 @@ class SubscriberServiceManager(private val context: Context) {
Log.d(TAG, "ServiceStartWorker: Starting foreground service with action $action (work ID: ${id})")
Intent(context, SubscriberService::class.java).also {
it.action = action.name
- ContextCompat.startForegroundService(context, it)
+ context.startService(it)
}
}
return Result.success()
diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainSettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainSettingsActivity.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1aabb1a1edbbf24cd4ec0e5ec29a17e3fefac921
--- /dev/null
+++ b/app/src/main/java/io/heckel/ntfy/ui/MainSettingsActivity.kt
@@ -0,0 +1,71 @@
+package io.heckel.ntfy.ui
+
+import android.content.res.Configuration
+import android.os.Build
+import android.os.Bundle
+import android.view.WindowInsetsController
+import androidx.annotation.RequiresApi
+import androidx.appcompat.app.AppCompatActivity
+import io.heckel.ntfy.R
+import io.heckel.ntfy.databinding.MainSettingsActivityBinding
+
+class MainSettingsActivity : AppCompatActivity() {
+
+ private lateinit var mBinding: MainSettingsActivityBinding
+
+ @RequiresApi(Build.VERSION_CODES.R)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ mBinding = MainSettingsActivityBinding.inflate(layoutInflater)
+ setContentView(mBinding.root)
+
+ setupToolbar()
+ setSystemBarsAppearance()
+ showPreferencesFragment()
+ }
+
+ private fun setupToolbar() {
+ mBinding.toolbar.setNavigationOnClickListener {
+ onBackPressedDispatcher.onBackPressed()
+ }
+ }
+
+ @RequiresApi(Build.VERSION_CODES.R)
+ private fun setSystemBarsAppearance() {
+ val insetsController = window.insetsController ?: return
+
+ val isLightMode = isSystemInLightMode()
+ if (isLightMode) {
+ insetsController.setSystemBarsAppearance(
+ WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
+ WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+ )
+ insetsController.setSystemBarsAppearance(
+ WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS,
+ WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+ )
+ } else {
+ insetsController.setSystemBarsAppearance(
+ 0,
+ WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
+ )
+ insetsController.setSystemBarsAppearance(
+ 0,
+ WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+ )
+ }
+ }
+
+ private fun isSystemInLightMode(): Boolean {
+ val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+ return nightModeFlags != Configuration.UI_MODE_NIGHT_YES
+ }
+
+ private fun showPreferencesFragment() {
+ supportFragmentManager
+ .beginTransaction()
+ .replace(R.id.fragment_container, PreferencesFragment())
+ .commit()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/heckel/ntfy/ui/PreferencesFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/PreferencesFragment.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2bc5e30d5b7daf574b5e06edb34adcee18344264
--- /dev/null
+++ b/app/src/main/java/io/heckel/ntfy/ui/PreferencesFragment.kt
@@ -0,0 +1,37 @@
+package io.heckel.ntfy.ui
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import android.widget.Toolbar
+import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.SwitchPreferenceCompat
+import io.heckel.ntfy.R
+import io.heckel.ntfy.service.SubscriberService
+import io.heckel.ntfy.util.Log
+
+class PreferencesFragment : PreferenceFragmentCompat() {
+
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ setPreferencesFromResource(R.xml.settings_preferences, rootKey)
+
+ val preference: SwitchPreferenceCompat? =
+ findPreference(getString(R.string.eos_preference_key_is_enabled))
+
+ preference?.setOnPreferenceChangeListener { _, newValue ->
+ val isChecked = newValue as Boolean
+ val intent = Intent(context, SubscriberService::class.java)
+ intent.action = if (isChecked) {
+ SubscriberService.Action.START.name
+ } else {
+ SubscriberService.Action.STOP.name
+ }
+
+ requireContext().startService(intent)
+ true
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml
index d02140aa2ccdf137a1399e6b4d23b175a17175d8..900100ba1745a94bf570a455e6b90cb43a170a85 100644
--- a/app/src/main/res/drawable/ic_notification.xml
+++ b/app/src/main/res/drawable/ic_notification.xml
@@ -1,31 +1,31 @@
diff --git a/app/src/main/res/layout/main_settings_activity.xml b/app/src/main/res/layout/main_settings_activity.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06731953cf289eaa9e472b1266409a8de5ef8258
--- /dev/null
+++ b/app/src/main/res/layout/main_settings_activity.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index a9c38b99a4da76d4af98d4ff18375fb78b67aeeb..3b0739f900ba75baa3eb6ce6cd734c7c3921db12 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -343,4 +343,6 @@
ntfy arbeitet nicht als UnifiedPush-Distributor
UnifiedPush aktivieren
ntfy arbeitet als UnifiedPush-Distributor
+ UnifiedPush-Distributor aktivieren
+ Es ermöglicht Drittanbieteranwendungen, UnifiedPush-Benachrichtigungen zu empfangen
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 0bda4a7a07753dbf6eb2f0beba1a67fe2f91beac..a08c19eba9fc30b93b6e2480d3c4458be09a28f1 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -343,4 +343,6 @@
Activar UnifiedPush
ntfy actuará como distribuidor UnifiedPush
ntfy no actuará como distribuidor UnifiedPush
+ Habilitar el distribuidor de UnifiedPush
+ Permite a las aplicaciones de terceros recibir notificaciones de UnifiedPush
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 348eecc25568c6f9dd977e788503e3f2f8253b7a..0fa51abd69ab734d003bae120202bce740f5d76d 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -343,4 +343,6 @@
ntfy agira comme un distributeur UnifiedPush
ntfy n\'agira pas comme un distributeur UnifiedPush
Activer le \"UnifiedPush\"
+ Activer le distributeur UnifiedPush
+ Cela permet aux applications tierces de recevoir des notifications UnifiedPush
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 703806f4e65f517ec092b102a229bf264a51d85c..453967a408d9d4dd75c60912ba5b514ae7f91537 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -330,4 +330,6 @@
Default
Dona 💸
Le app non possono più essere installate: devono essere scaricate via browser. Vedi l\'issue #531 per dettagli.
+ Abilita il distributore UnifiedPush
+ Consente alle applicazioni di terze parti di ricevere notifiche UnifiedPush
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c775990100879de1a3126eb45d46076f4cb7308e..1d08618498883c9b39bbeb99e8950c660b775cd1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -391,4 +391,10 @@
Cancel
Delete user
Save
+
+
+ isEnabled
+ UnifiedPush
+ Enable UnifiedPush distributor
+ It allows 3rd party applications to receive UnifiedPush notifications
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 4f0902d86c37b4b055f690801a4fa78c2764b37a..e7244948e0c527ee38747b05e0f3f00935cf5c2b 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -30,4 +30,26 @@
- rounded
- 5dp
+
+
+
+
diff --git a/app/src/main/res/xml/settings_preferences.xml b/app/src/main/res/xml/settings_preferences.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6b02c9c4692b64f010b6da9bbd2231194cf530e7
--- /dev/null
+++ b/app/src/main/res/xml/settings_preferences.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index fd5080038eb076866b6cc531c0d735ae85a493bb..865925819673184777014125ac237b235d5f7ba1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,6 +18,7 @@ allprojects {
repositories {
google()
mavenCentral()
+ maven { url 'https://gitlab.e.foundation/api/v4/groups/9/-/packages/maven'}
maven { url "https://jitpack.io" } // For StfalconImageViewer
}
}