Notification settings for pre-Oreo android

This commit is contained in:
Koitharu
2020-04-12 09:58:20 +03:00
parent 12b13f98f8
commit 3014ebdfd4
14 changed files with 185 additions and 22 deletions

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.prefs
import android.content.Context
import android.content.SharedPreferences
import android.content.res.Resources
import android.provider.Settings
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager
import org.koitharu.kotatsu.R
@@ -57,6 +58,21 @@ class AppSettings private constructor(resources: Resources, private val prefs: S
true
)
var notificationSound by StringPreferenceDelegate(
resources.getString(R.string.key_notifications_sound),
Settings.System.DEFAULT_NOTIFICATION_URI.toString()
)
val notificationVibrate by BoolPreferenceDelegate(
resources.getString(R.string.key_notifications_vibrate),
false
)
val notificationLight by BoolPreferenceDelegate(
resources.getString(R.string.key_notifications_light),
true
)
private var sourcesOrderStr by NullableStringPreferenceDelegate(resources.getString(R.string.key_sources_order))
var sourcesOrder: List<Int>

View File

@@ -3,12 +3,11 @@ package org.koitharu.kotatsu.ui.common
import androidx.annotation.StringRes
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.koin.android.ext.android.inject
import org.koitharu.kotatsu.core.prefs.AppSettings
abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
PreferenceFragmentCompat(), KoinComponent {
PreferenceFragmentCompat() {
protected val settings by inject<AppSettings>()

View File

@@ -1,7 +1,10 @@
package org.koitharu.kotatsu.ui.settings
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.arrayMapOf
@@ -15,6 +18,8 @@ import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.ui.common.BasePreferenceFragment
import org.koitharu.kotatsu.ui.main.list.ListModeSelectDialog
import org.koitharu.kotatsu.ui.settings.utils.MultiSummaryProvider
import org.koitharu.kotatsu.ui.tracker.TrackWorker
class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
SharedPreferences.OnSharedPreferenceChangeListener {
@@ -70,6 +75,17 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
ListModeSelectDialog.show(childFragmentManager)
true
}
getString(R.string.key_notifications_settings) -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
.putExtra(Settings.EXTRA_CHANNEL_ID, TrackWorker.CHANNEL_ID)
startActivity(intent)
} else {
(activity as? SettingsActivity)?.openNotificationSettingsLegacy()
}
true
}
else -> super.onPreferenceTreeClick(preference)
}
}

View File

@@ -0,0 +1,66 @@
package org.koitharu.kotatsu.ui.settings
import android.app.Activity
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import androidx.preference.Preference
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.ui.common.BasePreferenceFragment
import org.koitharu.kotatsu.utils.ext.toUriOrNull
class NotificationSettingsLegacyFragment : BasePreferenceFragment(R.string.notifications) {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_notifications)
findPreference<Preference>(R.string.key_notifications_sound)?.run {
val uri = settings.notificationSound.toUriOrNull()
summary = RingtoneManager.getRingtone(context, uri).getTitle(context)
}
}
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
return when (preference?.key) {
getString(R.string.key_notifications_sound) -> {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_NOTIFICATION)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
Settings.System.DEFAULT_NOTIFICATION_URI)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, preference.title)
val existingValue = settings.notificationSound.toUriOrNull()
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, existingValue)
startActivityForResult(intent, REQUEST_RINGTONE)
true
}
else -> super.onPreferenceTreeClick(preference)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_RINGTONE -> {
if (resultCode == Activity.RESULT_OK) {
val uri =
data?.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
settings.notificationSound = uri?.toString().orEmpty()
findPreference<Preference>(R.string.key_notifications_sound)?.run {
summary = RingtoneManager.getRingtone(context, uri).getTitle(context)
}
}
}
else -> {
super.onActivityResult(requestCode, resultCode, data)
}
}
}
private companion object {
const val REQUEST_RINGTONE = 340
}
}

View File

@@ -3,6 +3,9 @@ package org.koitharu.kotatsu.ui.settings
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.transition.Slide
import android.view.Gravity
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
@@ -20,7 +23,9 @@ class SettingsActivity : BaseActivity(),
if (supportFragmentManager.findFragmentById(R.id.container) == null) {
supportFragmentManager.commit {
replace(R.id.container, MainSettingsFragment())
replace(R.id.container, MainSettingsFragment().also {
it.exitTransition = Slide(Gravity.START)
})
}
}
}
@@ -30,16 +35,23 @@ class SettingsActivity : BaseActivity(),
val fragment = fm.fragmentFactory.instantiate(classLoader, pref.fragment)
fragment.arguments = pref.extras
fragment.setTargetFragment(caller, 0)
fm.commit {
replace(R.id.container, fragment)
addToBackStack(null)
}
openFragment(fragment)
return true
}
fun openMangaSourceSettings(mangaSource: MangaSource) {
openFragment(SourceSettingsFragment.newInstance(mangaSource))
}
fun openNotificationSettingsLegacy() {
openFragment(NotificationSettingsLegacyFragment())
}
private fun openFragment(fragment: Fragment) {
fragment.enterTransition = Slide(Gravity.END)
fragment.exitTransition = Slide(Gravity.START)
supportFragmentManager.commit {
replace(R.id.container, SourceSettingsFragment.newInstance(mangaSource))
replace(R.id.container, fragment)
addToBackStack(null)
}
}

View File

@@ -24,6 +24,7 @@ import org.koitharu.kotatsu.domain.MangaProviderFactory
import org.koitharu.kotatsu.domain.tracking.TrackingRepository
import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
import org.koitharu.kotatsu.utils.ext.safe
import org.koitharu.kotatsu.utils.ext.toUriOrNull
import java.util.concurrent.TimeUnit
class TrackWorker(context: Context, workerParams: WorkerParameters) :
@@ -151,8 +152,19 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
intent, PendingIntent.FLAG_UPDATE_CURRENT))
setAutoCancel(true)
color = colorPrimary
setLights(colorPrimary, 1000, 5000)
setPriority(NotificationCompat.PRIORITY_DEFAULT)
priority = NotificationCompat.PRIORITY_DEFAULT
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
builder.setSound(settings.notificationSound.toUriOrNull())
var defaults = if (settings.notificationLight) {
setLights(colorPrimary, 1000, 5000)
NotificationCompat.DEFAULT_LIGHTS
} else 0
if (settings.notificationVibrate) {
builder.setVibrate(longArrayOf(500, 500, 500, 500))
defaults = defaults or NotificationCompat.DEFAULT_VIBRATE
}
builder.setDefaults(defaults)
}
}
withContext(Dispatchers.Main) {
notificationManager.notify(TAG, id, builder.build())
@@ -161,7 +173,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
companion object {
private const val CHANNEL_ID = "tracking"
const val CHANNEL_ID = "tracking"
private const val TAG = "tracking"
@RequiresApi(Build.VERSION_CODES.O)

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.utils.ext
import android.net.Uri
import java.net.URLEncoder
fun String.longHashCode(): Long {
@@ -65,4 +66,10 @@ fun String.ellipsize(maxLength: Int) = if (this.length > maxLength) {
this.take(maxLength - 1) + Typography.ellipsis
} else this
fun String.urlEncoded(): String = URLEncoder.encode(this, Charsets.UTF_8.name())
fun String.urlEncoded(): String = URLEncoder.encode(this, Charsets.UTF_8.name())
fun String.toUriOrNull(): Uri? = if (isEmpty()) {
null
} else {
Uri.parse(this)
}