Split up ContextExtensions into smaller files
This commit is contained in:
parent
859601a46e
commit
d703fb7946
@ -1,14 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.util.system
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Build
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether if the device has a display cutout (i.e. notch, camera cutout, etc.).
|
|
||||||
*
|
|
||||||
* Only works in Android 9+.
|
|
||||||
*/
|
|
||||||
fun Activity.hasDisplayCutout(): Boolean {
|
|
||||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P &&
|
|
||||||
window.decorView.rootWindowInsets?.displayCutout != null
|
|
||||||
}
|
|
@ -1,10 +1,18 @@
|
|||||||
package eu.kanade.tachiyomi.util.system
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.provider.Settings
|
||||||
import android.view.ViewPropertyAnimator
|
import android.view.ViewPropertyAnimator
|
||||||
import android.view.animation.Animation
|
import android.view.animation.Animation
|
||||||
import androidx.constraintlayout.motion.widget.MotionScene.Transition
|
import androidx.constraintlayout.motion.widget.MotionScene.Transition
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the duration multiplier for general animations on the device
|
||||||
|
* @see Settings.Global.ANIMATOR_DURATION_SCALE
|
||||||
|
*/
|
||||||
|
val Context.animatorDurationScale: Float
|
||||||
|
get() = Settings.Global.getFloat(this.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f)
|
||||||
|
|
||||||
/** Scale the duration of this [Animation] by [Context.animatorDurationScale] */
|
/** Scale the duration of this [Animation] by [Context.animatorDurationScale] */
|
||||||
fun Animation.applySystemAnimatorScale(context: Context) {
|
fun Animation.applySystemAnimatorScale(context: Context) {
|
||||||
this.duration = (this.duration * context.animatorDurationScale).toLong()
|
this.duration = (this.duration * context.animatorDurationScale).toLong()
|
||||||
|
@ -1,27 +1,18 @@
|
|||||||
package eu.kanade.tachiyomi.util.system
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.content.res.Resources
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.net.NetworkCapabilities
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.net.wifi.WifiManager
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.provider.Settings
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.Display
|
|
||||||
import android.view.View
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.view.ContextThemeWrapper
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
@ -34,7 +25,6 @@ import androidx.core.graphics.red
|
|||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
import eu.kanade.domain.ui.model.TabletUiMode
|
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
|
import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
|
||||||
@ -112,44 +102,9 @@ fun Context.hasPermission(permission: String) = PermissionChecker.checkSelfPermi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts to px and takes into account LTR/RTL layout.
|
|
||||||
*/
|
|
||||||
val Float.dpToPxEnd: Float
|
|
||||||
get() = (
|
|
||||||
this * Resources.getSystem().displayMetrics.density *
|
|
||||||
if (Resources.getSystem().isLTR) 1 else -1
|
|
||||||
)
|
|
||||||
|
|
||||||
val Resources.isLTR
|
|
||||||
get() = configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR
|
|
||||||
|
|
||||||
val Context.notificationManager: NotificationManager
|
|
||||||
get() = getSystemService()!!
|
|
||||||
|
|
||||||
val Context.connectivityManager: ConnectivityManager
|
|
||||||
get() = getSystemService()!!
|
|
||||||
|
|
||||||
val Context.wifiManager: WifiManager
|
|
||||||
get() = getSystemService()!!
|
|
||||||
|
|
||||||
val Context.powerManager: PowerManager
|
val Context.powerManager: PowerManager
|
||||||
get() = getSystemService()!!
|
get() = getSystemService()!!
|
||||||
|
|
||||||
val Context.displayCompat: Display?
|
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
display
|
|
||||||
} else {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
getSystemService<WindowManager>()?.defaultDisplay
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the duration multiplier for general animations on the device
|
|
||||||
* @see Settings.Global.ANIMATOR_DURATION_SCALE
|
|
||||||
*/
|
|
||||||
val Context.animatorDurationScale: Float
|
|
||||||
get() = Settings.Global.getFloat(this.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to acquire a partial wake lock.
|
* Convenience method to acquire a partial wake lock.
|
||||||
*/
|
*/
|
||||||
@ -188,7 +143,7 @@ fun Context.openInBrowser(uri: Uri, forceDefaultBrowser: Boolean = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.defaultBrowserPackageName(): String? {
|
private fun Context.defaultBrowserPackageName(): String? {
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, "http://".toUri())
|
val browserIntent = Intent(Intent.ACTION_VIEW, "http://".toUri())
|
||||||
val resolveInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
val resolveInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
packageManager.resolveActivity(browserIntent, PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong()))
|
packageManager.resolveActivity(browserIntent, PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong()))
|
||||||
@ -210,59 +165,6 @@ fun Context.createFileInCacheDir(name: String): File {
|
|||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val TABLET_UI_REQUIRED_SCREEN_WIDTH_DP = 720
|
|
||||||
|
|
||||||
// some tablets have screen width like 711dp = 1600px / 2.25
|
|
||||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP = 700
|
|
||||||
|
|
||||||
// make sure icons on the nav rail fit
|
|
||||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP = 600
|
|
||||||
|
|
||||||
fun Context.isTabletUi(): Boolean {
|
|
||||||
return resources.configuration.isTabletUi()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Configuration.isTabletUi(): Boolean {
|
|
||||||
return smallestScreenWidthDp >= TABLET_UI_REQUIRED_SCREEN_WIDTH_DP
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Configuration.isAutoTabletUiAvailable(): Boolean {
|
|
||||||
return smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move the logic to `isTabletUi()` when main activity is rewritten in Compose
|
|
||||||
fun Context.prepareTabletUiContext(): Context {
|
|
||||||
val configuration = resources.configuration
|
|
||||||
val expected = when (Injekt.get<UiPreferences>().tabletUiMode().get()) {
|
|
||||||
TabletUiMode.AUTOMATIC ->
|
|
||||||
configuration.smallestScreenWidthDp >= when (configuration.orientation) {
|
|
||||||
Configuration.ORIENTATION_PORTRAIT -> TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP
|
|
||||||
else -> TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
|
||||||
}
|
|
||||||
TabletUiMode.ALWAYS -> true
|
|
||||||
TabletUiMode.LANDSCAPE -> configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
|
||||||
TabletUiMode.NEVER -> false
|
|
||||||
}
|
|
||||||
if (configuration.isTabletUi() != expected) {
|
|
||||||
val overrideConf = Configuration()
|
|
||||||
overrideConf.setTo(configuration)
|
|
||||||
overrideConf.smallestScreenWidthDp = if (expected) {
|
|
||||||
overrideConf.smallestScreenWidthDp.coerceAtLeast(TABLET_UI_REQUIRED_SCREEN_WIDTH_DP)
|
|
||||||
} else {
|
|
||||||
overrideConf.smallestScreenWidthDp.coerceAtMost(TABLET_UI_REQUIRED_SCREEN_WIDTH_DP - 1)
|
|
||||||
}
|
|
||||||
return createConfigurationContext(overrideConf)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if current context is in night mode
|
|
||||||
*/
|
|
||||||
fun Context.isNightMode(): Boolean {
|
|
||||||
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates night mode Context depending on reader theme/background
|
* Creates night mode Context depending on reader theme/background
|
||||||
*
|
*
|
||||||
@ -292,35 +194,6 @@ fun Context.createReaderThemeContext(): Context {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.isOnline(): Boolean {
|
|
||||||
val activeNetwork = connectivityManager.activeNetwork ?: return false
|
|
||||||
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
|
|
||||||
val maxTransport = when {
|
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 -> NetworkCapabilities.TRANSPORT_LOWPAN
|
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> NetworkCapabilities.TRANSPORT_WIFI_AWARE
|
|
||||||
else -> NetworkCapabilities.TRANSPORT_VPN
|
|
||||||
}
|
|
||||||
return (NetworkCapabilities.TRANSPORT_CELLULAR..maxTransport).any(networkCapabilities::hasTransport)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if device is connected to Wifi.
|
|
||||||
*/
|
|
||||||
fun Context.isConnectedToWifi(): Boolean {
|
|
||||||
if (!wifiManager.isWifiEnabled) return false
|
|
||||||
|
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
||||||
val activeNetwork = connectivityManager.activeNetwork ?: return false
|
|
||||||
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
|
|
||||||
|
|
||||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
|
|
||||||
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
||||||
} else {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
wifiManager.connectionInfo.bssid != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets document size of provided [Uri]
|
* Gets document size of provided [Uri]
|
||||||
*
|
*
|
||||||
@ -370,11 +243,3 @@ fun Context.getApplicationIcon(pkgName: String): Drawable? {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets system's config_navBarNeedsScrim boolean flag added in Android 10, defaults to true.
|
|
||||||
*/
|
|
||||||
fun Context.isNavigationBarNeedsScrim(): Boolean {
|
|
||||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ||
|
|
||||||
InternalResourceHelper.getBoolean(this, "config_navBarNeedsScrim", true)
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.os.Build
|
||||||
|
import android.view.Display
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
|
import eu.kanade.domain.ui.model.TabletUiMode
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
private const val TABLET_UI_REQUIRED_SCREEN_WIDTH_DP = 720
|
||||||
|
|
||||||
|
// some tablets have screen width like 711dp = 1600px / 2.25
|
||||||
|
private const val TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP = 700
|
||||||
|
|
||||||
|
// make sure icons on the nav rail fit
|
||||||
|
private const val TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP = 600
|
||||||
|
|
||||||
|
fun Context.isTabletUi(): Boolean {
|
||||||
|
return resources.configuration.isTabletUi()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Configuration.isTabletUi(): Boolean {
|
||||||
|
return smallestScreenWidthDp >= TABLET_UI_REQUIRED_SCREEN_WIDTH_DP
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Configuration.isAutoTabletUiAvailable(): Boolean {
|
||||||
|
return smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: move the logic to `isTabletUi()` when main activity is rewritten in Compose
|
||||||
|
fun Context.prepareTabletUiContext(): Context {
|
||||||
|
val configuration = resources.configuration
|
||||||
|
val expected = when (Injekt.get<UiPreferences>().tabletUiMode().get()) {
|
||||||
|
TabletUiMode.AUTOMATIC ->
|
||||||
|
configuration.smallestScreenWidthDp >= when (configuration.orientation) {
|
||||||
|
Configuration.ORIENTATION_PORTRAIT -> TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP
|
||||||
|
else -> TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
||||||
|
}
|
||||||
|
TabletUiMode.ALWAYS -> true
|
||||||
|
TabletUiMode.LANDSCAPE -> configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
TabletUiMode.NEVER -> false
|
||||||
|
}
|
||||||
|
if (configuration.isTabletUi() != expected) {
|
||||||
|
val overrideConf = Configuration()
|
||||||
|
overrideConf.setTo(configuration)
|
||||||
|
overrideConf.smallestScreenWidthDp = if (expected) {
|
||||||
|
overrideConf.smallestScreenWidthDp.coerceAtLeast(TABLET_UI_REQUIRED_SCREEN_WIDTH_DP)
|
||||||
|
} else {
|
||||||
|
overrideConf.smallestScreenWidthDp.coerceAtMost(TABLET_UI_REQUIRED_SCREEN_WIDTH_DP - 1)
|
||||||
|
}
|
||||||
|
return createConfigurationContext(overrideConf)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if current context is in night mode
|
||||||
|
*/
|
||||||
|
fun Context.isNightMode(): Boolean {
|
||||||
|
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||||
|
}
|
||||||
|
|
||||||
|
val Context.displayCompat: Display?
|
||||||
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
display
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
getSystemService<WindowManager>()?.defaultDisplay
|
||||||
|
}
|
||||||
|
|
||||||
|
val Resources.isLTR
|
||||||
|
get() = configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts to px and takes into account LTR/RTL layout.
|
||||||
|
*/
|
||||||
|
val Float.dpToPxEnd: Float
|
||||||
|
get() = (
|
||||||
|
this * Resources.getSystem().displayMetrics.density *
|
||||||
|
if (Resources.getSystem().isLTR) 1 else -1
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether if the device has a display cutout (i.e. notch, camera cutout, etc.).
|
||||||
|
*
|
||||||
|
* Only works in Android 9+.
|
||||||
|
*/
|
||||||
|
fun Activity.hasDisplayCutout(): Boolean {
|
||||||
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P &&
|
||||||
|
window.decorView.rootWindowInsets?.displayCutout != null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets system's config_navBarNeedsScrim boolean flag added in Android 10, defaults to true.
|
||||||
|
*/
|
||||||
|
fun Context.isNavigationBarNeedsScrim(): Boolean {
|
||||||
|
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ||
|
||||||
|
InternalResourceHelper.getBoolean(this, "config_navBarNeedsScrim", true)
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.net.wifi.WifiManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
|
||||||
|
val Context.connectivityManager: ConnectivityManager
|
||||||
|
get() = getSystemService()!!
|
||||||
|
|
||||||
|
val Context.wifiManager: WifiManager
|
||||||
|
get() = getSystemService()!!
|
||||||
|
|
||||||
|
fun Context.isOnline(): Boolean {
|
||||||
|
val activeNetwork = connectivityManager.activeNetwork ?: return false
|
||||||
|
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
|
||||||
|
val maxTransport = when {
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 -> NetworkCapabilities.TRANSPORT_LOWPAN
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> NetworkCapabilities.TRANSPORT_WIFI_AWARE
|
||||||
|
else -> NetworkCapabilities.TRANSPORT_VPN
|
||||||
|
}
|
||||||
|
return (NetworkCapabilities.TRANSPORT_CELLULAR..maxTransport).any(networkCapabilities::hasTransport)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if device is connected to Wifi.
|
||||||
|
*/
|
||||||
|
fun Context.isConnectedToWifi(): Boolean {
|
||||||
|
if (!wifiManager.isWifiEnabled) return false
|
||||||
|
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
val activeNetwork = connectivityManager.activeNetwork ?: return false
|
||||||
|
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
|
||||||
|
|
||||||
|
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
|
||||||
|
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
wifiManager.connectionInfo.bssid != null
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,19 @@
|
|||||||
package eu.kanade.tachiyomi.util.system
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.app.NotificationChannelCompat
|
import androidx.core.app.NotificationChannelCompat
|
||||||
import androidx.core.app.NotificationChannelGroupCompat
|
import androidx.core.app.NotificationChannelGroupCompat
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.content.PermissionChecker
|
import androidx.core.content.PermissionChecker
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
|
val Context.notificationManager: NotificationManager
|
||||||
|
get() = getSystemService()!!
|
||||||
|
|
||||||
fun Context.notify(id: Int, channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null) {
|
fun Context.notify(id: Int, channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null) {
|
||||||
if (PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PermissionChecker.PERMISSION_GRANTED) {
|
if (PermissionChecker.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PermissionChecker.PERMISSION_GRANTED) {
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user