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 } }