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์ ์ฌ์ฉ์ ํธ์์ฑ๊ณผ ์ ๋ณด ์ ๊ทผ์ฑ์ ๊ณ ๋ คํด ํต์ฌ ํ๋ฉด ์ค์ฌ์ผ๋ก ์ค๊ณ๋์์ต๋๋ค.
๊ฐ ํ๋ฉด์ ๋
๋ฆฝ์ ์ธ ์ญํ ์ ๊ฐ์ง๋ฉฐ, ์๋์ ๊ฐ์ด ๊ตฌ์ฑ๋ฉ๋๋ค:
๐ ์์ธ ํ๋ฉด: '๊ธฐ๋ฅ ์์ฝ'
๊ธฐ๋ฅ |
์ค๋ช
|
์ค๋์ค ํ๋ ์ด์ด UI |
๋ฆฌํฌํธ ์ ๋ชฉ / ์ฆ๊ถ์ฌ / ์ฌ์ ์๊ฐ ํ์ |
TTS ์ฌ์ |
๋ฆฌํฌํธ ๋ด์ฉ์ Google TTS๋ก ๋ณํํด mp3 ์ฌ์ |
์ด์ด๋ฃ๊ธฐ |
๋ค๋ฅธ Fragment ๋๋ Activity ์ด๋ ํ์๋ ์ฌ์ ์ง์ |
์ข์์ ๊ธฐ๋ฐ ํํฐ |
"๋ด ๋ชฉ๋ก" ๋ฒํผ ํด๋ฆญ ์ ์ข์์ํ ๋ฆฌํฌํธ๋ง ํ์ |
Top10/์ต์ ๋ชฉ๋ก ์ ํ |
๋ฒํผ ํด๋ฆญ์ผ๋ก ์๋ฒ ๋๋ ๋๋ฏธ ๋ฐ์ดํฐ ์ ํ |
Shimmer ๋ก๋ฉ |
์๋ฒ ํต์ ์ค ๋ก๋ฉ ์ ๋๋ฉ์ด์
์ ์ฉ |
๐ ์์ธ ๋ก์ง: HomeFragment
๊ธฐ๋ฅ |
์ค๋ช
|
๋ฆฌํฌํธ ๊ฒ์ |
๊ฒ์์ด ์
๋ ฅ ์ ์๋ฒ API ์์ฒญ์ผ๋ก ๊ฒฐ๊ณผ ์กฐํ |
์นดํ
๊ณ ๋ฆฌ ํํฐ |
์ ์ฒด / ์ข
๋ชฉ / ์ฐ์
ํญ์ผ๋ก ๋ถ๋ฅ ์กฐํ |
์ข์์ / TTS |
๊ฐ๋ณ ๋ฆฌํฌํธ ์นด๋์์ ์ข์์ ๋ฑ๋ก ๋ฐ TTS ์ฌ์ ๊ฐ๋ฅ |
Pull to Refresh |
์ค์์ดํ ์ ์ต์ ๋ฐ์ดํฐ ์๋ก ๋ถ๋ฌ์ค๊ธฐ |
Shimmer ๋ก๋ฉ |
์ด๊ธฐ ๋๋ ๊ฐฑ์ ์ค ๋ก๋ฉ ์ ๋๋ฉ์ด์
ํ์ |
๊ธฐ๋ฅ |
์ค๋ช
|
์ถ์ฒ ๋ฆฌํฌํธ ์ฌ๋ผ์ด๋ |
ViewPager2๋ก ์๋ ์ฌ๋ผ์ด๋ฉ ๋ฐฉ์ ๊ตฌํ |
์ธ๊ธฐ ๋ฆฌํฌํธ ์นด๋ |
ํ๋จ์ ๋ญํน ๊ธฐ๋ฐ ์นด๋ ๋์ด |
Dot Indicator ์ ํ |
์ถ์ฒ ์ฌ๋ผ์ด๋ ์ธ๋์ผ์ดํฐ ์ต๋ 5๊ฐ๋ก ์ ํ |
์๋ฒ ์ฐ๊ฒฐ ์คํจ ์ fallback |
๋๋ฏธ ๋ฐ์ดํฐ ์๋ ๋ก๋ ์ฒ๋ฆฌ |
๊ธฐ๋ฅ |
์ค๋ช
|
๋ฆฌํฌํธ ์ ๋ฌธ ๋ณด๊ธฐ |
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์์ ํ์ฌ ๋ก๊ทธ์ธ ์ํ ์ฒดํฌ ํ ๋ฐ๋ก ์ง์
๊ฐ๋ฅ |
๊ธฐ๋ฅ |
์ค๋ช
|
์ด๊ธฐ ๋ก๋ฉ ํ๋ฉด |
์ฑ ์คํ ์ 1์ด๊ฐ ๋ก๊ณ ๋
ธ์ถ |
์๋ ๋ก๊ทธ์ธ ์ฌ๋ถ ํ์ธ |
๋ก๊ทธ์ธ ์ ๋ณด ์กด์ฌ ์ ๋ฐ๋ก main์ผ๋ก ์ด๋ |
SharedPreferences ์ด๊ธฐํ |
PreferenceUtil์์ ๋ก๊ทธ์ธ ์ํ ๋ก๋ |
๐ธ๏ธ Report Crawling ์์ฝ
๊ตฌ๋ถ |
์ข
๋ชฉ๋ถ์ ๋ฆฌํฌํธ ํฌ๋กค๋ง |
์ฐ์
๋ถ์ ๋ฆฌํฌํธ ํฌ๋กค๋ง |
ํฌ๋กค๋ง ๋์ |
์ข
๋ชฉ๋ณ ๋ฆฌํฌํธ |
์
์ข
๋ณ ๋ฆฌํฌํธ |
์ฃผ์ ์๋ณ ํญ๋ชฉ |
์ข
๋ชฉ๋ช
(์ข
๋ชฉ๋ช
), ์ข
๋ชฉ ์ฝ๋ (์ฝ๋ ) |
์
์ข
๋ช
(์
์ข
) |
์ฆ๊ถ์ฌ ํํฐ๋ง |
SECURITIES_CONFIGS ๊ธฐ์ค์ผ๋ก ํํฐ๋ง |
๋์ผํ๊ฒ SECURITIES_CONFIGS ๊ธฐ์ค |
์์ธ ๋ณธ๋ฌธ ์ถ์ถ |
HTML ์์ธ ํ์ด์ง ํฌ๋กค๋ง (fetch_report_details ) |
๋์ผ |
๊ฒฐ๊ณผ ์ ์ฅ ํญ๋ชฉ |
์ข
๋ชฉ๋ช
, ์ฝ๋, ์
์ข
, ์ ๋ชฉ, ์ฆ๊ถ์ฌ, ์์ฑ์ผ, ์กฐํ์, ๋ณธ๋ฌธ, PDF ์ฝํ
์ธ |
์
์ข
, ์ ๋ชฉ, ์ฆ๊ถ์ฌ, ์์ฑ์ผ, ์กฐํ์, ๋ณธ๋ฌธ, PDF ์ฝํ
์ธ |
์ข
๋ชฉ๋ช
/์
์ข
๊ตฌ๋ถ |
์ข
๋ชฉ๋ช
๊ธฐ๋ฐ์ผ๋ก ์
์ข
์ ๋งคํ |
์
์ข
๋ช
์ด ์ง์ ํ๊ธฐ๋จ |
๋ฐํ ํ์ |
List[Dict[str, str]] ํํ์ ๋ฆฌํฌํธ ์ ๋ณด ๋ฆฌ์คํธ |
List[Dict[str, str]] ํํ์ ๋ฆฌํฌํธ ์ ๋ณด ๋ฆฌ์คํธ |
๋ค์ ํ์ด์ง๋ก ๋์ด๊ฐ๋ ค๋ฉด ๐ [ํ๋ฉด๋ณ ๊ธฐ๋ฅ ์์ธ ์ค๋ช
๋ฐ ๋ก์ง ๋ถ์](ํ๋ฉด ๋ณ ๊ธฐ๋ฅ ์์ธ ์ค๋ช
)
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")