Home - GachonCapstoneTeam/TTS_JAVA GitHub Wiki

ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

๐Ÿ” ํ”„๋กœ์ ํŠธ ์„ค๋ช…

TalkStock์€ ์ฆ๊ถŒ์‚ฌ ๋ฆฌํฌํŠธ๋ฅผ ์š”์•ฝ ์ œ๊ณตํ•˜๊ณ , ์ด๋ฅผ **TTS(Text-to-Speech)**๋กœ ๋ณ€ํ™˜ํ•ด
์–ธ์ œ ์–ด๋””์„œ๋‚˜ ํ•ธ์ฆˆํ”„๋ฆฌ๋กœ ์ฒญ์ทจํ•  ์ˆ˜ ์žˆ๋Š” Android ๊ธฐ๋ฐ˜ ๋ชจ๋ฐ”์ผ ์•ฑ์ž…๋‹ˆ๋‹ค.
์ด๋™ ์ค‘์ด๊ฑฐ๋‚˜ ๊ธ€์„ ์ฝ๊ธฐ ์–ด๋ ค์šด ์ƒํ™ฉ์—์„œ๋„ ์‰ฝ๊ฒŒ ์ •๋ณด๋ฅผ ์Šต๋“ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


๐ŸŽฏ ๊ฐœ๋ฐœ ๋ชฉํ‘œ

  • ์ฆ๊ถŒ ๋ฆฌํฌํŠธ๋ฅผ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•ด ์ด๋™ ์ค‘์—๋„ ํŽธ๋ฆฌํ•œ ์ •๋ณด ์ฒญ์ทจ ์ œ๊ณต
  • ์ดˆ๋ณด์ž๋„ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์š”์•ฝ ์ค‘์‹ฌ์˜ ์ง๊ด€์ ์ธ UI ์ œ๊ณต
  • ์ข‹์•„์š” ๊ธฐ๋ฐ˜ ์žฌ์ƒ๋ชฉ๋ก, ์ถ”์ฒœ ์ฝ˜ํ…์ธ , ์ด์–ด๋“ฃ๊ธฐ ๊ธฐ๋Šฅ ๋“ฑ ์‚ฌ์šฉ์ž ๋งž์ถค ๊ธฐ๋Šฅ ์ œ๊ณต
  • ์ •๋ณด ์ ‘๊ทผ์„ฑ๊ณผ ํŽธ์˜์„ฑ ํ–ฅ์ƒ์„ ํ†ตํ•œ ๋ฆฌํฌํŠธ ์†Œ๋น„ ๋ฐฉ์‹ ๊ฐœ์„ 

์•ฑ ๊ตฌ์กฐ ๋ฐ ์•„ํ‚คํ…์ฒ˜

๐Ÿ“ฑ ์ฃผ์š” ํ™”๋ฉด ๊ตฌ์„ฑ

TalkStock์€ ์ด **4๊ฐœ์˜ ํ•ต์‹ฌ ํ™”๋ฉด(Activity/Fragment)**์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค:

ํ™”๋ฉด ๊ตฌ์„ฑ ์„ค๋ช…
SplashActivity ์ž๋™ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ ์ดˆ๊ธฐ ์ง„์ž…
LoginActivity / SignUpActivity ์ด๋ฉ”์ผ ๋˜๋Š” Google ๊ณ„์ • ๊ธฐ๋ฐ˜ ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž…
basic_layout ์•ฑ ๋ฉ”์ธ ํ™”๋ฉด (Bottom Navigation + ViewPager2)
HomeFragment TTS ๊ธฐ๋ฐ˜ ์˜ค๋””์˜ค ํ”Œ๋ ˆ์ด์–ด ๋ฐ ์ข‹์•„์š” ๋ชฉ๋ก
SearchFragment ๋ฆฌํฌํŠธ ๊ฒ€์ƒ‰ ๋ฐ ํ•„ํ„ฐ ๊ธฐ๋Šฅ
RecommendFragment ์ถ”์ฒœ/์ธ๊ธฐ ๋ฆฌํฌํŠธ ์Šฌ๋ผ์ด๋“œ ๋ทฐ
OriginalActivity ์ „์ฒด ๋ฆฌํฌํŠธ ๋ณธ๋ฌธ + ์˜ค๋””์˜ค ์žฌ์ƒ ํ™”๋ฉด
SimplePlayerActivity ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋‹จ์ผ ๋ฆฌํฌํŠธ ํ”Œ๋ ˆ์ด ํ™”๋ฉด

