MY IT

안드로이드 App에서 Kakao 로그인 연동

메롱씨티 배드맨 2018. 6. 22. 11:21

너무 간간히 연동 하다보니 할때마다 항상 새롭다.

당연히 삽질도 새롭게 다시 시작하고...

또 잊어버리기 전에 기록 해두어야겠다.



1. 프로젝트 등록 (카카오 개발자 콘솔)


관련 내용 설명 : http://firstblog912.tistory.com/8



2. 라이브러리 설정 (gradle 파일)


- Project > App > build.gradle 파일에 추가한다.


android {

      .............................

     packagingOptions {

        exclude 'META-INF/services/javax.annotation.processing.Processor'

        exclude 'META-INF/NOTICE.txt'

        exclude 'META-INF/NOTICE'

        exclude 'META-INF/LICENSE.txt'

        exclude 'META-INF/LICENSE'

        exclude 'META-INF/DEPENDENCIES'

    }


    repositories {

        jcenter()

        maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' }

    }


    repositories {

        mavenCentral()

    }

}


dependencies {

      .............................

 compile 'com.squareup.picasso:picasso:2.3.2'


 compile group: 'com.kakao.sdk', name: 'usermgmt', version: '1.11.1'

}


compile 'com.squareup.picasso:picasso:2.3.2' <- 이 라이브러리는 프로필 이미지를 보여주기 위한 용도로 필수적이지 않다.



3. 카카오 로그인 연동


레이아웃 파일 이외에 세개의 파일을 생성한다.

MainActivity.java

GlobalApplication.java

KakaoSDKAdapter.java


MainActivity 는 로그인 화면과 프로세서 처리를 담당한다.

KakaoSDKAdapter와 GlobalApplication 은 마치 서비스 처럼 동작하여 Kakao Session류의 처리를 담당한다.


- Layout xml


<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.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:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.ubuno.kakaologinsample.MainActivity">


    <RelativeLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent">

        <Button

            android:id="@+id/login_button"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="카카오톡 로그인"

            android:layout_alignParentBottom="true"

            android:layout_alignParentLeft="true"

            android:layout_alignParentStart="true" />


        <TextView

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="로그인해주세요"

            android:id="@+id/tv_user_id"

            android:layout_centerVertical="true"

            android:layout_centerHorizontal="true" />


        <TextView

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="로그인해주세요"

            android:id="@+id/tv_user_name"

            android:layout_below="@+id/tv_user_id"

            android:layout_centerHorizontal="true" />


        <ImageView

            android:layout_width="100dp"

            android:layout_height="100dp"

            android:id="@+id/iv_user_profile"

            android:layout_above="@+id/tv_user_id"

            android:layout_centerHorizontal="true" />

    </RelativeLayout>


</android.support.constraint.ConstraintLayout>


- MainActivity.java

  실제 구동되는 메인 액티비티

public class MainActivity extends AppCompatActivity {

private SessionCallback mKakaocallback;
// view
private Button login_button;
private TextView tv_user_id;
private TextView tv_user_name;
private ImageView iv_user_profile;
private String userName;
private String userId;
private String profileUrl;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 헤쉬키를 가져온다
getAppKeyHash();

tv_user_id = (TextView) findViewById(R.id.tv_user_id);
tv_user_name = (TextView) findViewById(R.id.tv_user_name);
iv_user_profile = (ImageView) findViewById(R.id.iv_user_profile);

login_button = (Button) findViewById(R.id.login_button);
login_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 카카오 로그인 요청
isKakaoLogin();
}
});
}

private void isKakaoLogin() {
// 카카오 세션을 오픈한다
mKakaocallback = new SessionCallback();
com.kakao.auth.Session.getCurrentSession().addCallback(mKakaocallback);
com.kakao.auth.Session.getCurrentSession().checkAndImplicitOpen();
com.kakao.auth.Session.getCurrentSession().open(AuthType.KAKAO_TALK_EXCLUDE_NATIVE_LOGIN, MainActivity.this);
}

