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