diff --git a/README.md b/README.md
index b7226bd3..ec57fc24 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
### ๐ Description
-์นด์นด์ค๋งต ํด๋ก ์ฝ๋ฉ _ ์๋ฆผ-ํ์ด์ด๋ฒ ์ด
+์นด์นด์ค๋งต ํด๋ก ์ฝ๋ฉ _ ์๋ฆผ-ํ์ด์ด๋ฒ ์ด์ค
### ๐ฏ Tasks
@@ -17,4 +17,17 @@
- ๋งค๊ฐ๋ณ์ ์ด๋ฆ : serviceState, serviceMessage
- ๋งค๊ฐ๋ณ์ serviceState ๊ฐ์ด ON_SERVICE์ผ ๋๋ง ์ด๊ธฐ ์ง์
ํ๋ฉด์ด ์ง๋ ํ๋ฉด์ผ๋ก ๋์ด๊ฐ
- ๋งค๊ฐ๋ณ์ serviceState ๊ฐ์ด ON_SERVICE์ด ์๋ ๊ฒฝ์ฐ, serviceMessage ๊ฐ์ ์ด๊ธฐ ์ง์
ํ๋ฉด ํ๋จ์ ํ์ํ๊ณ ์ง๋ ํ๋ฉด์ผ๋ก ์ง์
ํ์ง ์์
-- ์๋ฒ ์ํ, UI ๋ก๋ฉ ๋ฑ์ ๋ํ ์ํ ๊ด๋ฆฌ
\ No newline at end of file
+- ์๋ฒ ์ํ, UI ๋ก๋ฉ ๋ฑ์ ๋ํ ์ํ ๊ด๋ฆฌ
+
+---
+## Step2
+
+### ๐ฏ Tasks
+
+- Main ๊ธฐ๋ฅ : **ํธ์ ์๋ฆผ**
+
+- Firebase Cloud Message ์ค์
+- ํ
์คํธ ๋ฉ์์ง
+ - ์ฑ์ด ๋ฐฑ๊ทธ๋ผ์ด๋ ์ํ์ผ ๊ฒฝ์ฐ FCM ๊ธฐ๋ณธ ๊ฐ์ ์ฌ์ฉํ์ฌ Notification ๋ฐ์
+ - ์ฑ์ด ํฌ๊ทธ๋ผ์ด๋ ์ํ์ผ ๊ฒฝ์ฐ ์ปค์คํ
Notification ๋ฐ์
+- Notification ์ฐฝ์ ํฐ์นํ๋ฉด ์ด๊ธฐ ์ง์
ํ๋ฉด ํธ์ถ
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 45f6371a..103fc76f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
+
+
+
+
+
+
-
@@ -32,7 +41,6 @@
-
diff --git a/app/src/main/java/campus/tech/kakao/map/service/MapFirebaseMessagingService.kt b/app/src/main/java/campus/tech/kakao/map/service/MapFirebaseMessagingService.kt
new file mode 100644
index 00000000..bce652a1
--- /dev/null
+++ b/app/src/main/java/campus/tech/kakao/map/service/MapFirebaseMessagingService.kt
@@ -0,0 +1,85 @@
+package campus.tech.kakao.map.service
+
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.util.Log
+import androidx.core.app.NotificationCompat
+import campus.tech.kakao.map.R
+import campus.tech.kakao.map.ui.MapActivity
+import campus.tech.kakao.map.ui.SplashScreenActivity
+import com.google.firebase.messaging.FirebaseMessagingService
+import com.google.firebase.messaging.RemoteMessage
+
+class MapFirebaseMessagingService : FirebaseMessagingService() {
+
+ private lateinit var notificationManager: NotificationManager
+
+ override fun onNewToken(token: String) {
+ super.onNewToken(token)
+ Log.d("MapFCM", "Refreshed token: $token")
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ createNotificationChannel()
+ }
+
+ override fun onMessageReceived(message: RemoteMessage) {
+ super.onMessageReceived(message)
+
+ Log.d("remoteMessage", "From: ${message.from}")
+
+ message.notification?.let {
+ Log.d("remoteMessage", "Message Notification Body: ${it.body}")
+
+ sendNotification()
+ }
+ }
+
+ private fun createNotificationChannel() {
+ val descriptionText = getString(R.string.fcm_channel_description)
+ val channel = NotificationChannel(
+ CHANNEL_ID,
+ CHANNEL_NAME,
+ NotificationManager.IMPORTANCE_DEFAULT
+ ).apply {
+ description = descriptionText
+ }
+ notificationManager.createNotificationChannel(channel)
+ }
+
+ private fun sendNotification() {
+ val intent = Intent(this, SplashScreenActivity::class.java).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+ }
+ val pendingIntent = PendingIntent.getActivity(
+ this,
+ 0,
+ intent,
+ PendingIntent.FLAG_IMMUTABLE
+ )
+ val builder = NotificationCompat.Builder(this, CHANNEL_ID)
+ .setSmallIcon(R.drawable.ic_launcher_foreground)
+ .setContentTitle("[์ค์] ํฌ๊ทธ๋ผ์ด๋ ์๋ฆผ")
+ .setContentText("์ฑ์ด ์คํ ์ค์
๋๋ค.")
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setContentIntent(pendingIntent)
+ .setStyle(
+ NotificationCompat.BigTextStyle()
+ .bigText("์ฑ์ด ์คํ ์ค์ผ ๋๋ ํฌ๊ทธ๋ผ์ด๋ ์๋ฆผ์ด ๋ฐ์ํฉ๋๋ค.")
+ )
+ .setAutoCancel(true)
+ notificationManager.notify(NOTIFICATION_ID, builder.build())
+ }
+
+ companion object {
+ private const val NOTIFICATION_ID = 222222
+ private const val CHANNEL_ID = "main_default_channel"
+ private const val CHANNEL_NAME = "main channelName"
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/campus/tech/kakao/map/ui/MapActivity.kt b/app/src/main/java/campus/tech/kakao/map/ui/MapActivity.kt
index 77341599..94492836 100644
--- a/app/src/main/java/campus/tech/kakao/map/ui/MapActivity.kt
+++ b/app/src/main/java/campus/tech/kakao/map/ui/MapActivity.kt
@@ -1,20 +1,28 @@
package campus.tech.kakao.map.ui
+import android.app.AlertDialog
import android.content.Intent
+import android.content.pm.PackageManager
import android.graphics.Color
+import android.net.Uri
+import android.os.Build
import android.os.Bundle
+import android.provider.Settings
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import campus.tech.kakao.map.R
import campus.tech.kakao.map.databinding.ActivityMapBinding
import campus.tech.kakao.map.databinding.BottomSheetBinding
import campus.tech.kakao.map.databinding.ErrorLayoutBinding
import campus.tech.kakao.map.viewmodel.MapViewModel
+import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.kakao.vectormap.KakaoMap
import com.kakao.vectormap.KakaoMapReadyCallback
@@ -26,6 +34,7 @@ import com.kakao.vectormap.label.LabelOptions
import com.kakao.vectormap.label.LabelStyle
import com.kakao.vectormap.label.LabelStyles
import dagger.hilt.android.AndroidEntryPoint
+import com.google.firebase.messaging.FirebaseMessaging
@AndroidEntryPoint
class MapActivity : AppCompatActivity() {
@@ -39,6 +48,16 @@ class MapActivity : AppCompatActivity() {
private val mapViewModel: MapViewModel by viewModels()
+ private val requestPermissionLauncher = registerForActivityResult(
+ ActivityResultContracts.RequestPermission(),
+ ) { isGranted: Boolean ->
+ if (isGranted) {
+ Log.d("MapActivity", "์๋ฆผ ๊ถํ ํ์ฉ")
+ } else {
+ Log.d("MapActivity", "์๋ฆผ ๊ถํ ๊ฑฐ๋ถ")
+ }
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_map)
@@ -56,6 +75,18 @@ class MapActivity : AppCompatActivity() {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
+
+ askNotificationPermission()
+
+// // ํ ํฐ ๋ฐ๊ธฐ
+// FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
+// if (!task.isSuccessful) {
+// Log.w("MapFCM", "Fetching FCM registration token failed", task.exception)
+// return@OnCompleteListener
+// }
+// val token = task.result
+// Log.d("token", token)
+// })
}
override fun onResume() {
@@ -168,4 +199,45 @@ class MapActivity : AppCompatActivity() {
binding.searchLayout.visibility = if (message != null) View.GONE else View.VISIBLE
binding.mapView.visibility = if (message != null) View.GONE else View.VISIBLE
}
+
+ private fun askNotificationPermission() {
+ // This is only necessary for API level >= 33 (TIRAMISU)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(
+ this,
+ android.Manifest.permission.POST_NOTIFICATIONS
+ ) ==
+ PackageManager.PERMISSION_GRANTED
+ ) {
+ Log.d("MapActivity", "์๋ฆผ ๊ถํ ์ด๋ฏธ ํ์ฉ")
+ // FCM SDK (and your app) can post notifications.
+ } else if (shouldShowRequestPermissionRationale(android.Manifest.permission.POST_NOTIFICATIONS)) {
+ // ๊ถํ ์์ฒญ ์ด์ ๋ฅผ ์ค๋ช
ํ๋ UI๋ฅผ ํ์
+ showNotificationPermissionDialog()
+ } else {
+ // Directly ask for the permission
+ requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
+ }
+ }
+ }
+
+ private fun showNotificationPermissionDialog() {
+ AlertDialog.Builder(this).apply {
+ setTitle(getString(R.string.ask_notification_permission_dialog_title))
+ setMessage(
+ String.format(
+ "๋ค์ํ ์๋ฆผ ์์์ ๋ฐ๊ธฐ ์ํด ๊ถํ์ ํ์ฉํ์๊ฒ ์ด์?\n(์๋ฆผ์์ %s์ ์๋ฆผ ๊ถํ์ ํ์ฉํด์ฃผ์ธ์.)",
+ getString(R.string.app_name)
+ )
+ )
+ setPositiveButton(getString(R.string.yes)) { _, _ ->
+ val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ val uri = Uri.fromParts("package", packageName, null)
+ intent.data = uri
+ startActivity(intent)
+ }
+ setNegativeButton(getString(R.string.deny_notification_permission)) { _, _ -> }
+ show()
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/campus/tech/kakao/map/ui/SplashScreenActivity.kt b/app/src/main/java/campus/tech/kakao/map/ui/SplashScreenActivity.kt
index 8fb67d00..5747e328 100644
--- a/app/src/main/java/campus/tech/kakao/map/ui/SplashScreenActivity.kt
+++ b/app/src/main/java/campus/tech/kakao/map/ui/SplashScreenActivity.kt
@@ -8,10 +8,13 @@ import android.util.Log
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
+import androidx.lifecycle.lifecycleScope
import campus.tech.kakao.map.R
import campus.tech.kakao.map.databinding.ActivitySplashScreenBinding
import campus.tech.kakao.map.viewmodel.SplashScreenViewModel
import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
@AndroidEntryPoint
class SplashScreenActivity : AppCompatActivity() {
@@ -37,10 +40,11 @@ class SplashScreenActivity : AppCompatActivity() {
private fun navigateToMapActivity() {
Log.d("SplashScreen", "Success")
- Handler(Looper.getMainLooper()).postDelayed({
- startActivity(Intent(this, MapActivity::class.java))
+ lifecycleScope.launch {
+ delay(3000L)
+ startActivity(Intent(this@SplashScreenActivity, MapActivity::class.java))
finish()
- }, 3000)
+ }
}
private fun showServiceMessage() {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 843469f2..1b461211 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -18,4 +18,8 @@
๋ก๋ฉ ์ด๋ฏธ์ง
tvServiceMessage
splashScreenMapIcon
+ ์ฑ ์๋ฆผ ์ฑ๋
+ ์๋ฆผ ๊ถํ ์์ฒญ
+ ์
+ ์๋์
\ No newline at end of file