일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 막내의막무가내 코볼 COBOL
- 주엽역 생활맥주
- 막내의막무가내 프로그래밍
- 막내의막무가내
- 막내의막무가내 코틀린
- flutter network call
- 프로그래머스 알고리즘
- 막무가내
- 안드로이드
- 막내의막무가내 일상
- Fragment
- 안드로이드 sunflower
- 부스트코스에이스
- 막내의막무가내 rxjava
- 2022년 6월 일상
- 막내의막무가내 SQL
- 막내의막무가내 알고리즘
- 막내의 막무가내 알고리즘
- 막내의막무가내 플러터 flutter
- 막내의막무가내 안드로이드 에러 해결
- 막내의 막무가내
- 막내의막무가내 안드로이드 코틀린
- 부스트코스
- 안드로이드 Sunflower 스터디
- 주택가 잠실새내
- 막내의막무가내 안드로이드
- 막내의막무가내 목표 및 회고
- 막내의막무가내 플러터
- 프래그먼트
- 막내의막무가내 코틀린 안드로이드
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] 카카오톡 로그인 본문
구글로그인과 페이스북로그인에 이어서 카카오톡 로그인을 해본 걸 정리하는 포스팅을 갖도록 해보겠습니다.
[2020-06-21 업데이트]
참고로 저는 구글 파이어베이스의 OAuth 토큰을 사용하기 위해서 카카오톡 로그인과 구글 로그인을 통합해야했습니다.
그래서 카카오톡 로그인 성공시 해당 정보를 갖고 구글로그인 가입이 되게 하여 토큰을 받을 수 있게 했었습니다.
즉 카카오톡 로그인 -> 구글 로그인 -> 가입 완료가 되는 절차입니다.
카카오 디빌로퍼 UI가 좀 바꼇네요. 활성화 하시고 키는 여깄습니다.
https://developers.kakao.com/docs/latest/ko/kakaologin/android
그리고 플랫폼도 등록해주세요
키 해시는 다음 코드를 안드로이드 스튜디오에서 실행해서 세팅해주시면 되요.
private fun getHashKey() {
var packageInfo: PackageInfo? = null
try {
packageInfo =
packageManager.getPackageInfo(
packageName,
PackageManager.GET_SIGNATURES
)
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
if (packageInfo == null) Log.e("KeyHash", "KeyHash:null")
for (signature in packageInfo!!.signatures) {
try {
val md: MessageDigest = MessageDigest.getInstance("SHA")
md.update(signature.toByteArray())
Log.d("KeyHash", Base64.encodeToString(md.digest(), Base64.DEFAULT))
} catch (e: NoSuchAlgorithmException) {
Log.e("KeyHash", "Unable to get MessageDigest. signature=$signature", e)
}
}
}
0. 기본사항
string.xml에 카카오 디벨로퍼에서 제공하는 키값 추가 (네이티브 앱 키 추가하면 됩니다.) (카카오 디벨로퍼 사이트 가입은 다른 블로그에도 많이 적혀있으므로 참고바랍니다.)
<resources>
<string name="app_name">Dal.kommPhoto</string>
<string name="kakao_app_key">키값</string>
</resources>
gradle.properties에 추가
KAKAO_SDK_GROUP=com.kakao.sdk
KAKAO_SDK_VERSION=1.1.7
모듈수준 gradle에 추가 (카카오로그인sdk)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:animated-vector-drawable:28.0.0'
implementation 'com.android.support:customtabs:28.0.0'
implementation 'com.android.support:support-media-compat:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.google.firebase:firebase-storage:17.0.0'
implementation 'com.google.firebase:firebase-auth:17.0.0'
implementation 'com.google.firebase:firebase-database:17.0.0'
implementation 'com.google.firebase:firebase-firestore:17.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//페이스북로그인
implementation 'com.facebook.android:facebook-android-sdk:[5,6)'
//파이어베이스 이메일 인증
implementation 'com.google.android.gms:play-services-auth:16.0.1'
//파이어베이스
implementation 'com.google.firebase:firebase-core:16.0.9'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
/*anko라이브러리*/
implementation "org.jetbrains.anko:anko:$anko_version"
/*카카오로그인*/
implementation group: project.KAKAO_SDK_GROUP, name: 'usermgmt', version: project.KAKAO_SDK_VERSION
}
주의 : 밑 단계까지 해줘야 여기서 에러가 안납니다.
앱수준 grdle에 카카오라 주석친거 추가
allprojects {
repositories {
google()
jcenter()
maven{
url "https://maven.google.com"
}
/*카카오*/
maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/'}
}
}
1. GlobalApplication 자바클래스 생성
import android.app.Activity;
import android.app.Application;
import com.kakao.auth.KakaoSDK;
/**
* 이미지를 캐시를 앱 수준에서 관리하기 위한 애플리케이션 객체이다.
* 로그인 기반 샘플앱에서 사용한다.
*
* @author MJ
*/
public class GlobalApplication extends Application {
private static volatile GlobalApplication instance = null;
private static volatile Activity currentActivity = null;
@Override
public void onCreate() {
super.onCreate();
instance = this;
KakaoSDK.init(new KakaoSDKAdapter());
}
public static Activity getCurrentActivity() {
return currentActivity;
}
public static void setCurrentActivity(Activity currentActivity) {
GlobalApplication.currentActivity = currentActivity;
}
/**
* singleton 애플리케이션 객체를 얻는다.
* @return singleton 애플리케이션 객체
*/
public static GlobalApplication getGlobalApplicationContext() {
if(instance == null)
throw new IllegalStateException("this application does not inherit com.kakao.GlobalApplication");
return instance;
}
/**
* 애플리케이션 종료시 singleton 어플리케이션 객체 초기화한다.
*/
@Override
public void onTerminate() {
super.onTerminate();
instance = null;
}
}
2. KakaoSDKAdapter 자바클래스 생성
import android.app.Activity;
import android.content.Context;
import com.kakao.auth.*;
public class KakaoSDKAdapter extends KakaoAdapter {
/**
* Session Config에 대해서는 default값들이 존재한다. * 필요한 상황에서만 override해서 사용하면 됨. * @return Session의 설정값.
*/
@Override
public ISessionConfig getSessionConfig() {
return new ISessionConfig() {
@Override
public AuthType[] getAuthTypes() {
return new AuthType[]{AuthType.KAKAO_ACCOUNT};
}
@Override
public boolean isUsingWebviewTimer() {
return false;
}
@Override
public ApprovalType getApprovalType() {
return ApprovalType.INDIVIDUAL;
}
@Override
public boolean isSaveFormData() {
return true;
}
};
}
@Override
public IApplicationConfig getApplicationConfig() {
return new IApplicationConfig() {
@Override
public Activity getTopActivity() {
return GlobalApplication.getCurrentActivity();
}
@Override
public Context getApplicationContext() {
return GlobalApplication.getGlobalApplicationContext();
}
};
}
}
3. 로그인 액티비티에서 사용
저는 파이어베이스 파이어스토어에 바로 토큰값과 이름 저장등의 코드도 섞여있는데 그부분들은 지워서 사용하면 됩니다. (Firebase관련코드는 지워도됩니다. 전 파이어베이스에 토큰값으로 집어넣기 위해 사용했습니다.)
추가로 HomeActivity는 로그인 성공시 이동할 액티비티입니다. (일반 앱에서 로그인 성공하면 다음화면으로 넘어가듯이)
그리고 SplashActivity는 MainActivity 이전의 화면입니다. 안드로이드 스플래쉬라고치면 뭐하는 건지 나올겁니다.
즉 SplashActivity( 스플래쉬화면) -> LoginActivity -> HomeActivity 순으로 화면이 전환됩니다.
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.kakao.auth.ErrorCode;
import com.kakao.auth.ISessionCallback;
import com.kakao.auth.Session;
import com.kakao.network.ErrorResult;
import com.kakao.usermgmt.UserManagement;
import com.kakao.usermgmt.callback.MeResponseCallback;
import com.kakao.usermgmt.response.model.UserProfile;
import com.kakao.util.exception.KakaoException;
import com.kakao.util.helper.log.Logger;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
/**
* Created by hp on 2016-01-26.
*/
public class LoginActivity extends Activity {
private SessionCallback callback; //콜백 선언
//유저프로필
String token = "";
String name = "";
FirebaseFirestore db = FirebaseFirestore.getInstance();
final static String TAG = "LoginActivityT";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//카카오 로그인 콜백받기
callback = new SessionCallback();
Session.getCurrentSession().addCallback(callback);
//키값 알아내기(알아냈으면 등록하고 지워도 상관없다)
getAppKeyHash();
//자기 카카오톡 프로필 정보 및 디비정보 쉐어드에 저장해놨던거 불러오기
loadShared();
}
//카카오 디벨로퍼에서 사용할 키값을 로그를 통해 알아낼 수 있다. (로그로 본 키 값을을 카카오 디벨로퍼에 등록해주면 된다.)
private void getAppKeyHash() {
try {
PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String something = new String(Base64.encode(md.digest(), 0));
Log.e("Hash key", something);
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("name not found", e.toString());
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Session.getCurrentSession().handleActivityResult(requestCode, resultCode, data)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
super.onDestroy();
Session.getCurrentSession().removeCallback(callback);
}
private class SessionCallback implements ISessionCallback {
@Override
public void onSessionOpened() {
requestMe();
//redirectSignupActivity(); // 세션 연결성공 시 redirectSignupActivity() 호출
}
@Override
public void onSessionOpenFailed(KakaoException exception) {
if (exception != null) {
Logger.e(exception);
}
setContentView(R.layout.activity_login); // 세션 연결이 실패했을때
} // 로그인화면을 다시 불러옴
}
protected void requestMe() { //유저의 정보를 받아오는 함수
UserManagement.requestMe(new MeResponseCallback() {
@Override
public void onFailure(ErrorResult errorResult) {
String message = "failed to get user info. msg=" + errorResult;
Logger.d(message);
ErrorCode result = ErrorCode.valueOf(errorResult.getErrorCode());
if (result == ErrorCode.CLIENT_ERROR_CODE) {
finish();
} else {
redirectLoginActivity();
}
}
@Override
public void onSessionClosed(ErrorResult errorResult) {
redirectLoginActivity();
}
@Override
public void onNotSignedUp() {
} // 카카오톡 회원이 아닐 시 showSignup(); 호출해야함
@Override
public void onSuccess(final UserProfile userProfile) { //성공 시 userProfile 형태로 반환
Logger.d("UserProfile : " + userProfile);
Log.d(TAG, "유저가입성공");
// Create a new user with a first and last name
// 유저 카카오톡 아이디 디비에 넣음(첫가입인 경우에만 디비에저장)
Map<String, String> user = new HashMap<>();
user.put("token", userProfile.getId() + "");
user.put("name", userProfile.getNickname());
db.collection("users")
.document(userProfile.getId() + "")
.set(user)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "유저정보 디비삽입 성공");
saveShared(userProfile.getId() + "", userProfile.getNickname());
}
});
redirectHomeActivity(); // 로그인 성공시 MainActivity로
}
});
}
private void redirectHomeActivity() {
startActivity(new Intent(this, HomeActivity.class));
finish();
}
protected void redirectLoginActivity() {
final Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
finish();
}
/*쉐어드에 입력값 저장*/
private void saveShared( String id, String name) {
SharedPreferences pref = getSharedPreferences("profile", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString("token", id);
editor.putString("name", name);
editor.apply();
}
/*쉐어드값 불러오기*/
private void loadShared() {
SharedPreferences pref = getSharedPreferences("profile", MODE_PRIVATE);
token = pref.getString("token", "");
name = pref.getString("name", "");
}
}
위 코드에서 getAppKeyHash()에서 로그를 통해 키값을 알아낼 수 있습니다. 이것을 카카오디벨로퍼에 밑과 같이 사용합니다. 플랫폼을 추가하면서 키해시 해당 키값을 추가해주면 됩니다. 마켓url은 참고로 기본값으로 해도 처음엔 상관없습니다.
4. 로그앤 액티비티 xml 에 다음 카카오로그인 버튼 추가
<com.kakao.usermgmt.LoginButton
android:id="@+id/login_btn_kakaologin"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"/>
5. manifest에 처음 만든 GlobalApplication을 <application name>으로 추가해줍니다.
그리고 인터넷접근 퍼미션을 추가해줍니다. 또한 <application>내에 <meta-data>를 다음과같이 추가해줍니다.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name=".GlobalApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SplashActivity"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="com.kakao.sdk.AppKey"
android:value="@string/kakao_app_key"/>
<activity android:name=".KakaoSignUpActivity"/>
<activity android:name=".LoginActivity">
</activity> <!-- 카카오톡 -->
<activity android:name=".HomeActivity">
</activity>
</application>
- 실행결과화면 로그인액티비티(LoginActivity) 입니다. -
+). KakaoSDKAdapter 자바클래스도 만들어줘야합니다.
GloabalApplication에서 사용함(바로밑코드참고)
[GloabalApplication]
KakaoSDK.init(new KakaoSDKAdapter());
[KakaoSDKAdapter ]
import android.app.Activity;
import android.content.Context;
import com.kakao.auth.*;
public class KakaoSDKAdapter extends KakaoAdapter {
/**
* Session Config에 대해서는 default값들이 존재한다. * 필요한 상황에서만 override해서 사용하면 됨. * @return Session의 설정값.
*/
@Override
public ISessionConfig getSessionConfig() {
return new ISessionConfig() {
@Override
public AuthType[] getAuthTypes() {
return new AuthType[]{AuthType.KAKAO_ACCOUNT};
}
@Override
public boolean isUsingWebviewTimer() {
return false;
}
@Override
public ApprovalType getApprovalType() {
return ApprovalType.INDIVIDUAL;
}
@Override
public boolean isSaveFormData() {
return true;
}
};
}
@Override
public IApplicationConfig getApplicationConfig() {
return new IApplicationConfig() {
@Override
public Activity getTopActivity() {
return GlobalApplication.getCurrentActivity();
}
@Override
public Context getApplicationContext() {
return GlobalApplication.getGlobalApplicationContext();
}
};
}
}
https://github.com/mtjin/DalkommPhotoEditApp
댓글과 공감은 큰 힘이됩니다. 감사합니다!
'안드로이드 > 자바 & Previous' 카테고리의 다른 글
[안드로이드] EditeText 글자 힌트 및 크기 변경 (0) | 2019.07.30 |
---|---|
[안드로이드] 인플레이션 이해하기 (0) | 2019.07.22 |
[안드로이드] 데이터바인딩 간단하게 적용해보는 공부 (0) | 2019.07.09 |
[안드로이드] 선택 다이얼로그 (0) | 2019.06.24 |
[안드로이드] 버튼 중복클릭 방지하기 (0) | 2019.06.24 |