Skip to content

Commit

Permalink
chore: add notification permissions and bump min sdk to 24
Browse files Browse the repository at this point in the history
  • Loading branch information
wax911 committed Dec 30, 2024
1 parent f02fd7d commit 819eb8b
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package co.anitrend.core.android.helpers.notification

import android.Manifest
import android.content.Context
import android.os.Build
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
import androidx.fragment.app.FragmentActivity
import co.anitrend.core.android.helpers.notification.NotificationHelper.Companion.POST_NOTIFICATION_PERMISSION_REQUEST_CODE
import co.anitrend.core.android.helpers.notification.config.NotificationConfig


fun Context.hasNotificationPermissionFor(config: NotificationConfig): Boolean {
val hasPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PERMISSION_GRANTED
} else {
NotificationManagerCompat.from(this).areNotificationsEnabled()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasPermission) {
val channel = NotificationManagerCompat.from(this).getNotificationChannel(config.name)
if (channel != null && channel.importance == config.importance) {
return false
}
}
return hasPermission
}

fun FragmentActivity.requestPostNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(
/* context = */ this,
/* permission = */ Manifest.permission.POST_NOTIFICATIONS,
) != PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
/* activity = */ this,
/* permissions = */ arrayOf(Manifest.permission.POST_NOTIFICATIONS),
/* requestCode = */ POST_NOTIFICATION_PERMISSION_REQUEST_CODE,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package co.anitrend.core.android.helpers.notification

import android.app.NotificationChannel
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import co.anitrend.core.android.helpers.notification.config.NotificationConfig

class NotificationHelper(
private val notificationManager: NotificationManagerCompat
) {

@RequiresApi(Build.VERSION_CODES.O)
fun createNotificationChannels() {
val channels = NotificationConfig.entries.map { config ->
return with (NotificationChannel(config.name, config.title, config.importance)) {
description = config.description
group = config.group
setShowBadge(true)
enableLights(false)
}
}
notificationManager.createNotificationChannels(channels)
}

companion object {
const val POST_NOTIFICATION_PERMISSION_REQUEST_CODE = 0x12

fun notificationVisibilityFor(isAdult: Boolean) =
if (isAdult) NotificationCompat.VISIBILITY_SECRET else NotificationCompat.VISIBILITY_PUBLIC
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package co.anitrend.core.android.helpers.notification.config

import android.app.NotificationManager

enum class NotificationConfig(
val title: String,
val description: String,
val importance: Int,
val group: String,
) {
GENERAL(
title = "General",
description = "AniTrend specific notifications",
importance = NotificationManager.IMPORTANCE_DEFAULT,
group = "co.anitrend.notification.group.GENERAL",
),
ANILIST(
title = "AniList",
description = "AniList related notifications",
importance = NotificationManager.IMPORTANCE_DEFAULT,
group = "co.anitrend.notification.group.ANILIST",
),
ANNOUNCEMENT(
title = "Announcements",
description = "Announcements and other important information",
importance = NotificationManager.IMPORTANCE_HIGH,
group = "co.anitrend.notification.group.ANNOUNCEMENT",
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ package co.anitrend.core.android.koin
import android.content.pm.ShortcutManager
import android.net.ConnectivityManager
import android.os.PowerManager
import androidx.core.app.NotificationManagerCompat
import co.anitrend.arch.extension.dispatchers.SupportDispatcher
import co.anitrend.arch.extension.dispatchers.contract.ISupportDispatcher
import co.anitrend.arch.extension.ext.systemServiceOf
import co.anitrend.arch.extension.util.date.contract.AbstractSupportDateHelper
import co.anitrend.core.android.controller.power.AndroidPowerController
import co.anitrend.core.android.controller.power.contract.IPowerController
import co.anitrend.core.android.helpers.date.AniTrendDateHelper
import co.anitrend.core.android.helpers.notification.NotificationHelper
import co.anitrend.core.android.settings.Settings
import co.anitrend.core.android.settings.helper.config.ConfigurationHelper
import co.anitrend.core.android.settings.helper.config.contract.IConfigurationHelper
Expand Down Expand Up @@ -68,6 +70,13 @@ private val coreModule = module {
val localeHelper = get<ILocaleHelper>()
PrettyTime(localeHelper.locale)
}

factory {
NotificationHelper(
notificationManager = NotificationManagerCompat
.from(androidContext())
)
}
}

private val configurationModule = module {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ abstract class AniTrendScreen : SupportActivity(), AndroidScopeComponent, KoinSc

override val scope by activityRetainedScope()


private val connectivity by inject<ISupportConnectivity>()

/**
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<uses-permission
android:name="android.permission.CLEAR_APP_CACHE"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/kotlin/co/anitrend/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ class App : AniTrendApplication() {
override fun restartDependencyInjection() {
stopKoin()
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/kotlin/co/anitrend/component/screen/MainScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import co.anitrend.component.action.ChangeSettingsMenuStateAction
import co.anitrend.component.action.ShowHideFabStateAction
import co.anitrend.component.presenter.MainPresenter
import co.anitrend.component.viewmodel.MainScreenViewModel
import co.anitrend.core.android.helpers.notification.config.NotificationConfig
import co.anitrend.core.android.helpers.notification.hasNotificationPermissionFor
import co.anitrend.core.android.helpers.notification.requestPostNotificationPermission
import co.anitrend.core.component.screen.AniTrendBoundScreen
import co.anitrend.core.extensions.invoke
import co.anitrend.core.koin.scope.AppScope
Expand Down Expand Up @@ -191,6 +194,14 @@ class MainScreen : AniTrendBoundScreen<MainScreenBinding>() {
observeNavigationDrawer()
}
}
lifecycleScope.launch {
val needsNotificationPermission = NotificationConfig.entries.any {
!hasNotificationPermissionFor(it)
}
if (needsNotificationPermission) {
requestPostNotificationPermission()
}
}
onUpdateUserInterface()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private fun Project.configureLint() = baseAppExtension().run {
internal fun Project.configureAndroid(): Unit = baseExtension().run {
compileSdkVersion(35)
defaultConfig {
minSdk = 23
minSdk = 24
targetSdk = 35
versionCode = props[PropertyTypes.CODE].toInt()
versionName = props[PropertyTypes.VERSION]
Expand Down

0 comments on commit 819eb8b

Please sign in to comment.