Skip to content

Commit

Permalink
Merge pull request #381 from 6QuizOnTheBlock/AND_develop
Browse files Browse the repository at this point in the history
And develop
  • Loading branch information
ghddbwns9808 authored May 20, 2024
2 parents d0081be + 9cdbe92 commit ca2d146
Show file tree
Hide file tree
Showing 513 changed files with 22,959 additions and 493 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

## 역할
7 changes: 4 additions & 3 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
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">

<activity
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
android:exported="true">
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
Expand Down
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.
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>
8 changes: 8 additions & 0 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ plugins {
alias(libs.plugins.hilt) apply false
alias(libs.plugins.googleServices) apply false
}

buildscript{
repositories {
mavenCentral()
google()
maven ( url = "https://jitpack.io" )
}
}
1 change: 1 addition & 0 deletions android/core/bluetooth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
15 changes: 15 additions & 0 deletions android/core/bluetooth/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
plugins {
alias(libs.plugins.sixkids.android.library)
alias(libs.plugins.sixkids.android.hilt)
}

android {
namespace = "com.sixkids.core.bluetooth"

}

dependencies {
implementation(libs.androidx.annotation.jvm)
implementation(libs.kotlinx.coroutines.core)
implementation(projects.core.model)
}
Empty file.
21 changes: 21 additions & 0 deletions android/core/bluetooth/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
17 changes: 17 additions & 0 deletions android/core/bluetooth/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.sixkids.core.bluetooth

import android.Manifest
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.content.Context
import android.os.ParcelUuid
import android.util.Log
import androidx.annotation.RequiresPermission
import com.sixkids.core.bluetooth.BluetoothServer.Companion.ULBAN_UUID
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import java.nio.ByteBuffer
import java.util.UUID

private const val TAG = "D107 ble"

class BluetoothScanner(context: Context) {
private val bluetooth = context.getSystemService(Context.BLUETOOTH_SERVICE)
as? BluetoothManager ?: throw Exception("This device doesn't support Bluetooth")

private val scanner: BluetoothLeScanner
get() = bluetooth.adapter.bluetoothLeScanner

val isScanning = MutableStateFlow(false)
val foundDevices = MutableStateFlow<List<Long>>(emptyList())

private val scanCallback = object : ScanCallback() {
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
override fun onScanResult(callbackType: Int, result: ScanResult?) {
super.onScanResult(callbackType, result)
result ?: return

val bytes = result.scanRecord?.getServiceData(ParcelUuid(UUID.fromString(ULBAN_UUID)))

bytes?.let {
val memberId = ByteBuffer.wrap(bytes).long
if (!foundDevices.value.contains(memberId)) {
foundDevices.update { it + memberId }
}
}
}

override fun onBatchScanResults(results: MutableList<ScanResult>?) {
super.onBatchScanResults(results)
}

override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
Log.d(TAG, "onScanFailed: 실패")
isScanning.value = false
}
}

@RequiresPermission(Manifest.permission.BLUETOOTH_SCAN)
fun startScanning() {
scanner.startScan(scanCallback)
isScanning.value = true
}

@RequiresPermission(Manifest.permission.BLUETOOTH_SCAN)
fun stopScanning() {
scanner.stopScan(scanCallback)
isScanning.value = false
}

fun removeDevice(memberId: Long) {
foundDevices.update { it - memberId }
}

}
Loading

0 comments on commit ca2d146

Please sign in to comment.