Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
HABINOH committed May 20, 2024
2 parents 944817b + ca2d146 commit 6f1f2ec
Show file tree
Hide file tree
Showing 635 changed files with 30,904 additions and 215 deletions.
68 changes: 68 additions & 0 deletions android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# 울반 - NFC기반 학급 소통 앱
![](https://blog.kakaocdn.net/dn/kTWTG/btsHtPbRbMO/ApDuCfEaKyqA57ZlnGnkU0/img.png)

<div>
<h4>📱 NFC, 블루투스 기반으로 소통해요<h4>

<h4>🎯 친구들과 채팅하고 글을 쓰며 일상을 공유해요<h4>

<h4>👥 친구들과의 친밀도를 확인해요<h4>

<h4>🥇 선생님은 학생들의 소통 통계를 확인해요<h4>
</div>
<br/>

## 개요

- **한 줄 요약** : *울반* 프로젝트는 NFC와 BLE 통신을 기반으로 한 학급 소통 앱입니다.

- **기획의도** : 코로나 이후 악화된 교우관개를 개선을 위해 제작되었습니다.

- **개발 인원 및 기간**

- **개발 인원** : Android 3명, BackEnd 3명

- **프로젝트 기간** : 2024.04.08 ~ 2024.05.19

- **주요 기능**

- NFC 기반의 태깅인사, 이어달리기

- 블루투스 기반의 함께달리기

- 학급별 채팅, 게시판, 알림장

- 학급별 소통 통계

<br/><br/><br/><br/>


# 프로젝트 구조
![](https://blog.kakaocdn.net/dn/17Gn2/btsHtQhx6Ti/nfrxsULAZmdlsdLl3SJZxK/img.png)

### 기술
- Android: <span style="color:yellowgreen"> Hilt, Jetpack AAC(ViewModel, Room), Jetpack Compose, Paging</span>
- Kotlin : <span style="color:blueviolet"> Coroutine, Flow, KotlinSerialization</span>
- Library : <span style="color:orange"> Retrofit, Coil, FCM, KakaoSocialAuth, KrossBow(Stomp)</span>
- Architecture : <span style="color:gray"> MVI, MultiModule, CleanArchitecture</span>
- Connection : NFC, BlueTooth
<br/><br/><br/><br/>


# 동작 화면

**주요 동작화면은 추후 추가 예정입니다.**

### [피그마](https://www.figma.com/design/yfm5gTmRJED2uAdm7H70YC/6-kids-on-the-block?node-id=0%3A1&t=5blyLSniokJVPpQR-1)


<br/><br/><br/>
## 개발 환경

- Android Studio : Iguana | 2023.2.1 Patch 2
- Gradle JDK : jbr-17(JetBrains Runtime version 17.0.6)
- Android Gradle Plugin Version : 8.1.3
- Gradle Version : 8.1
- Kotlin version : 1.8.0

## 역할
3 changes: 2 additions & 1 deletion android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/build
/build
/google-services.json
25 changes: 25 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
import java.util.Properties

plugins {
alias(libs.plugins.sixkids.android.application)
}

fun getProperty(propertyKey: String): String =
gradleLocalProperties(rootDir, providers).getProperty(propertyKey)

android {
namespace = "com.sixkids.ulban"
defaultConfig {
applicationId = "com.sixkids.ulban"
versionCode = 1
versionName = "1.0"

val localProperties = Properties()
val localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localProperties.load(localPropertiesFile.inputStream())
}

val nativeAppKey = localProperties.getProperty("KAKAO_NATIVE_APP_KEY") ?: ""
manifestPlaceholders["NATIVE_APP_KEY"] = nativeAppKey

buildConfigField("String", "KAKAO_NATIVE_APP_KEY", "\"${nativeAppKey}\"")
}

buildFeatures {
buildConfig = true
}
}

dependencies {
implementation(projects.feature.navigator)
implementation(projects.data)
implementation(libs.kakao.user)
implementation(platform(libs.firebase.bom))
implementation(libs.bundles.firebase)
}
32 changes: 29 additions & 3 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,41 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

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

<application
android:name=".UlbanApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:icon="@mipmap/ic_app_icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:roundIcon="@mipmap/ic_app_icon_round"
android:supportsRtl="true"
tools:targetApi="31"/>
tools:targetApi="31">

<activity
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<!-- Redirect URI: "kakao${NATIVE_APP_KEY}://oauth" -->
<data android:host="oauth"
android:scheme="kakao${NATIVE_APP_KEY}" />
</intent-filter>
</activity>

<service
android:name=".UlbanFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>

</manifest>
Binary file added android/app/src/main/ic_app_icon-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 21 additions & 1 deletion android/app/src/main/java/com/sixkids/ulban/UlbanApplication.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
package com.sixkids.ulban

import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import com.kakao.sdk.common.KakaoSdk
import com.sixkids.ulban.UlbanFirebaseMessagingService.Companion.CHANNEL_ID
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class UlbanApplication: Application(){
class UlbanApplication : Application() {
override fun onCreate() {
super.onCreate()
createNotificationChannel()

KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
}

private fun createNotificationChannel() {
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, "Ulban", importance)

val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.sixkids.ulban

import android.Manifest
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.sixkids.designsystem.R
import com.sixkids.feature.navigator.MainActivity

private const val TAG = "D107"
class UlbanFirebaseMessagingService : FirebaseMessagingService() {

override fun onNewToken(token: String) {
super.onNewToken(token)
Log.d(TAG, "onNewToken: $token")
}
override fun onMessageReceived(message: RemoteMessage) {
var messageTitle = ""
var messageContent = ""

message.notification?.let {
messageTitle = it.title.toString()
messageContent = it.body.toString()
} ?: run {
message.data.isNotEmpty().let {
messageTitle = message.data["title"].toString()
messageContent = message.data["body"].toString()
}
}


val mainIntent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

val pendingIntentFlags =
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT

val mainPendingIntent: PendingIntent = PendingIntent.getActivity(
this,
0,
mainIntent,
pendingIntentFlags,
)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.announce)
.setContentTitle(messageTitle)
.setContentText(messageContent)
.setAutoCancel(true)
.setContentIntent(mainPendingIntent)

val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.POST_NOTIFICATIONS,
) != PackageManager.PERMISSION_GRANTED
) {
return
}
}

notificationManager.notify(107, builder.build())

}

