2026/04/15
오늘의 이야기
#스하리1000명프로젝트,
迷失在韓國?即使您不會說韓語,這個應用程式也可以幫助您輕鬆出行。
只需說出您的語言即可 - 它會翻譯、搜尋並以您的語言顯示結果。
非常適合旅行者!支援英語、日語、中文、越南語等10多種語言。
現在就試試吧!
https://play.google.com/store/apps/details?id=com.billcoreatech.opdgang1127
2026/04/14
오늘의 이야기
Python을 이용한 Firebase Realtime Database 생성 및 Android Studio를 통한 데이터 읽기
안녕하세요! 오늘은 Python을 사용해 Excel 데이터를 Firebase Realtime Database에 업로드하고, Android Studio를 통해 해당 데이터를 읽어오는 방법을 소개하려고 합니다. 이 과정에서 발생할 수 있는 주요 오류와 대처 방안도 함께 살펴보겠습니다.
Python을 이용한 Firebase Realtime Database 생성
1. 라이브러리 설치
먼저 필요한 라이브러리를 설치합니다.
pip install openpyxl firebase-admin
2. Firebase 초기화 및 Excel 파일 읽기
다음 코드를 작성하여 Excel 파일을 읽고 Firebase에 데이터를 업로드합니다.
import openpyxl
import firebase_admin
from firebase_admin import credentials, db
# Firebase 초기화
cred = credentials.Certificate("serviceAccountKey.json")
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://your-database-name.firebaseio.com/'
})
# Excel 파일 읽기
workbook = openpyxl.load_workbook('your_excel_file.xlsx')
sheet = workbook.active
# 데이터 Firebase에 업로드
for row in sheet.iter_rows(min_row=2, values_only=True): # 첫 번째 행은 헤더로 간주
data = {
'column1': row[0],
'column2': row[1],
# 필요한 만큼 추가
}
db.reference('path/to/your/data').push(data)
print("데이터가 성공적으로 Firebase에 저장되었습니다.")
Android Studio에서 Firebase 데이터 읽기
1. Gradle 설정
build.gradle 파일에 Firebase 의존성을 추가합니다.
dependencies {
implementation 'com.google.firebase:firebase-database:20.0.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
}
2. ViewModel 정의 및 LiveData 설정
다음 코드를 작성하여 ViewModel에서 Firebase 데이터를 읽고 LiveData에 저장합니다.
class MyViewModel : ViewModel() {
private val database = FirebaseDatabase.getInstance().reference
private val _data = MutableLiveData<List<Record>>()
val data: LiveData<List<Record>> get() = _data
init {
fetchDataFromFirebase()
}
private fun fetchDataFromFirebase() {
database.child("path/to/data").addChildEventListener(object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
val recordList = _data.value?.toMutableList() ?: mutableListOf()
val record = snapshot.getValue(Record::class.java)
record?.let { recordList.add(it) }
_data.value = recordList
}
override fun onCancelled(error: DatabaseError) {}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onChildRemoved(snapshot: DataSnapshot) {}
})
}
}
3. Activity에서 LiveData 관찰
Activity에서 ViewModel과 LiveData를 관찰하여 UI를 업데이트합니다.
class MainActivity : AppCompatActivity() {
private val myViewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myViewModel.data.observe(this, Observer { recordList ->
// UI 업데이트
for (record in recordList) {
println("Field1: ${record.field1}")
println("Field2: ${record.field2}")
println("Field3: ${record.field3}")
println("Field4: ${record.field4}")
println("Field5: ${record.field5}")
println("Field6: ${record.field6}")
}
})
}
}
오류 및 대처 방안
- Firebase Realtime Database 연결 강제 종료
- 오류: Firebase Database connection was forcefully killed by the server.
- 원인: 데이터베이스가 다른 지역에 위치.
- 해결: 데이터베이스 URL을 올바르게 설정.
- Firebase 데이터 클래스 빈 생성자 오류
- 오류: Class does not define a no-argument constructor.
- 해결: 데이터 클래스에 빈 생성자 추가.
kotlin
복사
data class Record(
val field1: String? = null,
val field2: String? = null,
// 필요한 필드 추가
) {
constructor() : this(null, null, null, null, null, null)
}
이렇게 하면 Python과 Android Studio를 사용해 Firebase Realtime Database를 효과적으로 관리할 수 있습니다. 추가적인 질문이나 도움이 필요하시면 언제든지 말씀해 주세요!
오늘의 이야기
Room Database Migration: 칼럼 추가와 데이터 타입 변경
안녕하세요! 이번 포스트에서는 Room 데이터베이스에서 마이그레이션을 통해 칼럼을 추가하고 데이터 타입을 변경하는 방법에 대해 알아보겠습니다. 이 포스트를 통해 데이터베이스 마이그레이션을 원활하게 처리하는 방법을 배우실 수 있습니다.
1. 기본적인 칼럼 추가
새로운 칼럼을 추가할 때는 마이그레이션 클래스를 작성하여 ALTER TABLE SQL 명령어를 사용합니다. 예를 들어, new_column이라는 INTEGER 칼럼을 example_table에 추가하는 방법은 다음과 같습니다:
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE example_table ADD COLUMN new_column INTEGER NOT NULL DEFAULT 0")
}
}
2. Boolean 칼럼 추가
Room에서는 Boolean 타입을 직접 지원하지 않기 때문에, INTEGER 타입을 사용하여 0과 1로 표현합니다. deviceInfo 테이블에 deviceSelected라는 Boolean 칼럼을 추가하는 예제는 다음과 같습니다:
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE deviceInfo ADD COLUMN deviceSelected INTEGER NOT NULL DEFAULT 0")
}
}
3. 데이터베이스 빌더에 마이그레이션 추가
데이터베이스 빌더에 마이그레이션을 추가하여 데이터베이스 인스턴스를 생성합니다:
val db = Room.databaseBuilder(applicationContext, AppDatabase::class.java, "database-name")
.addMigrations(MIGRATION_1_2)
.build()
4. 데이터베이스 버전 업데이트
@Database 어노테이션에서 데이터베이스 버전을 업데이트합니다:
@Database(entities = [DeviceInfo::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
abstract fun deviceInfoDao(): DeviceInfoDao
}
5. 전체 마이그레이션 과정 요약
위 단계를 통해 데이터베이스 마이그레이션을 원활하게 처리할 수 있습니다. 새로운 칼럼을 추가하거나 데이터 타입을 변경할 때는 항상 주의 깊게 작업해야 하며, 마이그레이션 로직을 정확하게 작성하는 것이 중요합니다.
오늘의 이야기
#스하리1000명프로젝트
오늘 내가 만든앱 하나 알려주고 싶어, 이 앱은 알림수집기 라고 이름을 붙였는 데,
내 폰에 표시 되는 알림을 읽어서 내가 지정한 단어가 들어 있고, 지출기록을 남겨야 하는 알림이
있으면 수집하고, 카카오톡으로 친구에게 전달해 주는 기능을 구현해 줄꺼야. 📲
이번 패치에서는 하루 한번 지정한 시간에 나에게 알림(노티) 하도록 기능을 추가 했어. 🙏
한번 써보고 불편한 거 있으면 말해줘.
앱 바로가기
👉 https://play.google.com/store/apps/details?id=com.nari.notify2kakao
오늘의 이야기
Python 정규식으로 문자열에서 특정 문자만 남기기
Python에서 정규식을 사용하여 문자열에서 특정 문자만 남기고 나머지를 제거하는 방법을 알아보겠습니다. 예를 들어, 영문자, 숫자, 밑줄(_), 하이픈(-), <, 그리고 공백을 제외한 모든 문자를 제거하는 방법을 살펴보겠습니다.
정규식 치환 예제
다음은 정규식을 사용하여 문자열에서 특정 문자만 남기고 나머지를 제거하는 예제입니다:
Python
import re
text = "Hello, World! 1234 @#$%^&*()_+-<> "
# 정규식을 사용하여 영문자, 숫자, 밑줄, 하이픈, <, 공백을 제외한 모든 문자 치환
result = re.sub(r'[^A-Za-z0-9_<\-\s]', '', text)
print(result) # "Hello World 1234 _-<> "
AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
코드 설명
모듈 임포트: re 모듈을 임포트합니다.
문자열 정의: 예제로 사용할 문자열을 정의합니다.
정규식 패턴: [^A-Za-z0-9_<\-\s] 패턴을 사용하여 영문자, 숫자, 밑줄, 하이픈, <, 공백을 제외한 모든 문자를 빈 문자열로 치환합니다.
[^...]: 대괄호 안에 있는 문자들을 제외한 모든 문자를 매칭합니다.
A-Za-z: 모든 영문자.
0-9: 모든 숫자.
_: 밑줄.
-: 하이픈.
<: < 문자.
\s: 공백 문자.
치환 및 출력: re.sub() 함수를 사용하여 치환하고 결과를 출력합니다.
결론
이 방법을 사용하면 문자열에서 특정 문자만 남기고 나머지를 제거할 수 있습니다. 정규식을 활용하면 다양한 문자열 처리 작업을 효율적으로 수행할 수 있습니다.
이 포스트가 도움이 되길 바랍니다! 다른 질문이 있으면 언제든지 알려주세요. 😊
오늘의 이야기
공공데이터를 사용하여 Python으로 데이터 수집 및 처리하기
안녕하세요! 오늘은 공공데이터를 활용하여 Python을 사용해 데이터를 수집하고 처리하는 방법에 대해 소개해드리려고 합니다. 이번 예제에서는 http://apis.data.go.kr/1471000/MdcinGrnIdntfcInfoService01/getMdcinGrnIdntfcInfoList01 API를 사용하여 의약품 정보를 가져오는 과정을 다룹니다.
준비물
- Python 설치
- requests 라이브러리 설치
먼저, requests 라이브러리를 설치합니다:
sh
복사
pip install requests
API 키 발급
공공데이터 포털에서 API 키를 발급받아야 합니다. 발급받은 키를 활용하여 데이터를 요청합니다.
코드 예제
다음은 API를 호출하고 응답 데이터를 처리하는 Python 예제 코드입니다:
python
복사
import requests
# API URL과 키 설정
api_url = "http://apis.data.go.kr/1471000/MdcinGrnIdntfcInfoService01/getMdcinGrnIdntfcInfoList01"
api_key = "YOUR_API_KEY" # 여기서 API 키를 입력하세요.
# 요청 파라미터 설정
params = {
'serviceKey': api_key,
'numOfRows': 10,
'pageNo': 1,
'type': 'json'
}
# API 호출
response = requests.get(api_url, params=params)
# 응답 상태 확인
if response.status_code == 200:
data = response.json()
# 응답 데이터 처리
items = data.get('body', {}).get('items', [])
for item in items:
print(f"품목명: {item.get('ITEM_NAME')}, 성분명: {item.get('MATERIAL_NAME')}")
else:
print("API 요청 실패:", response.status_code)
주요 단계
- API URL 및 키 설정: 발급받은 API 키를 사용하여 요청 URL을 구성합니다.
- 요청 파라미터 설정: 필요한 파라미터를 설정하여 API 요청을 준비합니다.
- API 호출: requests.get() 메서드를 사용하여 API 호출을 수행합니다.
- 응답 상태 확인: 응답 상태 코드를 확인하여 요청이 성공적으로 처리되었는지 확인합니다.
- 응답 데이터 처리: 응답 데이터를 JSON 형식으로 파싱하여 필요한 정보를 추출합니다.
이 예제에서는 공공데이터 포털의 API를 사용하여 의약품 정보를 가져오고, 이를 Python으로 처리하는 방법을 보여줍니다. API를 활용하면 다양한 공공데이터를 쉽게 사용할 수 있으니, 여러분도 한번 시도해 보세요!
오늘의 이야기
#스하리1000명프로젝트
오늘 내가 만든앱 하나 알려주고 싶어, 이 앱은 알림수집기 라고 이름을 붙였는 데,
내 폰에 표시 되는 알림을 읽어서 내가 지정한 단어가 들어 있고, 지출기록을 남겨야 하는 알림이
있으면 수집하고, 카카오톡으로 친구에게 전달해 주는 기능을 구현해 줄꺼야. 📲
이번 패치에서는 하루 한번 지정한 시간에 나에게 알림(노티) 하도록 기능을 추가 했어. 🙏
한번 써보고 불편한 거 있으면 말해줘.
앱 바로가기
👉 https://play.google.com/store/apps/details?id=com.nari.notify2kakao
오늘의 이야기
Android Foreground Services 사용법
안녕하세요! 이번 포스트에서는 Android Foreground Services에 대해 알아보겠습니다. Foreground Service는 사용자가 앱과 상호작용하지 않더라도 백그라운드에서 지속적으로 실행되어야 하는 작업을 수행하는 데 사용됩니다. 아래는 Foreground Service 설정 방법에 대한 자세한 설명입니다.
1. 서비스 클래스 생성
먼저 Service를 상속받는 서비스 클래스를 정의합니다.
class MyForegroundService : Service() {
private lateinit var notification: Notification
override fun onCreate() {
super.onCreate()
startForeground(1, createNotification())
}
private fun createNotification(): Notification {
val builder = NotificationCompat.Builder(this, "channel_id")
.setContentTitle("Foreground Service")
.setContentText("This is a foreground service")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(PendingIntent.getActivity(this, 0, Intent(this, MainActivity::class.java), 0))
.setAutoCancel(false)
// android api 26 이상의 경우 필요
val channel = NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
return builder.build()
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onDestroy() {
super.onDestroy()
stopForeground(true)
}
}2. 서비스 시작
서비스를 시작하려면 액티비티나 프래그먼트에서 다음과 같이 호출합니다.
val serviceIntent = Intent(this, MyForegroundService::class.java)
// android api 30 이상의 경우
startForegroundService(serviceIntent)3. AndroidManifest.xml 설정
AndroidManifest.xml 파일에 서비스 선언을 추가합니다.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<application
...
<service
android:name=".MyForegroundService"
android:exported="false"
android:foregroundServiceType="connectedDevice"
/>
</application>4. Notification Channel 생성
앱이 Android Oreo(API 레벨 26) 이상을 타겟으로 하는 경우, Notification Channel을 생성해야 합니다.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}
5. Deprecated 메서드 대체
stopForeground 메서드가 deprecated 되었기 때문에, 대신 stopSelf 또는 stopService 메서드를 사용합니다.
override fun onDestroy() {
super.onDestroy()
stopSelf()
}
6. 안드로이드 생명 주기와 서비스 관리
적절한 시점에 startService와 stopService를 호출하여 서비스의 시작과 종료를 관리해야 합니다. 예를 들어:
- onCreate() 또는 onStart(): 앱이 처음 실행될 때.
- onDestroy(): 앱이 종료될 때.
이 포스트가 Android Foreground Services 설정과 관리에 도움이 되길 바랍니다. 궁금한 점이 있으면 언제든지 댓글로 남겨주세요! 😊
오늘의 이야기
#스하리1000명프로젝트,
Lost in Korea?即使您不会说韩语,这个应用程序也可以帮助您轻松出行。
只需说出您的语言即可 - 它会翻译、搜索并以您的语言显示结果。
非常适合旅行者!支持英语、日语、中文、越南语等10多种语言。
现在就试试吧!
https://play.google.com/store/apps/details?id=com.billcoreatech.opdgang1127
오늘의 이야기
#스치니1000프로젝트 #재미 #행운기원 #Compose #Firebase
🎯 야 너 토요일마다 로또 확인하냐?
나도 맨날 “혹시나~” 하면서 봤거든 ㅋㅋ
근데 이제는 그냥 안 해
AI한테 맡겼어 🤖✨
그것도 구글 Gemini로다가!
그래서 앱 하나 만들었지
👉 “로또 예상번호 by Gemini” 🎱
AI가 분석해서 번호 딱! 뽑아줌
그냥 보고 참고만 하면 됨
재미로 해도 좋고…
혹시 모르는 거잖아? 😏
https://play.google.com/store/apps/details?id=com.billcorea.gptlotto1127
2026/04/13
오늘의 이야기
#스하리1000명프로젝트,
Às vezes é difícil conversar com trabalhadores estrangeiros, certo?
Fiz um aplicativo simples que ajuda! Você escreve na sua língua e os outros veem na deles.
Ele é traduzido automaticamente com base nas configurações.
Muito útil para bate-papos fáceis. Dê uma olhada quando tiver uma chance!
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416
오늘의 이야기
#스치니1000프로젝트 #재미 #행운기원 #Compose #Firebase 🎯 야 너 토요일마다 로또 확인하냐? 나도 맨날 “혹시나~” 하면서 봤거든 ㅋㅋ 근데 이제는 그냥 안 해 AI한테 맡겼어 🤖✨ 그것도 구글 Gemini로다가! ...