Restful API(๋ฉ๋ชจ API)๋ฅผ ๋ง๋ค๊ณ , MySQL๊ณผ ์ฐ๋ํ์ฌ Postman์ผ๋ก ๊ฐ๋ฐํ ํ, ์งํํ์๋ค.
์กํฐ๋นํฐ ์ธ ๊ฐ ๋ง๋ค๊ธฐ
ํ๊ฒฝ๋ณ์ ์ค์ ํ๊ธฐ
Retrofit ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์นํ๊ธฐ
build.gradle.kts(:app)์์
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
ํ๊ณ , Sync ๋๋ฌ์ค๋ค.
activity_login.xml ๋ง๋ค๊ธฐ
๊ธ์์ ๋ฐ์ค ์๊ธฐ๊ฒ ํ๊ธฐ
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="30dp"
android:gravity="center"
android:text="๋ก๊ทธ์ธ"
android:textSize="32sp" />
<EditText
android:id="@+id/editEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:ems="10"
android:hint="์ด๋ฉ์ผ ์
๋ ฅ..."
android:inputType="textEmailAddress"
android:textSize="20sp" />
<EditText
android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:ems="10"
android:hint="๋น๋ฐ๋ฒํธ ์
๋ ฅ..."
android:inputType="textPassword"
android:textSize="20sp" />
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="๋ก๊ทธ์ธ"
android:textSize="20sp" />
<TextView
android:id="@+id/txtRegister"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/txt_register"
android:textColor="#3F51B5"
android:textSize="20sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
LoginActivity.java
ํ๋ฉด์ฐ๊ฒฐ ์๋ฐ์ฝ๋ ์์ฑํ๊ธฐ
package com.~.memo;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class LoginActivity extends AppCompatActivity {
EditText editEmail;
EditText editPassword;
TextView txtRegister;
Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
editEmail = findViewById(R.id.editEmail);
editPassword = findViewById(R.id.editPassword);
txtRegister = findViewById(R.id.txtRegister);
btnLogin = findViewById(R.id.btnLogin);
txtRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//ํ์๊ฐ์
์กํฐ๋นํฐ ์คํ
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
finish();
}
});
}
}
activity_Register.xml ๋ง๋ค๊ธฐ
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="30dp"
android:gravity="center"
android:text="ํ์๊ฐ์
"
android:textSize="32sp" />
<EditText
android:id="@+id/editEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:ems="10"
android:hint="์ด๋ฉ์ผ ์
๋ ฅ..."
android:inputType="textEmailAddress"
android:textSize="20sp" />
<EditText
android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:ems="10"
android:hint="๋น๋ฐ๋ฒํธ ์
๋ ฅ..."
android:inputType="textPassword"
android:textSize="20sp" />
<EditText
android:id="@+id/editNickname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:ems="10"
android:hint="๋๋ค์ ์
๋ ฅ..."
android:inputType="text"
android:textSize="20sp" />
<Button
android:id="@+id/btnRegister"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="ํ์๊ฐ์
"
android:textSize="20sp" />
<TextView
android:id="@+id/txtLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/txt_login"
android:textColor="#3F51B5"
android:textSize="20sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
RegisterActivity.java
ํ๋ฉด์ฐ๊ฒฐ ์๋ฐ์ฝ๋ ์์ฑํ๊ธฐ
package com.~.memo;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class RegisterActivity extends AppCompatActivity {
EditText editEmail;
EditText editPassword;
EditText editNickname;
Button btnRegister;
TextView txtLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
editEmail = findViewById(R.id.editEmail);
editPassword = findViewById(R.id.editPassword);
editNickname = findViewById(R.id.editNickname);
btnRegister = findViewById(R.id.btnRegister);
txtLogin = findViewById(R.id.txtLogin);
txtLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ๋ก๊ทธ์ธ ์กํฐ๋นํฐ ์คํ
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
});
}
}
api, config ๋ง๋ค๊ธฐ
NetworkClient.java
package com.~.memo.api;
import android.content.Context;
import com.~.memo.config.Config;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class NetworkClient {
public static Retrofit retrofit;
public static Retrofit getRetrofitClient(Context context){
if(retrofit == null){
// ํต์ ๋ก๊ทธ ํ์ธํ ๋ ํ์ํ ์ฝ๋
HttpLoggingInterceptor loggingInterceptor =
new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// ๋คํธ์ํฌ ์ฐ๊ฒฐ๊ด๋ จ ์ฝ๋
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.addInterceptor(loggingInterceptor)
.build();
// ๋คํธ์ํฌ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ ๋ฐ๋
// ๋ ํธ๋กํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ด๋ จ ์ฝ๋
retrofit = new Retrofit.Builder()
.baseUrl(Config.DOMAIN)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
UserApi.java
package com.~.memo.api;
import com.~.memo.model.User;
import com.~.memo.model.UserRes;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface UserApi { //์ธํฐํ์ด์ค๋ก ๋ฐ๊ฟ์ค๋ค.
// HTTP Method ์จ์ฃผ๊ณ , ๊ทธ ์์๋ ๊ฒฝ๋ก๋ฅผ ์จ์ค๋ค.
// ํจ์์ ๋ฆฌํด ๋ฐ์ดํฐ ํ์
์, Call ์์ ์๋ต์ผ๋ก ๋ฐ์ ํด๋์ค๋ฅผ ๋ฃ์ด์ค๋ค.
// ํจ์๋ช
์ ์์ฑํด์ฃผ๊ณ , ๋ณด๋ผ ๋ฐ์ดํฐ๋ ํ๋ผ๋ฏธํฐ์ ์์ฑ, ๋ฐ์ ๋ฐ์ดํฐ๋ ๋ฆฌํด์ ์์ฑ.
// ํ์๊ฐ์
API
@POST("/dev/user/register")
Call<UserRes> register(@Body User user);
// ๋ก๊ทธ์ธ API
@POST("/dev/user/login")
Call<UserRes> login(@Body User user);
}
Config.java
package com.yujinoh.memo.config;
public class Config {
public static final String YOUTUBE_KEY = "์์ ์ key ์
๋ ฅ";
public static final String DOMAIN = "์์ ์ ์๋ง์กด api ์ฃผ์ ์
๋ ฅ";
//public static final String DOMAIN = "https://vrskmc6b8c.execute-api.ap-northeast-2.amazonaws.com";
}
model ํจํค์ง ๋ง๋ค๊ณ , User ์ UserRes ํด๋์ค ๋ง๋ค๊ธฐ
User ํด๋์ค ๋ง๋ค๊ธฐ
package com.~.memo.model;
public class User {
public String email;
public String password;
public String nickname;
public User(){
}
public User(String email, String password){
this.email = email;
this.password = password;
}
public User(String email, String password, String nickname) {
this.email = email;
this.password = password;
this.nickname = nickname;
}
}
UserRes ํด๋์ค
package com.~.memo.model;
public class UserRes {
public String result;
public String accessToken;
}
RegisterActivity.java
ํ์๊ฐ์ ๋ฒํผ ๋๋ฅด๋ฉด, ํ์๊ฐ์ ๋๋๋ก postman๊ณผ ์ฐ๊ฒฐํ๊ธฐ
package com.~.memo;
import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.snackbar.Snackbar;
import com.~.memo.api.NetworkClient;
import com.~.memo.api.UserApi;
import com.~.memo.config.Config;
import com.~.memo.model.User;
import com.~.memo.model.UserRes;
import java.util.regex.Pattern;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class RegisterActivity extends AppCompatActivity {
EditText editEmail;
EditText editPassword;
EditText editNickname;
Button btnRegister;
TextView txtLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
editEmail = findViewById(R.id.editEmail);
editPassword = findViewById(R.id.editPassword);
editNickname = findViewById(R.id.editNickname);
btnRegister = findViewById(R.id.btnRegister);
txtLogin = findViewById(R.id.txtLogin);
txtLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ๋ก๊ทธ์ธ ์กํฐ๋นํฐ ์คํ
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
});
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1. ์ ์ ๊ฐ ์
๋ ฅํ ๋ฐ์ดํฐ๋ค์ ๊ฐ์ ธ์จ๋ค.
String email = editEmail.getText().toString().trim();
String password = editPassword.getText().toString().trim();
String nickname = editNickname.getText().toString().trim();
if(email.isEmpty() || password.isEmpty() || nickname.isEmpty()){
Snackbar.make(btnRegister, "ํ์ํญ๋ชฉ์
๋๋ค. ๋ชจ๋์
๋ ฅํ์ธ์.", Snackbar.LENGTH_SHORT).show();
return;
}
// 2. ์ด๋ฉ์ผ ํ์์ด ์ฌ๋ฐ๋ฅธ์ง ์ฒดํฌ
// ์๋ฐ์ ์ด๋ฉ์ผ ํ์ ์ฒดํฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ Pattern
Pattern pattern = Patterns.EMAIL_ADDRESS;
if(pattern.matcher(email).matches() == false){
Snackbar.make(btnRegister,"์ด๋ฉ์ผ ํ์์ ๋ฐ๋ฅด๊ฒ ์์ฑํ์ธ์.",Snackbar.LENGTH_SHORT).show();
return;
}
// ํ์๊ฐ์
API๋ฅผ ํธ์ถํ๋ค.
// 0. ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๋ณด์ฌ์ค๋ค.
showProgress();
// 1. ๋ ํธ๋กํ ๋ณ์ ์์ฑ : api ํจํค์ง์ NetworkClient.java ํ์ผ์ด ์์ด์ผ ํ๋ค.
Retrofit retrofit = NetworkClient.getRetrofitClient(RegisterActivity.this);
// 2. api ํจํค์ง์ ์๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ฒด๋ก ์์ฑ : api ํจํค์ง์ ์ธํฐํ์ด์ค๊ฐ ์์ด์ผ ํ๋ค.
UserApi api = retrofit.create(UserApi.class);
// 3. ๋ณด๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ ๋ค.
User user = new User(email, password, nickname);
// 4. api ํจ์๋ฅผ ๋ง๋ ๋ค.
Call<UserRes> call = api.register(user);
// 5. api๋ฅผ ํธ์ถํ๋ค.
call.enqueue(new Callback<UserRes>() {
@Override
public void onResponse(Call<UserRes> call, Response<UserRes> response) {
Log.i("MEMO REGISTER", ""+response.code());
//๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๋จผ์ ์์ค๋ค.
dismissProgress();
// 200 OK ์ผ๋,
if(response.isSuccessful()){
UserRes userRes = response.body();
Log.i("MEMO REGISTER",userRes.accessToken);
// ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ํ ํฐ์ ์ ์ฅํด์ผ ํ๋ค.
SharedPreferences sp = getSharedPreferences(Config.SP_NAME,MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("token", userRes.accessToken);
editor.commit(); //์ฑ์ ์ญ์ ํ๊ธฐ ์ ๊น์ง๋ ์๊ตฌ์ ์ฅํด์ค๋ค
// ํ์๊ฐ์
์กํฐ๋นํฐ๋ ์ข
๋ฃ๋ฅผ ํ๊ณ ๋ฉ์ธ์กํฐ๋นํฐ๋์ด๋ค.
Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(intent);
finish();
return;
}else if(response.code() == 500){
Snackbar.make(btnRegister, "์ด๋ฏธ ํ์๊ฐ์
ํ ์ด๋ฉ์ผ์
๋๋ค. ๋ก๊ทธ์ธํ์ธ์.",
Snackbar.LENGTH_SHORT).show();
return;
}else {
Snackbar.make(btnRegister, "์๋ฒ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ ์ ํ ๋ค์ ์๋ํ์ธ์.",
Snackbar.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<UserRes> call, Throwable throwable) {
//๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๋จผ์ ์์ค๋ค.
dismissProgress();
}
});
}
});
}
// *** ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋, ์์ ํ๊ฑฐ๋, ์ญ์ ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค!
Dialog dialog;
void showProgress(){
dialog = new Dialog(this);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setContentView(new ProgressBar(this));
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
void dismissProgress(){
dialog.dismiss();
}
}
LoginActivity.java
๋ก๊ทธ์ธ ๋ฒํผ ๋๋ฅด๋ฉด, ๋ก๊ทธ์ธ ๋๋๋ก postman๊ณผ ์ฐ๊ฒฐํ๊ธฐ
package com.yujinoh.memo;
import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.material.snackbar.Snackbar;
import com.yujinoh.memo.api.NetworkClient;
import com.yujinoh.memo.api.UserApi;
import com.yujinoh.memo.config.Config;
import com.yujinoh.memo.model.User;
import com.yujinoh.memo.model.UserRes;
import java.util.regex.Pattern;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class LoginActivity extends AppCompatActivity {
EditText editEmail;
EditText editPassword;
TextView txtRegister;
Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
editEmail = findViewById(R.id.editEmail);
editPassword = findViewById(R.id.editPassword);
txtRegister = findViewById(R.id.txtRegister);
btnLogin = findViewById(R.id.btnLogin);
txtRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//ํ์๊ฐ์
์กํฐ๋นํฐ ์คํ
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
finish();
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email = editEmail.getText().toString().trim();
String password = editPassword.getText().toString().trim();
if(email.isEmpty() || password.isEmpty()){
Snackbar.make(btnLogin, "ํ์ํญ๋ชฉ์
๋๋ค. ๋ชจ๋ ์
๋ ฅํ์ธ์.",Snackbar.LENGTH_SHORT).show();
return;
}
// ์ด๋ฉ์ผ ํ์ ์ฒดํฌ (ํ์๊ฐ์
์ ์ฝ๋ C&P)
// ์๋ฐ์ ์ด๋ฉ์ผ ํ์ ์ฒดํฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ Pattern
Pattern pattern = Patterns.EMAIL_ADDRESS;
if(pattern.matcher(email).matches() == false){
Snackbar.make(btnLogin,"์ด๋ฉ์ผ ํ์์ ๋ฐ๋ฅด๊ฒ ์์ฑํ์ธ์.",Snackbar.LENGTH_SHORT).show();
return;
}
// ๋ก๊ทธ์ธ API ํธ์ถ!
// 0. ๋ค์ด์ผ๋ก๊ทธ ํ์ํ๋ค.
showProgress();
// 1. ๋ ํธ๋กํ ๋ณ์ ๋ง๋ ๋ค.
Retrofit retrofit = NetworkClient.getRetrofitClient(LoginActivity.this);
// 2. API ๊ฐ์ฒด ์์ฑํ๋ค
UserApi api = retrofit.create(UserApi.class);
// 3. ๋ณด๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ ๋ค.
User user = new User(email, password);
// 4. api ํจ์๋ฅผ ๋ง๋ ๋ค.
Call<UserRes> call = api.login(user);
// 5. ๋คํธ์ํฌ๋ก ํธ์ถํ๋ค
call.enqueue(new Callback<UserRes>() {
@Override
public void onResponse(Call<UserRes> call, Response<UserRes> response) {
dismissProgress();
if(response.isSuccessful()){
UserRes userRes = response.body();
// ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ํ ํฐ์ ์ ์ฅํด์ผ ํ๋ค.
SharedPreferences sp = getSharedPreferences(Config.SP_NAME,MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("token", userRes.accessToken);
editor.commit(); //์ฑ์ ์ญ์ ํ๊ธฐ ์ ๊น์ง๋ ์๊ตฌ์ ์ฅํด์ค๋ค
// ํ์๊ฐ์
์กํฐ๋นํฐ๋ ์ข
๋ฃ๋ฅผ ํ๊ณ ๋ฉ์ธ์กํฐ๋นํฐ๋์ด๋ค.
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
return;
}else{
Snackbar.make(btnLogin, "์๋ฒ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ ์ ํ ๋ค์ ์๋ํ์ธ์.",
Snackbar.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<UserRes> call, Throwable throwable) {
dismissProgress();
// ์ ์ ์๊ฒ ์๋ฆฌ๊ณ ๋ก๊ทธ๋จ๊ธฐ๊ณ ๋ฆฌํด
}
});
}
});
}
// *** ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋, ์์ ํ๊ฑฐ๋, ์ญ์ ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค!
Dialog dialog;
void showProgress(){
dialog = new Dialog(this);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setContentView(new ProgressBar(this));
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
void dismissProgress(){
dialog.dismiss();
}
}
๋ก๊ทธ์์ ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
menu ํจํค์ง๋ฅผ ๋ง๋ค์ด์ฃผ๊ณ , xml ํ์ผ์ ๋ง๋ค์ด์ ์ก์ ๋ฐ์ ์์ด์ฝ์ ๋ฃ์ผ๋ ค๊ณ ํ๋ค.
https://codebunny99.tistory.com/139
์ก์ ๋ฐ(Actionbar) ์ด๋ฆ, ์, ๋ฐฑ๋ฒํผ, ์์ด์ฝ ๋์์ธ๊ณผ ์ญ์ ๋ฐฉ๋ฒ
์ก์ ๋ฐ ์ ๋ฐ๊พธ๊ธฐ name๋ ์์ ์ด ์ง์ ํ์ฌ ๋ฐ๊ฟ ์ ์๋ค. ์ก์ ๋ฐ ์ด๋ฆ ๋ฐ๊พธ๊ธฐ MainActivity.java ์์getSupportActionBar().setTitle("ํฌ์คํ ๋ฆฌ์คํธ"); + // ์ก์ ๋ฐ์ ํ์ดํ ๋ฐฑ๋ฒํผ์ ํ์ํ๋
codebunny99.tistory.com
์ก์ ๋ฐ ์์ด์ฝ ์ถ๊ฐ๋ฅผ ์ฐธ๊ณ ํ๋ค.
UserApi ์ ๋ก๊ทธ์์ API๋ฅผ ์ ๋ ฅํด์ค๋ค.
MainActivity์ ์์ฑํด์ฃผ๊ธฐ
package com.~.memo;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.~.memo.adapter.MemoAdapter;
import com.~.memo.api.MemoApi;
import com.~.memo.api.NetworkClient;
import com.~.memo.api.UserApi;
import com.~.memo.config.Config;
import com.~.memo.model.Memo;
import com.~.memo.model.MemoList;
import com.~.memo.model.UserRes;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class MainActivity extends AppCompatActivity {
ProgressBar progressBar;
Button btnAdd;
RecyclerView recyclerView;
ArrayList<Memo> memoArrayList = new ArrayList<>();
MemoAdapter adapter;
String token;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ๋ก๊ทธ์ธ์ ํ ์ ์ ์ธ์ง ์๋์ง๋ฅผ ์ฒดํฌํ๋ค.
// ๋ก๊ทธ์ธ์ ์ํ์ผ๋ฉด, ๋ก๊ทธ์ธ ์กํฐ๋นํฐ๋ฅผ ๋์ฐ๊ณ ,
// ๋ก๊ทธ์ธ์ ํ์ผ๋ฉด, ์ธ์ฆํ ํฐ์ ๊ฐ์ ธ์จ๋ค.
SharedPreferences sp = getSharedPreferences(Config.SP_NAME, MODE_PRIVATE);
token = sp.getString("token", "");
if(token.isEmpty()){
// ๋ก๊ทธ์ธ ์กํฐ๋นํฐ๋ฅผ ๋์ด๋ค.
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
return;
}
progressBar = findViewById(R.id.progressBar);
btnAdd = findViewById(R.id.btnAdd);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
}
});
// ๋ด ๋ฉ๋ชจ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์จ๋ค.
getNetworkData();
}
private void getNetworkData() {
Retrofit retrofit = NetworkClient.getRetrofitClient(MainActivity.this);
MemoApi api = retrofit.create(MemoApi.class);
Call<MemoList> call = api.getMemoList("Bearer "+token);
call.enqueue(new Callback<MemoList>() {
@Override
public void onResponse(Call<MemoList> call, Response<MemoList> response) {
progressBar.setVisibility(View.GONE);
if(response.isSuccessful()){
MemoList memoList = response.body();
// ๋น์ด์๋ ์ด๋ ์ด๋ฆฌ์คํธ์, ๋ฐ์์จ ๋ฆฌ์คํธ๋ฅผ ๋ด์์ค๋ค!
memoArrayList.addAll( memoList.getItems() );
// ๋ฐ์ดํฐ๊ฐ ์ค๋น ์๋ฃ ๋์์ผ๋,
// ์ด๋ํฐ ๋ง๋ค์ด์, ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ์ ์ ์ฉํ๋ค.
adapter = new MemoAdapter(MainActivity.this, memoArrayList);
recyclerView.setAdapter(adapter);
}else {
}
}
@Override
public void onFailure(Call<MemoList> call, Throwable throwable) {
progressBar.setVisibility(View.GONE);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if( item.getItemId() == R.id.menuLogout ){
showAlertDialog();
}
return super.onOptionsItemSelected(item);
}
void showAlertDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setTitle("๋ก๊ทธ์์");
builder.setMessage("์ ๋ง ๋ก๊ทธ์์ ํ์๊ฒ ์ต๋๊น??");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// ๋ก๊ทธ์์ API ํธ์ถ!
Retrofit retrofit = NetworkClient.getRetrofitClient(MainActivity.this);
UserApi api = retrofit.create(UserApi.class);
Call<UserRes> call = api.logout("Bearer " + token);
call.enqueue(new Callback<UserRes>() {
@Override
public void onResponse(Call<UserRes> call, Response<UserRes> response) {
if(response.isSuccessful()){
SharedPreferences sp = getSharedPreferences(Config.SP_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("token", "");
editor.commit();
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
return;
}else{
}
}
@Override
public void onFailure(Call<UserRes> call, Throwable throwable) {
}
});
}
});
builder.setNegativeButton("No", null);
builder.show();
}
}