๐Ÿงญ ํ™”๋ฉด ์ „ํ™˜ ํ๋ฆ„

๋ฉ”๋‰ด ๊ตฌ์กฐ๋„


๐Ÿ“ฆ ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”

TalkStock์€ ๋‹จ์ผ Activity - ๋‹ค์ค‘ Fragment ๊ตฌ์กฐ๋กœ ์„ค๊ณ„๋˜๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค:

  • Fragment ๊ฐ„ ์ „ํ™˜: ViewPager2 + BottomNavigationView๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„
  • ๋ฐ์ดํ„ฐ ํ†ต์‹ : OkHttp + REST API๋กœ ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ ์š”์ฒญ
  • ๋กœ์ปฌ ์ €์žฅ: SharedPreferences ๊ธฐ๋ฐ˜์œผ๋กœ ์ข‹์•„์š”/์ž๋™๋กœ๊ทธ์ธ ์ •๋ณด ์ €์žฅ
  • TTS ๋ณ€ํ™˜: Google TTS๋ฅผ ํ†ตํ•ด mp3 ํŒŒ์ผ ์ƒ์„ฑ ํ›„ ์บ์‹œ ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅ
  • ์˜ค๋””์˜ค ์žฌ์ƒ ์„œ๋น„์Šค: ForegroundService๋ฅผ ํ†ตํ•ด Fragment/Activity ๊ฐ„ ์ด์–ด๋“ฃ๊ธฐ ์œ ์ง€
  • UI ๋™๊ธฐํ™”: LocalBroadcastManager๋ฅผ ํ†ตํ•ด ์ข‹์•„์š” ์ƒํƒœ ๋ฐ˜์˜ ๋“ฑ ์ฒ˜๋ฆฌ

๐Ÿ—‚๏ธ ์ €์žฅ ๊ตฌ์กฐ ์š”์•ฝ

ํ•ญ๋ชฉ ๋ฐฉ์‹ ์„ค๋ช…
๋กœ๊ทธ์ธ ์ •๋ณด Firebase Auth ์ด๋ฉ”์ผ / Google ๋กœ๊ทธ์ธ
์ข‹์•„์š” ๋ชฉ๋ก SharedPreferences "liked_๋ฆฌํฌํŠธ์ œ๋ชฉ" ํ˜•ํƒœ๋กœ ์ €์žฅ
์ž๋™ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ SharedPreferences isLoggedIn = true
์Œ์„ฑ ํŒŒ์ผ Internal Cache ํŒŒ์ผ๋ช….mp3 ํ˜•ํƒœ๋กœ ์ €์žฅ
TTS ์บ์‹œ Google TTS ๋ณ€ํ™˜ ํ›„ ์บ์‹œ๋œ ํŒŒ์ผ๋กœ ์žฌ์ƒ

๐Ÿ“Œ ๊ธฐํƒ€

  • ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ์‹คํŒจ ์‹œ ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋กœ fallback ์ฒ˜๋ฆฌ
  • Shimmer UI ๋กœ๋”ฉ ๊ตฌํ˜„ (Home / Search / Recommend)
  • ์‹ค์‹œ๊ฐ„ ์žฌ์ƒ ์ƒํƒœ ๋ฐ˜์˜์„ ์œ„ํ•ด AudioService์—์„œ ์ฝœ๋ฐฑ ์ฒ˜๋ฆฌ ๋ฐ UI ๊ฐฑ์‹ 

๐Ÿ“ฒ ํ™”๋ฉด๋ณ„ ๊ธฐ๋Šฅ ์š”์•ฝ

TalkStock์€ ์‚ฌ์šฉ์ž ํŽธ์˜์„ฑ๊ณผ ์ •๋ณด ์ ‘๊ทผ์„ฑ์„ ๊ณ ๋ คํ•ด ํ•ต์‹ฌ ํ™”๋ฉด ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๊ฐ ํ™”๋ฉด์€ ๋…๋ฆฝ์ ์ธ ์—ญํ• ์„ ๊ฐ€์ง€๋ฉฐ, ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค:

๐Ÿ” ์ƒ์„ธ ํ™”๋ฉด: '๊ธฐ๋Šฅ ์š”์•ฝ'


