diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e8bcdc28..e95cc344 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,9 @@
+
(R.layout.activity_main
private val prevScreenName by lazy { intent.extras?.getString(KEY_PREV_SCREEN, "") }
private val notiType by lazy { intent.extras?.getString(KEY_NOTI_TYPE, "") }
private val feedId by lazy { intent.extras?.getString(KEY_FEED_ID) }
+ private val notificationPermissionLauncher =
+ registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
+ if (!isGranted) {
+ wineySnackbar(
+ anchorView = binding.root,
+ isSuccess = false,
+ message = stringOf(R.string.snackbar_notification_permission_fail)
+ )
+ }
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ requestNotificationPermission()
+
// 위니피드, 마이페이지 프래그먼트에서 getUserState 관찰
mainViewModel.getUser()
mainViewModel.patchFcmToken()
@@ -51,6 +68,16 @@ class MainActivity : BindingActivity(R.layout.activity_main
showSuccessSnackBar()
}
+ private fun requestNotificationPermission() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission.POST_NOTIFICATIONS
+ ) == PackageManager.PERMISSION_DENIED
+ ) {
+ notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
+ }
+ }
+
private fun initNotiTypeHandler() {
val notificationType = NotificationType.values().find { it.key == notiType }
when (notificationType) {
@@ -61,9 +88,11 @@ class MainActivity : BindingActivity(R.layout.activity_main
KEY_FROM_NOTI,
true
)
+
NotificationType.LIKE_NOTIFICATION, NotificationType.COMMENT_NOTIFICATION
-> navigateToDetail(feedId?.toInt())
- else -> navigateToLevelupHelp()
+ NotificationType.HOW_TO_LEVEL_UP -> navigateToLevelupHelp()
+ else -> {}
}
}
diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt
index ed5253a6..0665653f 100644
--- a/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt
+++ b/app/src/main/java/org/go/sopt/winey/presentation/main/mypage/MyPageFragment.kt
@@ -1,10 +1,19 @@
package org.go.sopt.winey.presentation.main.mypage
+import android.Manifest
+import android.content.ActivityNotFoundException
+import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
import android.net.Uri
+import android.os.Build
import android.os.Bundle
+import android.provider.Settings
import android.view.View
import androidx.activity.OnBackPressedCallback
+import androidx.core.content.ContextCompat
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.commit
@@ -34,6 +43,7 @@ import org.go.sopt.winey.util.fragment.snackBar
import org.go.sopt.winey.util.fragment.stringOf
import org.go.sopt.winey.util.fragment.viewLifeCycle
import org.go.sopt.winey.util.fragment.viewLifeCycleScope
+import org.go.sopt.winey.util.fragment.wineySnackbar
import org.go.sopt.winey.util.view.UiState
import org.go.sopt.winey.util.view.setOnSingleClickListener
import javax.inject.Inject
@@ -48,10 +58,12 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
@Inject
lateinit var amplitudeUtils: AmplitudeUtils
+ private var isNotificationPermissionAllowed = true
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
amplitudeUtils.logEvent("view_mypage")
+ initCheckNotificationPermission()
initUserData()
initNavigation()
@@ -64,6 +76,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
initWithdrawButtonClickListener()
initNicknameButtonClickListener()
initAllowedNotificationButtonClickListener()
+ initNotificationPermissionChangeButtonClickListener()
registerBackPressedCallback()
setupGetUserState()
@@ -73,27 +86,36 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
checkFromWineyFeed()
}
+ private fun initCheckNotificationPermission() {
+ isNotificationPermissionAllowed = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ ContextCompat.checkSelfPermission(
+ requireContext(),
+ Manifest.permission.POST_NOTIFICATIONS
+ ) == PackageManager.PERMISSION_GRANTED
+ } else {
+ true
+ }
+ }
+
private fun setupPatchAllowedNotificationState() {
myPageViewModel.patchAllowedNotificationState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
is UiState.Success -> {
when (state.data) {
true -> {
- binding.ivMypageAgree.transitionToEnd()
+ binding.ivMypageAgree.transitionToState(R.id.end, -1)
}
false -> {
- binding.ivMypageAgree.transitionToStart()
+ binding.ivMypageAgree.transitionToState(R.id.start, -1)
}
null -> {
- binding.ivMypageAgree.transitionToStart()
+ binding.ivMypageAgree.transitionToState(R.id.start, -1)
}
}
}
- is UiState.Failure -> {}
- is UiState.Empty -> {}
else -> {}
}
}
@@ -101,22 +123,91 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
private fun initAllowedNotificationButtonClickListener() {
binding.ivMypageSwitch.setOnClickListener {
- val isAllowed = when (binding.ivMypageAgree.currentState) {
- R.id.start -> false
- R.id.end -> true
- else -> false
- }
- when (isAllowed) {
+ when (isNotificationPermissionAllowed) {
true -> {
- binding.ivMypageAgree.transitionToStart()
+ val isAllowed = when (binding.ivMypageAgree.currentState) {
+ R.id.start -> false
+ R.id.end -> true
+ else -> false
+ }
+ when (isAllowed) {
+ true -> {
+ showNotificationOffDialog(isAllowed)
+ }
+
+ false -> {
+ binding.ivMypageAgree.transitionToState(R.id.end, -1)
+ patchUserInfo()
+ myPageViewModel.patchAllowedNotification(isAllowed)
+ }
+ }
}
false -> {
- binding.ivMypageAgree.transitionToEnd()
+ wineySnackbar(
+ binding.root,
+ true,
+ stringOf(R.string.snackbar_notification_permission_fail)
+ )
}
}
- patchUserInfo()
- myPageViewModel.patchAllowedNotification(isAllowed)
+ }
+ }
+
+ private fun showNotificationOffDialog(isAllowed: Boolean) {
+ val dialog = WineyDialogFragment.newInstance(
+ WineyDialogLabel(
+ stringOf(R.string.notification_off_dialog_title),
+ stringOf(R.string.notification_off_dialog_subtitle),
+ stringOf(R.string.notification_off_dialog_negative_button),
+ stringOf(R.string.notification_off_dialog_positive_button)
+ ),
+ handleNegativeButton = {},
+ handlePositiveButton = {
+ binding.ivMypageAgree.transitionToState(R.id.start, -1)
+ patchUserInfo()
+ myPageViewModel.patchAllowedNotification(isAllowed)
+ }
+ )
+ dialog.show(
+ parentFragmentManager,
+ TAG_NOTIFICATION_OFF_DIALOG
+ )
+ }
+
+ private fun initNotificationPermissionChangeButtonClickListener() {
+ binding.llMypageAgreePermissionChange.setOnClickListener {
+ navigateToNotificationSetting(requireContext())
+ }
+ }
+
+ private fun navigateToNotificationSetting(context: Context) {
+ val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ setNotificationIntentActionOreo(context)
+ } else {
+ setNorificationIntentActionOreoLess(context)
+ }
+ try {
+ context.startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ e.printStackTrace()
+ }
+ }
+
+ private fun setNotificationIntentActionOreo(context: Context): Intent {
+ return Intent().also { intent ->
+ intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ }
+ }
+
+ private fun setNorificationIntentActionOreoLess(context: Context): Intent {
+ return Intent().also { intent ->
+ intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
+ intent.putExtra("app_package", context.packageName)
+ intent.putExtra("app_uid", context.applicationInfo?.uid)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
}
@@ -132,6 +223,20 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
override fun onStart() {
super.onStart()
mainViewModel.getUser()
+ initCheckNotificationPermission()
+ changeNotiButtonByPermission()
+ }
+
+ private fun changeNotiButtonByPermission() {
+ if (isNotificationPermissionAllowed) {
+ binding.ivMypageAgree.isVisible = true
+ binding.llMypageAgreePermissionChange.isGone = true
+ binding.tvMypageAgreePermission.isGone = true
+ } else {
+ binding.ivMypageAgree.isGone = true
+ binding.llMypageAgreePermissionChange.isVisible = true
+ binding.tvMypageAgreePermission.isVisible = true
+ }
}
// 위니피드 프래그먼트에서 마이페이지로 전환 시, 바텀시트 바로 띄우도록
@@ -352,14 +457,23 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
}
private fun updateNotificationAllowSwitchState(data: User) {
- when (data.fcmIsAllowed) {
- true -> {
- binding.ivMypageAgree.transitionToEnd()
- }
+ if (isNotificationPermissionAllowed) {
+ binding.ivMypageAgree.isVisible = true
+ binding.llMypageAgreePermissionChange.isGone = true
+ binding.tvMypageAgreePermission.isGone = true
+ when (data.fcmIsAllowed) {
+ true -> {
+ binding.ivMypageAgree.transitionToState(R.id.end, 1)
+ }
- false -> {
- binding.ivMypageAgree.transitionToStart()
+ false -> {
+ binding.ivMypageAgree.transitionToState(R.id.start, 1)
+ }
}
+ } else {
+ binding.ivMypageAgree.isGone = true
+ binding.llMypageAgreePermissionChange.isVisible = true
+ binding.tvMypageAgreePermission.isVisible = true
}
}
@@ -412,6 +526,8 @@ class MyPageFragment : BindingFragment(R.layout.fragment_
private const val VAL_MY_PAGE_SCREEN = "MyPageFragment"
private const val KEY_FROM_NOTI = "fromNoti"
private const val KEY_FROM_WINEY_FEED = "fromWineyFeed"
+
private const val KEY_TO_MYFEED = "toMyFeed"
+ private const val TAG_NOTIFICATION_OFF_DIALOG = "offNotification"
}
}
diff --git a/app/src/main/res/drawable/ic_mypage_change.xml b/app/src/main/res/drawable/ic_mypage_change.xml
new file mode 100644
index 00000000..64a17e57
--- /dev/null
+++ b/app/src/main/res/drawable/ic_mypage_change.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/fragment_my_page.xml b/app/src/main/res/layout/fragment_my_page.xml
index 3edcd7f9..4d0f52fc 100644
--- a/app/src/main/res/layout/fragment_my_page.xml
+++ b/app/src/main/res/layout/fragment_my_page.xml
@@ -363,18 +363,57 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/v_mypage_line6">
-
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent">
+
+
+
+
+
+
+
+
+
취소
삭제하기
+
+ 알림을 끄시겠어요?
+ 앞으로 위니 제국에서 오는 편지를 받으실 수 없어요.
+ 취소
+ 확인
+
절약을 인증할 수 있는\n사진을 업로드 해 주세요.
절약을 실천한\n모습을 보여주세요!
@@ -89,6 +95,7 @@
1:1 문의
이용약관
알림설정
+ 기기 설정을 변경해야 알림을 받을 수 있어요
탈퇴하기
로그아웃
@@ -216,6 +223,7 @@
죄송합니다. 다시 시도해주세요.
정상적으로 신고되었습니다 :)
죄송합니다. 신고접수에 실패하였습니다.
+ 기기 설정을 변경해야 알림을 받을 수 있어요
LV. 평민 ㆍ