protected void KakaorequestMe() {

UserManagement.getInstance().requestMe(new MeResponseCallback() {
@Override
public void onFailure(ErrorResult errorResult) {
int ErrorCode = errorResult.getErrorCode();
int ClientErrorCode = -777;

if (ErrorCode == ClientErrorCode) {
Toast.makeText(getApplicationContext(), "카카오톡 서버의 네트워크가 불안정합니다. 잠시 후 다시 시도해주세요.", Toast.LENGTH_SHORT).show();
} else {
Log.d("TAG" , "오류로 카카오로그인 실패 ");
}
}

@Override
public void onSessionClosed(ErrorResult errorResult) {
Log.d("TAG" , "오류로 카카오로그인 실패 ");
}

@Override
public void onSuccess(UserProfile userProfile) {
profileUrl = userProfile.getProfileImagePath();
userId = String.valueOf(userProfile.getId());
userName = userProfile.getNickname();

Log.i(TAG, "prifileUrl:" + profileUrl);
Log.i(TAG, "userId:" + userId);
Log.i(TAG, "userName:" + userName);

setLayoutText();
}

@Override
public void onNotSignedUp() {
// 자동가입이 아닐경우 동의창
}
});
}

private void setLayoutText(){
tv_user_id.setText(userId);
tv_user_name.setText(userName);

Picasso.with(this)
.load(profileUrl)
.fit()
.into(iv_user_profile);
}

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.d(TAG, "getAppKeyHash > Hash key:" + something);
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(TAG, "getAppKeyHash > name not found : " + e.toString());
}
}

private class SessionCallback implements ISessionCallback {
@Override
public void onSessionOpened() {
// 사용자 정보를 가져옴, 회원가입 미가입시 자동가입 시킴
KakaorequestMe();
}

@Override
public void onSessionOpenFailed(KakaoException exception) {
if(exception != null) {
Log.d(TAG, "Session CallBack Error > " + exception.getMessage());
}
}
}
}


onSuccess 함수에서 보듯 getProfileImagePath(), getId(), getNickname() 함수를 통해 사용자 정보를 가져온다.



GlobalApplication.java

   서비스처럼 동작하기 위한 프로세서

public class GlobalApplication extends Application {

private static GlobalApplication mInstance;
private static volatile Activity currentActivity = null;

public static Activity getCurrentActivity() {
Log.d("TAG", "++ currentActivity : " + (currentActivity != null ? currentActivity.getClass().getSimpleName() : ""));
return currentActivity;
}

public static void setCurrentActivity(Activity currentActivity) {
GlobalApplication.currentActivity = currentActivity;
}

public static GlobalApplication getGlobalApplicationContext() {
if(mInstance == null)
throw new IllegalStateException("this application does not inherit GlobalApplication");
return mInstance;
}

@Override
public void onCreate() {
super.onCreate();
mInstance = this;
KakaoSDK.init(new KakaoSDKAdapter());
}
}


KakaoSDKAdapter.java

  Application 서비스 초기화

public class KakaoSDKAdapter extends KakaoAdapter {

    @Override
public ISessionConfig getSessionConfig() {
return new ISessionConfig() {
@Override
public AuthType[] getAuthTypes() {
return new AuthType[] {AuthType.KAKAO_LOGIN_ALL};
}
@Override
public boolean isUsingWebviewTimer() {
return false;
}
@Override
public boolean isSecureMode() { return true; }
@Override
public ApprovalType getApprovalType() {
return ApprovalType.INDIVIDUAL;
}
@Override
public boolean isSaveFormData() {
return true;
}
};
}

@Override
public IApplicationConfig getApplicationConfig() {
return new IApplicationConfig() {
@Override
public Context getApplicationContext() {
return GlobalApplication.getGlobalApplicationContext();
}
};
}
}



4. 메니페스트에 카카오 서비스 등록


<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="PACKAGE_NAME">

<uses-permission android:name="android.permission.INTERNET" />

<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=".MainActivity">
<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="eabf3c2485cd80a68e1b30989e6f77a2" />
</application>

</manifest>


application > android:name=".GlobalApplication" <- 여기에 파일을 등록해 줘야 한다.