๐Ÿ  HomeFragment

๊ธฐ๋Šฅ ์„ค๋ช…
์˜ค๋””์˜ค ํ”Œ๋ ˆ์ด์–ด UI ๋ฆฌํฌํŠธ ์ œ๋ชฉ / ์ฆ๊ถŒ์‚ฌ / ์žฌ์ƒ ์‹œ๊ฐ„ ํ‘œ์‹œ
TTS ์žฌ์ƒ ๋ฆฌํฌํŠธ ๋‚ด์šฉ์„ Google TTS๋กœ ๋ณ€ํ™˜ํ•ด mp3 ์žฌ์ƒ
์ด์–ด๋“ฃ๊ธฐ ๋‹ค๋ฅธ Fragment ๋˜๋Š” Activity ์ด๋™ ํ›„์—๋„ ์žฌ์ƒ ์ง€์†
์ข‹์•„์š” ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ "๋‚ด ๋ชฉ๋ก" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ข‹์•„์š”ํ•œ ๋ฆฌํฌํŠธ๋งŒ ํ‘œ์‹œ
Top10/์ตœ์‹  ๋ชฉ๋ก ์ „ํ™˜ ๋ฒ„ํŠผ ํด๋ฆญ์œผ๋กœ ์„œ๋ฒ„ ๋˜๋Š” ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์ „ํ™˜
Shimmer ๋กœ๋”ฉ ์„œ๋ฒ„ ํ†ต์‹  ์ค‘ ๋กœ๋”ฉ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ

๐Ÿ” ์ƒ์„ธ ๋กœ์ง: HomeFragment


๐Ÿ” SearchFragment

๊ธฐ๋Šฅ ์„ค๋ช…
๋ฆฌํฌํŠธ ๊ฒ€์ƒ‰ ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ ์‹œ ์„œ๋ฒ„ API ์š”์ฒญ์œผ๋กœ ๊ฒฐ๊ณผ ์กฐํšŒ
์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ ์ „์ฒด / ์ข…๋ชฉ / ์‚ฐ์—… ํƒญ์œผ๋กœ ๋ถ„๋ฅ˜ ์กฐํšŒ
์ข‹์•„์š” / TTS ๊ฐœ๋ณ„ ๋ฆฌํฌํŠธ ์นด๋“œ์—์„œ ์ข‹์•„์š” ๋“ฑ๋ก ๋ฐ TTS ์žฌ์ƒ ๊ฐ€๋Šฅ
Pull to Refresh ์Šค์™€์ดํ”„ ์‹œ ์ตœ์‹  ๋ฐ์ดํ„ฐ ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
Shimmer ๋กœ๋”ฉ ์ดˆ๊ธฐ ๋˜๋Š” ๊ฐฑ์‹  ์ค‘ ๋กœ๋”ฉ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ‘œ์‹œ

๐ŸŽง RecommendFragment

๊ธฐ๋Šฅ ์„ค๋ช…
์ถ”์ฒœ ๋ฆฌํฌํŠธ ์Šฌ๋ผ์ด๋“œ ViewPager2๋กœ ์ž๋™ ์Šฌ๋ผ์ด๋”ฉ ๋ฐฉ์‹ ๊ตฌํ˜„
์ธ๊ธฐ ๋ฆฌํฌํŠธ ์นด๋“œ ํ•˜๋‹จ์— ๋žญํ‚น ๊ธฐ๋ฐ˜ ์นด๋“œ ๋‚˜์—ด
Dot Indicator ์ œํ•œ ์ถ”์ฒœ ์Šฌ๋ผ์ด๋“œ ์ธ๋””์ผ€์ดํ„ฐ ์ตœ๋Œ€ 5๊ฐœ๋กœ ์ œํ•œ
์„œ๋ฒ„ ์—ฐ๊ฒฐ ์‹คํŒจ ์‹œ fallback ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์ž๋™ ๋กœ๋“œ ์ฒ˜๋ฆฌ

๐ŸŽผ OriginalActivity

