진짜.. 많이 헤맸던 카카오 로그인
지금까지 소셜 로그인이 아니라 SMTP로 이메일 로그인만 구현해봤는데 카카오 로그인은 진짜 더 어려웠다.
계속 올리려고 마음만 먹다가 이제 올려보려고 노력중이다. 이러고 또 임시 저장 글에 처박히겠지...? (드디어 다시 쓰기 시작)
다음에는 SMTP 로그인하는 방법도 글을 올려야겠다.
카카오 로그인은 정말 다른 분들 블로그, 티스토리 등 여러 도움을 받았기 때문에 나도 기록겸해서 올려둔다.
애석하게도 카카오 공식 문서가 다 코틀린으로 되어 있어서 코틀린 모르는 나는 자바로 구현하려고 아둥바둥댔다.
Java로 안드로이드 개발하는 나는 레퍼런스 찾는데도 엄청 오래 걸렸다...
이 문서가 '카카오 로그인 v2 예제 java'를 찾아 구글을 뒤지는 당신에게 도움이 되기를 바랍니다. (제 경험담입니다)
** 앱 플랫폼 등록, 해시키 등록 등 기본적인 부분은 모두 마쳤다고 간주하고 글을 작성하겠습니다 **
** 설정 중 부족한 부분이 있을 수 있습니다 **
gradle (project)의 allprojects 부분에 추가합니다.
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
gradle (module)의 dependencies 부분에 추가합니다.
필요한 부분만 나눠서 넣으시면 됩니다. 로그인은 카카오 로그인 v2 부분만 넣으셔도 사용하실 수 있습니다.
implementation "com.kakao.sdk:v2-user:2.5.2" // 카카오 로그인
implementation "com.kakao.sdk:v2-talk:2.5.2" // 친구, 메시지(카카오톡)
implementation "com.kakao.sdk:v2-story:2.5.2" // 카카오스토리
implementation "com.kakao.sdk:v2-link:2.5.2" // 메시지(카카오링크)
implementation "com.kakao.sdk:v2-navi:2.5.2" // 카카오내비
gradle(module)의 android 부분에 넣어줍니다.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
GlobalApplication.java를 만듭니다.
import android.app.Application;
import com.kakao.sdk.common.KakaoSdk;
public class GlobalApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
KakaoSdk.init(this, "네이티브 앱 키 넣기");
}
}
Manifest의 application name에 ".GlobalApplication" 추가
Manifest application 부분에 추가
<meta-data
android:name="com.kakao.sdk.AppKey"
android:value="앱 키 Ex) kakao네이티브앱키" />
이 부분부터 LoginActivity 구현입니다.
<LoginActivity.java>
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.kakao.sdk.auth.model.OAuthToken;
import com.kakao.sdk.user.UserApiClient;
import com.kakao.sdk.user.model.User;
import kotlin.Unit;
import kotlin.jvm.functions.Function2;
public class LoginActivity extends AppCompatActivity {
private final static String TAG = "유저";
private Button kakaoAuth, googleAuth;
public static Context mContext;
private SharedPreferences sharedPreferences;
private User currentUser;
private String userImageString = "";
private Bitmap mBitmap;
SharedPreferences.Editor editor;
private Boolean isTrue = false;
private Boolean nextIntent = false;
private String meetingId;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Function2<OAuthToken, Throwable, Unit> callback = new Function2<OAuthToken, Throwable, Unit>() {
@Override
public Unit invoke(OAuthToken oAuthToken, Throwable throwable) {
if (oAuthToken != null) {
Log.i("user", oAuthToken.getAccessToken() + " " + oAuthToken.getRefreshToken());
}
if (throwable != null) {
// TBD
Log.w(TAG, "invoke: " + throwable.getLocalizedMessage());
}
updateKakaoLoginUi();
return null;
}
};
kakaoAuth = findViewById(R.id.kakao_auth_button); // 저는 카카오톡 로그인 버튼을 만들어서 했습니다.
kakaoAuth.setOnClickListener(new View.OnClickListener() { // 로그인 버튼 클릭 시
@Override
public void onClick(View v) {
if (UserApiClient.getInstance().isKakaoTalkLoginAvailable(LoginActivity.this)) {
// 카카오톡이 있을 경우?
UserApiClient.getInstance().loginWithKakaoTalk(LoginActivity.this, callback);
} else {
UserApiClient.getInstance().loginWithKakaoAccount(LoginActivity.this, callback);
}
}
});
updateKakaoLoginUi();
}
public void updateKakaoLoginUi() {
// 카카오 UI 가져오는 메소드 (로그인 핵심 기능)
UserApiClient.getInstance().me(new Function2<User, Throwable, Unit>() {
@Override
public Unit invoke(User user, Throwable throwable) {
if (user != null) {
// 유저 정보가 정상 전달 되었을 경우
Log.i(TAG, "id " + user.getId()); // 유저의 고유 아이디를 불러옵니다.
Log.i(TAG, "invoke: nickname=" + user.getKakaoAccount().getProfile().getNickname()); // 유저의 닉네임을 불러옵니다.
Log.i(TAG, "userimage " + user.getKakaoAccount().getProfile().getProfileImageUrl()); // 유저의 이미지 URL을 불러옵니다.
// 이 부분에는 로그인이 정상적으로 되었을 경우 어떤 일을 수행할 지 적으면 됩니다.
}
if (throwable != null) {
// 로그인 시 오류 났을 때
// 키해시가 등록 안 되어 있으면 오류 납니다.
Log.w(TAG, "invoke: " + throwable.getLocalizedMessage());
}
return null;
}
});
}
}
후기
처음 해본 소셜 로그인이었는데, 너무너무 어려웠다.
콜백에 대한 이해가 부족한 상태로 하려니 조금 죽을 맛이었다...
콜백함수, 코틀린 공부가 필요하다는 것을 뼈저리게 느꼈다.
이 부분부터는 온전히 기록용이라 사용하기에는 애매하실 수 있습니다.
** 번외 - 카카오톡 로그아웃 **
logoutButton.setOnClickListener(new View.OnClickListener() {
// 로그아웃 버튼
@Override
public void onClick(View v) {
UserApiClient.getInstance().logout(new Function1<Throwable, Unit>() {
@Override
public Unit invoke(Throwable throwable) {
((LoginActivity)LoginActivity.mContext).updateKakaoLoginUi(); // LoginActivity의 updateKakaoLoginUi를 가져오기 위해 context(this 저장)를 만들었습니다.
return null;
}
});
Intent backIntent = new Intent(getApplicationContext(), LoginActivity.class); // 로그인 화면으로 이동
startActivity(backIntent);
finish();
}
});
** 번외 - 해시키(키해시) 함수 **
private void getHashKey(){
PackageInfo packageInfo = null;
try {
packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (packageInfo == null)
Log.e("KeyHash", "KeyHash:null");
for (Signature signature : packageInfo.signatures) {
try {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash", Base64.encodeToString(md.digest(), Base64.DEFAULT));
} catch (NoSuchAlgorithmException e) {
Log.e("KeyHash", "Unable to get MessageDigest. signature=" + signature, e);
}
}
}
'Personal Study > 안드로이드' 카테고리의 다른 글
[Android] [Kotlin] Splash 화면 만들기 (0) | 2022.04.29 |
---|---|
[Android] 서버로 이미지 업로드하기 (Java) (2) | 2021.07.11 |
[Android] EditText 밑줄 없애기 (0) | 2021.05.14 |
[Android] 타이틀 바 없애기 / 상태 바 없애기 (0) | 2021.05.14 |
[Android Studio] 드로어블(Drawable) (0) | 2021.02.11 |