diff --git a/app/src/main/java/com/michatec/radio/MainActivity.kt b/app/src/main/java/com/michatec/radio/MainActivity.kt index 7e9dfa7..33e71c4 100644 --- a/app/src/main/java/com/michatec/radio/MainActivity.kt +++ b/app/src/main/java/com/michatec/radio/MainActivity.kt @@ -1,25 +1,30 @@ package com.michatec.radio import android.Manifest -import android.os.Build import android.content.Context +import android.content.Intent import android.content.SharedPreferences import android.content.pm.PackageManager import android.content.res.Configuration +import android.net.Uri +import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper +import android.provider.Settings import android.view.View +import android.widget.FrameLayout import androidx.activity.enableEdgeToEdge +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar +import androidx.core.app.ActivityCompat import androidx.core.view.isVisible import androidx.navigation.fragment.NavHostFragment -import androidx.activity.result.contract.ActivityResultContracts -import com.google.android.material.snackbar.Snackbar import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.navigateUp +import com.google.android.material.snackbar.Snackbar import com.michatec.radio.helpers.AppThemeHelper import com.michatec.radio.helpers.FileHelper import com.michatec.radio.helpers.LanguageHelper @@ -45,11 +50,24 @@ class MainActivity : AppCompatActivity() { ActivityResultContracts.RequestPermission() ) { isGranted -> if (!isGranted) { - Snackbar.make( + val snackbar = Snackbar.make( findViewById(android.R.id.content), - R.string.snackbar_failed_permission_notification, + R.string.snackbar_failed_permission_notification, Snackbar.LENGTH_LONG - ).show() + ) + val params = snackbar.view.layoutParams as FrameLayout.LayoutParams + params.bottomMargin = 300 + // If the user permanently denied the permission, show a link to settings + if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.POST_NOTIFICATIONS)) { + snackbar.setAction(R.string.fragment_settings_title) { + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", packageName, null) + } + startActivity(intent) + } + } + snackbar.view.layoutParams = params + snackbar.show() } } diff --git a/app/src/main/java/com/michatec/radio/NotificationSys.kt b/app/src/main/java/com/michatec/radio/NotificationSys.kt index 25cc636..6237291 100644 --- a/app/src/main/java/com/michatec/radio/NotificationSys.kt +++ b/app/src/main/java/com/michatec/radio/NotificationSys.kt @@ -6,21 +6,20 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent -import com.michatec.radio.R object NotificationSys { - private const val CHANNEL_ID = "com.michatec.radio.channel" + private const val CHANNEL_ID = "com.michatec.radio.channel_messages" private const val CHANNEL_NAME = "Notifications" - private const val NOTIFICATION_ID = 1001 + private const val NOTIFICATION_ID = 5000 fun createNotificationChannel(context: Context) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (notificationManager.getNotificationChannel(CHANNEL_ID) == null) { val channel = NotificationChannel( - CHANNEL_ID, - CHANNEL_NAME, - NotificationManager.IMPORTANCE_DEFAULT + CHANNEL_ID, + CHANNEL_NAME, + NotificationManager.IMPORTANCE_LOW ).apply { description = context.getString(R.string.notification_channel_description) } @@ -37,9 +36,9 @@ object NotificationSys { } val pendingIntent = PendingIntent.getActivity( - context, - 0, - targetIntent, + context, + 0, + targetIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) @@ -54,10 +53,4 @@ object NotificationSys { notificationManager.notify(NOTIFICATION_ID, notification) } - - fun showNotification(context: Context, titleResId: Int, contentResId: Int, intent: Intent? = null) { - val title = context.getString(titleResId) - val content = context.getString(contentResId) - showNotification(context, title, content, intent) - } } \ No newline at end of file diff --git a/app/src/main/java/com/michatec/radio/PlayerFragment.kt b/app/src/main/java/com/michatec/radio/PlayerFragment.kt index 5da5c8b..9352f49 100644 --- a/app/src/main/java/com/michatec/radio/PlayerFragment.kt +++ b/app/src/main/java/com/michatec/radio/PlayerFragment.kt @@ -1,5 +1,6 @@ package com.michatec.radio +import android.Manifest import android.app.Activity import android.content.ComponentName import android.content.Context @@ -13,6 +14,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResultLauncher @@ -60,7 +62,6 @@ import com.michatec.radio.extensions.* import com.michatec.radio.helpers.* import com.michatec.radio.ui.LayoutHolder import com.michatec.radio.ui.PlayerState -import com.michatec.radio.BuildConfig import kotlinx.coroutines.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main @@ -101,6 +102,10 @@ class PlayerFragment : Fragment(), context?.packageManager?.hasSystemFeature(PackageManager.FEATURE_LEANBACK) == true } + private fun isPermissionGranted(context: Context, permission: String): Boolean { + return context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED + } + /* Overrides onCreate from Fragment */ override fun onCreate(savedInstanceState: Bundle?) { @@ -840,7 +845,7 @@ class PlayerFragment : Fragment(), if (latestVersion != current && !BuildConfig.IS_DEBUG_ENABLED) { // We have an update available, tell our user about it view?.let { - Snackbar.make(it, getString(R.string.app_name) + " " + latestVersion + " " + getString(R.string.snackbar_update_available), 10000) + val snackbar = Snackbar.make(it, getString(R.string.app_name) + " " + latestVersion + " " + getString(R.string.snackbar_update_available), 10000) .setAction(R.string.snackbar_show) { val releaseurl = getString(R.string.snackbar_url_app_home_page) val i = Intent(Intent.ACTION_VIEW) @@ -853,17 +858,19 @@ class PlayerFragment : Fragment(), ContextCompat.getColor( requireActivity(), R.color.default_neutral_white)) - .show() - } - if (!isAndroidTV) { + if (!isAndroidTV) { + val params = snackbar.view.layoutParams as FrameLayout.LayoutParams + params.bottomMargin = 300 + snackbar.view.layoutParams = params + } + snackbar.show() + } + if (!isAndroidTV && isPermissionGranted(requireContext(), Manifest.permission.POST_NOTIFICATIONS)) { val releaseUrl = getString(R.string.snackbar_url_app_home_page) - - // Create the clean browser intent that will trigger ONLY when the notification is tapped - val updateIntent = Intent(Intent.ACTION_VIEW, Uri.parse(releaseUrl)).apply { + val updateIntent = Intent(Intent.ACTION_VIEW, releaseUrl.toUri()).apply { putExtra("SOURCE", "SELF") } - NotificationSys.showNotification( requireContext(), "${getString(R.string.app_name)} $latestVersion", diff --git a/app/src/main/java/com/michatec/radio/SettingsFragment.kt b/app/src/main/java/com/michatec/radio/SettingsFragment.kt index 110f316..124b41c 100644 --- a/app/src/main/java/com/michatec/radio/SettingsFragment.kt +++ b/app/src/main/java/com/michatec/radio/SettingsFragment.kt @@ -22,7 +22,6 @@ import com.michatec.radio.dialogs.PresetSelectionDialog import com.michatec.radio.dialogs.ThemeSelectionDialog import com.michatec.radio.dialogs.YesNoDialog import com.michatec.radio.helpers.* -import com.michatec.radio.NotificationSys import android.content.pm.PackageManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers.IO @@ -45,6 +44,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList context?.packageManager?.hasSystemFeature(PackageManager.FEATURE_LEANBACK) == true } + private fun isPermissionGranted(context: Context, permission: String): Boolean { + return context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED + } + /* Overrides onViewCreated from PreferenceFragmentCompat */ override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -386,7 +389,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList preferenceCategoryGeneral.addPreference(preferenceThemeSelection) preferenceCategoryGeneral.addPreference(preferenceLanguageSelection) - if (!isAndroidTV) { + if (!isAndroidTV && isPermissionGranted(activity as Context, android.Manifest.permission.POST_NOTIFICATIONS)) { preferenceCategoryGeneral.addPreference(preferenceTestNotification) } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e0b890a..a574d07 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,6 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="?android:attr/colorBackground" + android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize" android:fitsSystemWindows="true" tools:context=".MainActivity">