๊ธฐ๋Šฅ ์„ค๋ช…
๋ฆฌํฌํŠธ ์ „๋ฌธ ๋ณด๊ธฐ TTS ์žฌ์ƒ ์ค‘ ์ „์ฒด ๋ฆฌํฌํŠธ ๋ณธ๋ฌธ ํ‘œ์‹œ
์˜ค๋””์˜ค ์žฌ์ƒ ์ปจํŠธ๋กค SeekBar / Play / Pause / ๋‹ค์Œ / ์ด์ „ ํŠธ๋ž™ ์ง€์›
์ด์–ด๋“ฃ๊ธฐ HomeFragment์™€ ๊ฐ™์€ ํŠธ๋ž™ ์ •๋ณด ๊ณต์œ 
์ „์ฒด ItemList ์ „๋‹ฌ Intent๋กœ itemList์™€ ํ˜„์žฌ index ์ „๋‹ฌ๋ฐ›์Œ

โ–ถ๏ธ SimplePlayerActivity

๊ธฐ๋Šฅ ์„ค๋ช…
๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋‹จ์ผ ๋ฆฌํฌํŠธ ์žฌ์ƒ SearchFragment์—์„œ TTS ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ง„์ž…
๋…๋ฆฝ์  TTS ์žฌ์ƒ HomeFragment/OriginalActivity์™€ ๋ถ„๋ฆฌ๋œ ์žฌ์ƒ ๊ตฌ์กฐ
์ตœ์†Œ UI ๊ตฌ์„ฑ ์ œ๋ชฉ, ๋‚ ์งœ, ์ฆ๊ถŒ์‚ฌ, SeekBar๋งŒ ํ‘œ์‹œ

๐Ÿ‘ค LoginActivity / SignUpActivity

๊ธฐ๋Šฅ ์„ค๋ช…
์ด๋ฉ”์ผ ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… Firebase Auth ๊ธฐ๋ฐ˜์œผ๋กœ ์ฒ˜๋ฆฌ
Google ๋กœ๊ทธ์ธ GoogleSignInClient์™€ Firebase ์—ฐ๋™
์ž๋™ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ SplashActivity์—์„œ ํ˜„์žฌ ๋กœ๊ทธ์ธ ์ƒํƒœ ์ฒดํฌ ํ›„ ๋ฐ”๋กœ ์ง„์ž… ๊ฐ€๋Šฅ

๐ŸงŠ SplashActivity

๊ธฐ๋Šฅ ์„ค๋ช…
์ดˆ๊ธฐ ๋กœ๋”ฉ ํ™”๋ฉด ์•ฑ ์‹คํ–‰ ์‹œ 1์ดˆ๊ฐ„ ๋กœ๊ณ  ๋…ธ์ถœ
์ž๋™ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ํ™•์ธ ๋กœ๊ทธ์ธ ์ •๋ณด ์กด์žฌ ์‹œ ๋ฐ”๋กœ main์œผ๋กœ ์ด๋™
SharedPreferences ์ดˆ๊ธฐํ™” PreferenceUtil์—์„œ ๋กœ๊ทธ์ธ ์ƒํƒœ ๋กœ๋“œ

๐Ÿ•ธ๏ธ Report Crawling ์š”์•ฝ