companion object {
const val CHANNEL_ID = "ULBAN_NOTIFICATION_CHANNEL"
}


}
74 changes: 74 additions & 0 deletions android/app/src/main/res/drawable/ic_app_icon_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>
5 changes: 5 additions & 0 deletions android/app/src/main/res/mipmap-anydpi-v26/ic_app_icon.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_app_icon_background"/>
<foreground android:drawable="@mipmap/ic_app_icon_foreground"/>
</adaptive-icon>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_app_icon_background"/>
<foreground android:drawable="@mipmap/ic_app_icon_foreground"/>
</adaptive-icon>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<resources>
<string name="app_name">ulban</string>
<string name="app_name">울반</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal class AndroidApplicationConventionPlugin : Plugin<Project>{
apply("com.android.application")
apply("org.jetbrains.kotlin.android")
apply("sixkids.android.hilt")
apply("com.google.gms.google-services")
}

extensions.configure<ApplicationExtension>{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import com.sixkids.convention.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
Expand All @@ -17,6 +18,8 @@ class FeatureComposeConventionPlugin: Plugin<Project> {
"implementation"(project(":core:ui"))
"implementation"(project(":core:designsystem"))
"implementation"(project(":domain"))
"implementation"(libs.findLibrary("coil-compose").get())

}
}
}
Expand Down
Loading

0 comments on commit 6f1f2ec

Please sign in to comment.