Notification settings for pre-Oreo android
This commit is contained in:
@@ -15,7 +15,7 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode gitCommits
|
||||
versionName '0.1.4'
|
||||
versionName '0.2-b1'
|
||||
|
||||
buildConfigField 'String', 'GIT_BRANCH', "\"${gitBranch}\""
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
@@ -47,11 +48,10 @@
|
||||
android:name=".ui.reader.SimpleSettingsActivity"
|
||||
android:label="@string/settings" />
|
||||
<activity android:name=".ui.browser.BrowserActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.utils.CrashActivity"
|
||||
android:theme="@android:style/Theme.DeviceDefault.Dialog"
|
||||
android:label="@string/error_occurred"
|
||||
android:theme="@android:style/Theme.DeviceDefault.Dialog"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
|
||||
<service
|
||||
@@ -59,16 +59,10 @@
|
||||
android:foregroundServiceType="dataSync" />
|
||||
<service android:name=".ui.settings.AppUpdateService" />
|
||||
|
||||
<service
|
||||
android:name=".ui.tracker.TrackerJobService"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
|
||||
<provider
|
||||
android:name=".ui.search.MangaSuggestionsProvider"
|
||||
android:authorities="${applicationId}.MangaSuggestionsProvider"
|
||||
android:exported="false" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.files"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>()
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -118,4 +118,8 @@
|
||||
<string name="download">Загрузить</string>
|
||||
<string name="read_from_start">Читать с начала</string>
|
||||
<string name="restart">Перезапустить</string>
|
||||
<string name="notifications_settings">Настройки уведомлений</string>
|
||||
<string name="notification_sound">Звук уведомления</string>
|
||||
<string name="light_indicator">Световая индикация</string>
|
||||
<string name="vibration">Вибросигнал</string>
|
||||
</resources>
|
||||
@@ -15,6 +15,10 @@
|
||||
<string name="key_app_update">app_update</string>
|
||||
<string name="key_app_update_auto">app_update_auto</string>
|
||||
<string name="key_tracker_notifications">tracker_notifications</string>
|
||||
<string name="key_notifications_settings">notifications_settings</string>
|
||||
<string name="key_notifications_sound">notifications_sound</string>
|
||||
<string name="key_notifications_vibrate">notifications_vibrate</string>
|
||||
<string name="key_notifications_light">notifications_light</string>
|
||||
|
||||
<string name="key_parser_domain">domain</string>
|
||||
<string-array name="values_theme">
|
||||
|
||||
@@ -119,4 +119,8 @@
|
||||
<string name="download">Download</string>
|
||||
<string name="read_from_start">Read from start</string>
|
||||
<string name="restart">Restart</string>
|
||||
<string name="notifications_settings">Notifications settings</string>
|
||||
<string name="notification_sound">Notification sound</string>
|
||||
<string name="light_indicator">Light indicator</string>
|
||||
<string name="vibration">Vibration</string>
|
||||
</resources>
|
||||
@@ -70,6 +70,12 @@
|
||||
android:title="@string/new_chapters"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<Preference
|
||||
android:title="@string/notifications_settings"
|
||||
app:iconSpaceReserved="false"
|
||||
android:dependency="@string/key_tracker_notifications"
|
||||
android:key="@string/key_notifications_settings" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
23
app/src/main/res/xml/pref_notifications.xml
Normal file
23
app/src/main/res/xml/pref_notifications.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Preference
|
||||
android:key="@string/key_notifications_sound"
|
||||
android:title="@string/notification_sound"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_notifications_vibrate"
|
||||
android:title="@string/vibration"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_notifications_light"
|
||||
android:title="@string/light_indicator"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
Reference in New Issue
Block a user