๊ตฌ๋ถ„ ์ข…๋ชฉ๋ถ„์„ ๋ฆฌํฌํŠธ ํฌ๋กค๋ง ์‚ฐ์—…๋ถ„์„ ๋ฆฌํฌํŠธ ํฌ๋กค๋ง
ํฌ๋กค๋ง ๋Œ€์ƒ ์ข…๋ชฉ๋ณ„ ๋ฆฌํฌํŠธ ์—…์ข…๋ณ„ ๋ฆฌํฌํŠธ
์ฃผ์š” ์‹๋ณ„ ํ•ญ๋ชฉ ์ข…๋ชฉ๋ช… (์ข…๋ชฉ๋ช…), ์ข…๋ชฉ ์ฝ”๋“œ (์ฝ”๋“œ) ์—…์ข…๋ช… (์—…์ข…)
์ฆ๊ถŒ์‚ฌ ํ•„ํ„ฐ๋ง SECURITIES_CONFIGS ๊ธฐ์ค€์œผ๋กœ ํ•„ํ„ฐ๋ง ๋™์ผํ•˜๊ฒŒ SECURITIES_CONFIGS ๊ธฐ์ค€
์ƒ์„ธ ๋ณธ๋ฌธ ์ถ”์ถœ HTML ์ƒ์„ธ ํŽ˜์ด์ง€ ํฌ๋กค๋ง (fetch_report_details) ๋™์ผ
๊ฒฐ๊ณผ ์ €์žฅ ํ•ญ๋ชฉ ์ข…๋ชฉ๋ช…, ์ฝ”๋“œ, ์—…์ข…, ์ œ๋ชฉ, ์ฆ๊ถŒ์‚ฌ, ์ž‘์„ฑ์ผ, ์กฐํšŒ์ˆ˜, ๋ณธ๋ฌธ, PDF ์ฝ˜ํ…์ธ  ์—…์ข…, ์ œ๋ชฉ, ์ฆ๊ถŒ์‚ฌ, ์ž‘์„ฑ์ผ, ์กฐํšŒ์ˆ˜, ๋ณธ๋ฌธ, PDF ์ฝ˜ํ…์ธ 
์ข…๋ชฉ๋ช…/์—…์ข… ๊ตฌ๋ถ„ ์ข…๋ชฉ๋ช… ๊ธฐ๋ฐ˜์œผ๋กœ ์—…์ข…์„ ๋งคํ•‘ ์—…์ข…๋ช…์ด ์ง์ ‘ ํ‘œ๊ธฐ๋จ
๋ฐ˜ํ™˜ ํ˜•์‹ List[Dict[str, str]] ํ˜•ํƒœ์˜ ๋ฆฌํฌํŠธ ์ •๋ณด ๋ฆฌ์ŠคํŠธ List[Dict[str, str]] ํ˜•ํƒœ์˜ ๋ฆฌํฌํŠธ ์ •๋ณด ๋ฆฌ์ŠคํŠธ

๋‹ค์Œ ํŽ˜์ด์ง€๋กœ ๋„˜์–ด๊ฐ€๋ ค๋ฉด ๐Ÿ‘‰ [ํ™”๋ฉด๋ณ„ ๊ธฐ๋Šฅ ์ƒ์„ธ ์„ค๋ช… ๋ฐ ๋กœ์ง ๋ถ„์„](ํ™”๋ฉด ๋ณ„ ๊ธฐ๋Šฅ ์ƒ์„ธ ์„ค๋ช…)

API ์—ฐ๋™ ์š”์•ฝ

TalkStock ์•ฑ์€ Django ๊ธฐ๋ฐ˜ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์™€ REST API๋ฅผ ํ†ตํ•ด ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.
ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋Š” OkHttpClient๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญํ•˜๋ฉฐ, JSON ์‘๋‹ต์„ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ๊ตฌ์„ฑ๋„


๐Ÿ“ฌ API ์š”์ฒญ ๋ฐฉ์‹ ์š”์•ฝ

๊ธฐ๋Šฅ HTTP Method ์—”๋“œํฌ์ธํŠธ ์„ค๋ช…
์ „์ฒด ๋ฆฌํฌํŠธ ๋ชฉ๋ก ์กฐํšŒ GET /textload/content ๋ฉ”์ธ ํ™ˆํ™”๋ฉด ์ตœ์‹  ๋ฆฌํฌํŠธ ๋กœ๋”ฉ
์ข…๋ชฉ(๊ธฐ์—…) ๋ฆฌํฌํŠธ ์กฐํšŒ GET /textload/stock SearchFragment ๊ธฐ์—… ํƒญ์šฉ
์‚ฐ์—… ๋ฆฌํฌํŠธ ์กฐํšŒ GET /textload/industry SearchFragment ์‚ฐ์—… ํƒญ์šฉ
๊ฒ€์ƒ‰ GET /textload/search/?q={query} SearchFragment ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ
์ถ”์ฒœ ๋ฆฌํฌํŠธ GET /textload/content/ RecommendFragment ์ƒ๋‹จ ์Šฌ๋ผ์ด๋“œ
์ธ๊ธฐ ๋ฆฌํฌํŠธ GET /textload/content/ RecommendFragment ํ•˜๋‹จ ์นด๋“œ (์ž„์‹œ ๋™์ผ ์—”๋“œํฌ์ธํŠธ ์‚ฌ์šฉ)
๋กœ๊ทธ์ธ (์ง์ ‘์—ฐ๊ฒฐ ์‹œ) POST /api/login/ JSON {user_id, password} ์ „์†ก

๐Ÿ”— ๊ฐ ์—”๋“œํฌ์ธํŠธ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ, ์‘๋‹ต ํฌ๋งท ๋“ฑ์€ ๋ฐฑ์—”๋“œ ๋ฌธ์„œ ์ฐธ์กฐ


