Merge pull request #1877 from Hafizzle/Hafiz/android13-request-notification-permissions

Android 13 Notification Permissions
This commit is contained in:
Phillip Thelen 2022-12-05 17:53:02 +01:00 committed by GitHub
commit 48a65cd4d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 2 deletions

View file

@ -11,6 +11,7 @@
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application
android:name=".HabiticaApplication"

View file

@ -2,6 +2,10 @@ package com.habitrpg.android.habitica.helpers.notifications
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.edit
import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.RemoteMessage
@ -34,6 +38,18 @@ class PushNotificationManager(
this.user = user
}
/**
* New installs on Android 13 require
* Notification permissions be approved.
* Devices on Android 12L or lower with previously
* allowed notification permissions that update to 13
* will have notification permissions enabled by default.
*/
fun notificationPermissionEnabled(): Boolean {
val notificationManager = NotificationManagerCompat.from(context)
return notificationManager.areNotificationsEnabled()
}
fun addPushDeviceUsingStoredToken() {
if (refreshedToken.isNotBlank()) {
addRefreshToken()

View file

@ -13,6 +13,7 @@ import android.view.KeyEvent
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.core.view.children
@ -111,6 +112,16 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
private var userQuestStatus = UserQuestStatus.NO_QUEST
private var lastNotificationOpen: Long? = null
private val notificationPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) {
viewModel.pushNotificationManager.addPushDeviceUsingStoredToken()
} else {
viewModel.updateAllowPushNotifications(false)
}
}
val isAppBarExpanded: Boolean
get() = binding.content.appbar.height - binding.content.appbar.bottom == 0
@ -304,6 +315,13 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
MainNavigationController.setup(navigationController)
navigationController.addOnDestinationChangedListener { _, destination, arguments -> updateToolbarTitle(destination, arguments) }
viewModel.requestNotificationPermission.observe(this) { requestNotificationPermission ->
if (requestNotificationPermission && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)) {
notificationPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
viewModel.requestNotificationPermission.value = false
}
}
if (launchScreen == "/party") {
viewModel.user.observeOnce(this) {
if (viewModel.userViewModel.isUserInParty) {

View file

@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.fragments.preferences
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
@ -192,6 +193,10 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
}
}
private val notificationPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted -> if (granted) { pushNotificationManager.addPushDeviceUsingStoredToken() } }
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) {
when (key) {
"use_reminder" -> {
@ -214,7 +219,11 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
userRepository.updateUser("preferences.pushNotifications.unsubscribeFromAll", !usePushNotifications)
}
if (usePushNotifications) {
pushNotificationManager.addPushDeviceUsingStoredToken()
if (!pushNotificationManager.notificationPermissionEnabled() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)) {
notificationPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
} else {
pushNotificationManager.addPushDeviceUsingStoredToken()
}
} else {
pushNotificationManager.removePushDeviceUsingStoredToken()
}

View file

@ -1,7 +1,9 @@
package com.habitrpg.android.habitica.ui.viewmodels
import android.content.SharedPreferences
import android.os.Build
import androidx.core.content.edit
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.api.MaintenanceApiService
@ -61,6 +63,7 @@ class MainActivityViewModel : BaseViewModel(), TutorialView.OnTutorialReaction {
putString("language", value)
}
}
var requestNotificationPermission = MutableLiveData(false)
override fun onCleared() {
taskRepository.close()
@ -97,7 +100,13 @@ class MainActivityViewModel : BaseViewModel(), TutorialView.OnTutorialReaction {
analyticsManager.setUserProperty("checkin_count", user.loginIncentives.toString())
analyticsManager.setUserProperty("level", user.stats?.lvl?.toString() ?: "")
pushNotificationManager.setUser(user)
pushNotificationManager.addPushDeviceUsingStoredToken()
if (!pushNotificationManager.notificationPermissionEnabled() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)) {
if (sharedPreferences.getBoolean("usePushNotifications", true)) {
requestNotificationPermission.value = true
}
} else {
pushNotificationManager.addPushDeviceUsingStoredToken()
}
}
contentRepository.retrieveContent()
}
@ -107,6 +116,13 @@ class MainActivityViewModel : BaseViewModel(), TutorialView.OnTutorialReaction {
}
}
fun updateAllowPushNotifications(allowPushNotifications: Boolean) {
sharedPreferences.getBoolean("usePushNotifications", true)
sharedPreferences.edit {
putBoolean("usePushNotifications", allowPushNotifications)
}
}
override fun onTutorialCompleted(step: TutorialStep) {
updateUser("flags.tutorial." + step.tutorialGroup + "." + step.identifier, true)
logTutorialStatus(step, true)