Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

경북대 Android 남지연 6주차 과제 Step2 #77

Open
wants to merge 15 commits into
base: njiyeon
Choose a base branch
from
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# android-map-notification
## 기능 요구 사항
- 초기 진입 화면을 추가한다.
- Firebase의 Remote Config를 설정한다.
- 서비스 상태를 나타내는 매개변수를 아래와 같이 각각 등록한다.
- 매개변수 이름:serviceState, serviceMessage
- 매개변수 serviceState 값이 ON_SERVICE일 때만 초기 진입 화면이 지도 화면으로 넘어간다.
- 매개변수 serviceState 값이 ON_SERVICE이 아닌 경우에는 serviceMessage 값을 초기 진입 화면 하단에 표시하고 지도 화면으로 진입하지 않는다.
- Firebase Cloud Message를 설정한다.
- 테스트 메시지를 보낸다.
- 앱이 백그라운드 상태일 경우 FCM 기본 값을 사용하여 Notification을 발생한다.
- 앱이 포그라운드 상태일 경우 커스텀 Notification을 발생한다.
- Notification 창을 터치하면 초기 진입 화면이 호출된다.
1 change: 0 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ dependencies {
implementation("androidx.fragment:fragment-ktx:1.3.6")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.3.1")


implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-analytics-ktx")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import campus.tech.kakao.map.R
import campus.tech.kakao.map.view.SearchActivity
import campus.tech.kakao.map.presentation.view.SearchActivity
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
Expand Down
20 changes: 15 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
package="campus.tech.kakao.map">

<uses-permission android:name="android.permission.INTERNET" />

Expand All @@ -21,16 +21,26 @@
android:value="@string/KAKAO_API_KEY" />

<activity
android:name=".view.SplashActivity"
android:name=".presentation.view.SplashActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
<activity android:name=".view.SearchActivity" />

<activity android:name=".MainActivity" android:exported="true" />
<activity android:name=".presentation.view.SearchActivity" />

<service
android:name=".presentation.view.service.MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.api
package campus.tech.kakao.map.data.api

import com.google.gson.annotations.SerializedName
import retrofit2.http.GET
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package campus.tech.kakao.map.data.database

import androidx.room.Database
import androidx.room.RoomDatabase
import campus.tech.kakao.map.data.entity.KeywordEntity
import campus.tech.kakao.map.data.entity.LocationEntity
import campus.tech.kakao.map.domain.repository.keyword.KeywordDao
import campus.tech.kakao.map.domain.repository.location.LocationDao

@Database(entities = [KeywordEntity::class, LocationEntity::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
abstract fun keywordDao(): KeywordDao
abstract fun locationDao(): LocationDao
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.entity
package campus.tech.kakao.map.data.entity

import androidx.room.ColumnInfo
import androidx.room.Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.entity
package campus.tech.kakao.map.data.entity

import androidx.room.ColumnInfo
import androidx.room.Entity
Expand Down
14 changes: 0 additions & 14 deletions app/src/main/java/campus/tech/kakao/map/database/AppDatabase.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.model
package campus.tech.kakao.map.domain.model

import androidx.room.Entity
import androidx.room.PrimaryKey
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.model
package campus.tech.kakao.map.domain.model

data class Location(
val place: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package campus.tech.kakao.map.repository.keyword
package campus.tech.kakao.map.domain.repository.keyword

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import campus.tech.kakao.map.entity.KeywordEntity
import campus.tech.kakao.map.data.entity.KeywordEntity

@Dao
interface KeywordDao {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package campus.tech.kakao.map.repository.keyword
package campus.tech.kakao.map.domain.repository.keyword

import campus.tech.kakao.map.entity.KeywordEntity
import campus.tech.kakao.map.data.entity.KeywordEntity
import javax.inject.Inject
import javax.inject.Singleton

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package campus.tech.kakao.map.repository.location
package campus.tech.kakao.map.domain.repository.location

import androidx.room.Dao
import androidx.room.Query
import campus.tech.kakao.map.entity.LocationEntity
import campus.tech.kakao.map.data.entity.LocationEntity

@Dao
interface LocationDao {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package campus.tech.kakao.map.repository.location
package campus.tech.kakao.map.domain.repository.location

import campus.tech.kakao.map.model.Location
import campus.tech.kakao.map.domain.model.Location
import javax.inject.Inject
import javax.inject.Singleton

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package campus.tech.kakao.map.di
package campus.tech.kakao.map.domain.repository.module

import campus.tech.kakao.map.api.KakaoLocalApi
import campus.tech.kakao.map.data.api.KakaoLocalApi
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package campus.tech.kakao.map.di
package campus.tech.kakao.map.domain.repository.module

import android.content.Context
import androidx.room.Room
import campus.tech.kakao.map.database.AppDatabase
import campus.tech.kakao.map.repository.keyword.KeywordDao
import campus.tech.kakao.map.repository.location.LocationDao
import campus.tech.kakao.map.repository.keyword.KeywordRepository
import campus.tech.kakao.map.repository.location.LocationSearcher
import campus.tech.kakao.map.data.database.AppDatabase
import campus.tech.kakao.map.domain.repository.keyword.KeywordDao
import campus.tech.kakao.map.domain.repository.location.LocationDao
import campus.tech.kakao.map.domain.repository.keyword.KeywordRepository
import campus.tech.kakao.map.domain.repository.location.LocationSearcher
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import com.kakao.vectormap.label.LabelOptions
import com.kakao.vectormap.label.LabelStyle
import com.kakao.vectormap.label.LabelStyles
import com.kakao.vectormap.label.LabelTextStyle
import campus.tech.kakao.map.model.Location
import campus.tech.kakao.map.repository.location.LocationSearcher
import campus.tech.kakao.map.view.SearchActivity
import campus.tech.kakao.map.viewmodel.keyword.KeywordViewModel
import campus.tech.kakao.map.viewmodel.main.MainViewModel
import campus.tech.kakao.map.view.OnSearchItemClickListener
import campus.tech.kakao.map.view.OnKeywordItemClickListener
import campus.tech.kakao.map.domain.model.Location
import campus.tech.kakao.map.domain.repository.location.LocationSearcher
import campus.tech.kakao.map.presentation.view.SearchActivity
import campus.tech.kakao.map.presentation.viewmodel.keyword.KeywordViewModel
import campus.tech.kakao.map.presentation.viewmodel.main.MainViewModel
import campus.tech.kakao.map.presentation.view.OnSearchItemClickListener
import campus.tech.kakao.map.presentation.view.OnKeywordItemClickListener
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.view
package campus.tech.kakao.map.presentation.view

interface OnKeywordItemClickListener {
fun onKeywordItemDeleteClick(keyword: String)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package campus.tech.kakao.map.presentation.view

import campus.tech.kakao.map.domain.model.Location

interface OnSearchItemClickListener {
fun onSearchItemClick(location: Location)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.view
package campus.tech.kakao.map.presentation.view

import android.app.Activity
import android.content.Intent
Expand All @@ -9,12 +9,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.doAfterTextChanged
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import campus.tech.kakao.map.adapter.keyword.KeywordAdapter
import campus.tech.kakao.map.adapter.search.SearchAdapter
import campus.tech.kakao.map.presentation.view.adapter.keyword.KeywordAdapter
import campus.tech.kakao.map.presentation.view.adapter.search.SearchAdapter
import campus.tech.kakao.map.databinding.ActivitySearchBinding
import campus.tech.kakao.map.model.Location
import campus.tech.kakao.map.viewmodel.keyword.KeywordViewModel
import campus.tech.kakao.map.viewmodel.search.SearchViewModel
import campus.tech.kakao.map.domain.model.Location
import campus.tech.kakao.map.presentation.viewmodel.keyword.KeywordViewModel
import campus.tech.kakao.map.presentation.viewmodel.search.SearchViewModel
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
Expand Down Expand Up @@ -91,4 +91,4 @@ class SearchActivity : AppCompatActivity(), OnSearchItemClickListener, OnKeyword
// 저장된 검색어 삭제
keywordViewModel.deleteKeyword(keyword)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.view
package campus.tech.kakao.map.presentation.view

import android.content.Intent
import android.os.Bundle
Expand All @@ -23,8 +23,9 @@ class SplashActivity : AppCompatActivity() {

if (serviceState) {
startActivity(Intent(this, MainActivity::class.java))
finish()
} else {
// Handle service unavailable state

Log.e("SplashActivity", "Service is unavailable: $serviceMessage")
}
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.adapter.keyword
package campus.tech.kakao.map.presentation.view.adapter.keyword

import android.view.LayoutInflater
import android.view.View
Expand All @@ -9,7 +9,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import campus.tech.kakao.map.R
import campus.tech.kakao.map.view.OnKeywordItemClickListener
import campus.tech.kakao.map.presentation.view.OnKeywordItemClickListener

class KeywordAdapter(private val onKeywordItemClickListener: OnKeywordItemClickListener) :
ListAdapter<String, KeywordAdapter.KeywordViewHolder>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package campus.tech.kakao.map.adapter.search
package campus.tech.kakao.map.presentation.view.adapter.search

import android.view.LayoutInflater
import android.view.View
Expand All @@ -9,8 +9,8 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import campus.tech.kakao.map.R
import campus.tech.kakao.map.model.Location
import campus.tech.kakao.map.view.OnSearchItemClickListener
import campus.tech.kakao.map.domain.model.Location
import campus.tech.kakao.map.presentation.view.OnSearchItemClickListener

class SearchAdapter(
private val onSearchItemClickListener: OnSearchItemClickListener
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package campus.tech.kakao.map.presentation.view.service

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import campus.tech.kakao.map.MainActivity
import campus.tech.kakao.map.R
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {

override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
Log.d(TAG, "From: ${remoteMessage.from}")

val title = remoteMessage.notification?.title ?: DEFAULT_TITLE
val body = remoteMessage.notification?.body ?: DEFAULT_BODY
sendNotification(title, body)

if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
val title = remoteMessage.data["title"] ?: DEFAULT_TITLE
val body = remoteMessage.data["body"] ?: DEFAULT_BODY
sendNotification(title, body)
}
}

private fun sendNotification(title: String, messageBody: String) {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)

val channelId = getString(R.string.default_notification_channel_id)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground) // Use ic_launcher_foreground
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)

val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT
)
notificationManager.createNotificationChannel(channel)
}

notificationManager.notify(0, notificationBuilder.build())
}

override fun onNewToken(token: String) {
super.onNewToken(token)
Log.d(TAG, "Refreshed token: $token")
// Send the token to your server if necessary
}

companion object {
private const val TAG = "MyFirebaseMsgService"
private const val DEFAULT_TITLE = "Default Title"
private const val DEFAULT_BODY = "Default Body"
}
}
Loading