๐Ÿ› ๏ธ ์—ฐ๋™ ํ๋ฆ„ ์˜ˆ์‹œ (์˜ˆ: ํ™ˆ ์ตœ์‹  ๋ชฉ๋ก)

OkHttpClient client = new OkHttpClient();
String url = "http://10.0.2.2:8000/textload/content";

Request request = new Request.Builder()
        .url(url)
        .get()
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // ์‹คํŒจ ์‹œ ๋”๋ฏธ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        String json = response.body().string();
        // JSON ํŒŒ์‹ฑ ํ›„ RecyclerView ๊ฐฑ์‹ 
    }
});

๐Ÿงช ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

  • Android Emulator์—์„œ๋Š” localhost ๋Œ€์‹  10.0.2.2 ์‚ฌ์šฉํ•ด์•ผ ์„œ๋ฒ„์™€ ํ†ต์‹  ๊ฐ€๋Šฅ
  • HTTPS๊ฐ€ ์•„๋‹Œ HTTP ์‚ฌ์šฉ ์‹œ, network_security_config.xml ์„ค์ • ํ•„์š”
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
          <domain includeSubdomains="true">10.0.2.2</domain>
    </domain-config>
</network-security-config>
  • Django ์„œ๋ฒ„๊ฐ€ ์‹คํ–‰ ์ค‘์ธ์ง€ ํ•ญ์ƒ ํ™•์ธํ•  ๊ฒƒ (python manage.py runserver)

๐Ÿงพ ๊ธฐํƒ€ ์ฐธ๊ณ  ์‚ฌํ•ญ

  • ์„œ๋ฒ„ ํ†ต์‹  ์‹คํŒจ ์‹œ โ†’ ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋กœ ์ž๋™ fallback ์ฒ˜๋ฆฌ
  • ๋ชจ๋“  API ์š”์ฒญ์€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ (enqueue) ๋˜์–ด UI thread๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š์Œ
  • ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์ค‘์—๋Š” Shimmer ์• ๋‹ˆ๋ฉ”์ด์…˜์œผ๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต
  • Fragment์˜ onDestroyView()์—์„œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด๋‚˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€

์‚ฌ์šฉ์ž ์ธ์ฆ ํ๋ฆ„

TalkStock ์•ฑ์€ Firebase Authentication์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ ๋กœ๊ทธ์ธ๊ณผ Google ๊ณ„์ • ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ Splash ํ™”๋ฉด์—์„œ ์ž๋™ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜์—ฌ ๋กœ๊ทธ์ธ ์œ ์ง€ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


โœ… ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ ๋กœ๊ทธ์ธ

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ
  • Firebase Auth์˜ signInWithEmailAndPassword(email, password) ํ˜ธ์ถœ
  • ์„ฑ๊ณต ์‹œ basic_layout(๋ฉ”์ธ ํ™”๋ฉด)์œผ๋กœ ์ด๋™
mAuth.signInWithEmailAndPassword(email, password)
     .addOnCompleteListener(task -> {
         if (task.isSuccessful()) {
             FirebaseUser user = mAuth.getCurrentUser();
             updateUI(user); // โ†’ main ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜
         }
     });

๐Ÿ”Ž Google ๊ณ„์ • ๋กœ๊ทธ์ธ

  • Google Sign-In ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ Google ๊ณ„์ • ์„ ํƒ
  • ์„ ํƒํ•œ ๊ณ„์ •์˜ ID ํ† ํฐ์„ Firebase์— ์ธ์ฆ ์š”์ฒญ
  • ์‹ ๊ทœ ์œ ์ €์ธ ๊ฒฝ์šฐ Firebase Realtime Database์— ๋‹‰๋„ค์ž„ ๋“ฑ๋ก
AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
mAuth.signInWithCredential(credential)
     .addOnCompleteListener(task -> {
         if (task.isSuccessful()) {
             FirebaseUser user = mAuth.getCurrentUser();
             // ์ƒˆ ์œ ์ €๋ผ๋ฉด DB์— ์ถ”๊ฐ€
             if (task.getResult().getAdditionalUserInfo().isNewUser()) {
                 saveGoogleUserToDatabase(user);
             }
             updateUI(user); // โ†’ main ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜
         }
     });

๐Ÿš€ ์ž๋™ ๋กœ๊ทธ์ธ (SplashActivity)

  • ์•ฑ ์‹คํ–‰ ์‹œ SplashActivity์—์„œ ๋กœ๊ทธ์ธ ์ƒํƒœ ํ™•์ธ ํ›„ ํ™”๋ฉด ์ „ํ™˜:
  • ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉด โ†’ ๋ฐ”๋กœ basic_layout์œผ๋กœ ์ด๋™
  • ์—†์œผ๋ฉด โ†’ LoginActivity๋กœ ์ด๋™
FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
if (currentUser != null) {
    startActivity(new Intent(SplashActivity.this, basic_layout.class));
} else {
    startActivity(new Intent(SplashActivity.this, LoginActivity.class));
}

๐Ÿ”“ ๋กœ๊ทธ์•„์›ƒ

  • basic_layout ์ƒ๋‹จ ๋กœ๊ทธ์•„์›ƒ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ:
    • Firebase ๋กœ๊ทธ์•„์›ƒ
    • Google ๋กœ๊ทธ์•„์›ƒ (์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ๋งŒ)
    • SharedPreferences ์ดˆ๊ธฐํ™”
    • LoginActivity๋กœ ์ด๋™
FirebaseAuth.getInstance().signOut();
googleSignInClient.signOut().addOnCompleteListener(task -> {
    PreferenceUtil.clearAll(); // SharedPreferences ์ดˆ๊ธฐํ™”
    startActivity(new Intent(this, LoginActivity.class));
    finish();
});

๐Ÿงญ ์‚ฌ์šฉ์ž ์ธ์ฆ ํ๋ฆ„ ์š”์•ฝ

๋กœ๊ทธ์ธ ๋ฐ ์ถ”์ฒœ


๐Ÿ”‘ ์ฐธ๊ณ 

  • Firebase Realtime Database์— ์‚ฌ์šฉ์ž ์ •๋ณด ์ €์žฅ ์‹œ ์‚ฌ์šฉ์ž UID๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ €์žฅ๋จ
  • ์ธ์ฆ ์ƒํƒœ๋Š” ์•ฑ ์žฌ์‹œ์ž‘ ํ›„์—๋„ Firebase๊ฐ€ ์ž๋™ ์œ ์ง€
  • ๋กœ๊ทธ์•„์›ƒ ์‹œ ์•ฑ์˜ ๋ชจ๋“  ์„ธ์…˜ ๋ฐ SharedPreferences ์ดˆ๊ธฐํ™”๋จ

์‚ฌ์šฉ ๊ธฐ์ˆ  ์Šคํƒ

TalkStock๋Š” Android ๊ธฐ๋ฐ˜์˜ ์ฆ๊ถŒ ๋ฆฌํฌํŠธ ์˜ค๋””์˜ค ์š”์•ฝ ์•ฑ์œผ๋กœ,
ํ”„๋ก ํŠธ์—”๋“œ๋Š” Java ๊ธฐ๋ฐ˜ Android Studio, ๋ฐฑ์—”๋“œ๋Š” Django + Firebase๋ฅผ ํ™œ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.


๐Ÿ“ฑ ํ”„๋ก ํŠธ์—”๋“œ (Android)

ํ•ญ๋ชฉ ๊ธฐ์ˆ  ์„ค๋ช…
์–ธ์–ด Java Android ์•ฑ ๊ฐœ๋ฐœ ์ฃผ ์–ธ์–ด
IDE Android Studio ์•ฑ UI ๋ฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„
UI ๊ตฌ์„ฑ ConstraintLayout, RecyclerView, ViewPager2 ์œ ์—ฐํ•œ ๋ ˆ์ด์•„์›ƒ ๋ฐ ๋ฆฌ์ŠคํŠธ ๊ตฌ์„ฑ
์• ๋‹ˆ๋ฉ”์ด์…˜ Facebook Shimmer ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์ค‘ ์Šค์ผˆ๋ ˆํ†ค UI ํ‘œ์‹œ
์˜ค๋””์˜ค ์ฒ˜๋ฆฌ Android MediaPlayer, TTSHelper ํ…์ŠคํŠธ๋ฅผ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•ด ์žฌ์ƒ
๋ฐ์ดํ„ฐ ์ €์žฅ SharedPreferences ์ข‹์•„์š” ๋ชฉ๋ก, ์ž๋™ ๋กœ๊ทธ์ธ ์ƒํƒœ ์ €์žฅ
API ํ†ต์‹  OkHttp + JSON ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์™€ HTTP ํ†ต์‹  ์ฒ˜๋ฆฌ
์ด๋ฏธ์ง€ ๋ฐ ์Šคํƒ€์ผ VectorDrawable, Custom drawable ์•„์ด์ฝ˜ ๋ฐ ๋ฒ„ํŠผ ์Šคํƒ€์ผ๋ง

๐Ÿ” ์ธ์ฆ ๋ฐ ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ

ํ•ญ๋ชฉ ๊ธฐ์ˆ  ์„ค๋ช…
๋กœ๊ทธ์ธ Firebase Authentication ์ด๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ, Google ๋กœ๊ทธ์ธ ์ง€์›
์ž๋™ ๋กœ๊ทธ์ธ Firebase + SharedPreferences ์•ฑ ์‹คํ–‰ ์‹œ ์‚ฌ์šฉ์ž ์ƒํƒœ ํ™•์ธ
๋กœ๊ทธ์•„์›ƒ Firebase SignOut + GoogleSignInClient ์™„์ „ํ•œ ์„ธ์…˜ ์ •๋ฆฌ ์ฒ˜๋ฆฌ

โ˜ ๋ฐฑ์—”๋“œ (์š”์•ฝ)

ํ•ญ๋ชฉ ๊ธฐ์ˆ  ์„ค๋ช…
์–ธ์–ด Python ํฌ๋กค๋ง์— ๋น„๊ต์  ๊ฐ„๋‹จํ•œ ์–ธ์–ด ์‚ฌ์šฉ
IDE phCham / vsCode ํฌ๋กค๋ง, ์ถ”์ฒœ, TTS ๊ตฌํ˜„
TTS Google Cloud Speech API Google TTS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Œ์„ฑ ์ œ๊ณต
์„œ๋ฒ„ Python (3.10+) API ๋กœ์ง ์ฒ˜๋ฆฌ ๋ฐ ์‘๋‹ต ์ œ๊ณต
DB mongoDB / mySQL / Firebase Realtime DB ์‚ฌ์šฉ์ž ์ •๋ณด ๋ฐ ๋ฆฌํฌํŠธ ์ €์žฅ
์š”์•ฝ ๊ธฐ๋Šฅ GPT API (OpenAI) ๋ฆฌํฌํŠธ ์š”์•ฝ ์ž๋™ํ™” ์ฒ˜๋ฆฌ

๐Ÿงช ํ…Œ์ŠคํŠธ ๋ฐ ๊ธฐํƒ€

ํ•ญ๋ชฉ ๋„๊ตฌ ์„ค๋ช…
ํ…Œ์ŠคํŠธ ๊ธฐ๊ธฐ Android Emulator (Pixel 5, API 30+) ๊ธฐ๋ณธ ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ
์„œ๋ฒ„ ํ™˜๊ฒฝ localhost (10.0.2.2) ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ ๊ธฐ์ค€ ๋กœ์ปฌ ๊ฐœ๋ฐœ
๋ฒ„์ „ ๊ด€๋ฆฌ Git + GitHub ํŒ€ ํ˜‘์—… ๋ฐ ์ฝ”๋“œ ๊ด€๋ฆฌ

๐Ÿ“ฆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชฉ๋ก (build.gradle)

    implementation ("com.squareup.okhttp3:okhttp:4.9.2")
    implementation ("com.google.android.material:material:1.9.0")
    implementation ("com.squareup.retrofit2:retrofit:2.6.4")
    implementation ("com.squareup.retrofit2:converter-gson:2.6.4")
    implementation ("androidx.viewpager2:viewpager2:1.0.0")
    implementation ("com.tbuonomo:dotsindicator:5.0")
    implementation ("com.facebook.shimmer:shimmer:0.5.0")
    implementation(platform("com.google.firebase:firebase-bom:33.12.0"))
    implementation("com.google.firebase:firebase-analytics")
    implementation("com.google.android.gms:play-services-auth:21.2.0")
    implementation("com.google.firebase:firebase-auth")
    implementation("com.google.firebase:firebase-firestore")
โš ๏ธ **GitHub.com Fallback** โš ๏ธ