본문 바로가기
Android

안드로이드 카카오톡 로그인 연동하기

by 일용직 코딩노동자 2020. 12. 9.
728x90
반응형

우선

 

developers.kakao.com/

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

카카오톡 개발자 사이트를 들어가줄게요.

 

내 에플리케이션을 들어가주세요

 

추가하기를 들어가주세요

 

이러한 화면이 나옵니다.

 

앱 아이콘을 추가하시고, 앱 이름 사업자명(회사명) 을 입력하시면 됩니다.

 

 

이런식으로 화면을 볼 수 있습니다.

 

여기서 플랫폼 설정하기를 눌러주세요.

 

여기서 나오는 네이티브 앱 키는 잘 복사해두세요!!

 

안드로이드 플랫폼 등록을 클릭하시면 됩니다!

 

 

키 해시는

 

private void HashKey() {
        try {
            PackageInfo pkinfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
            for (Signature signature : pkinfo.signatures) {
                MessageDigest messageDigest = MessageDigest.getInstance("SHA");
                messageDigest.update(signature.toByteArray());
                String result = new String(Base64.encode(messageDigest.digest(), 0));
                Log.d("해시", result);
            }
        }
        catch (Exception e) {
        }
    }

해당 함수로 로그에서 찍어서 보면 됩니다.

배포를 하실때는

안드로이드 스튜디오 터미널에서

echo SHA-1값 | xxd -r -p | openssl base64

치시면 나옵니다.

여기 사진처럼 스토어에 올린 SHA-1 값을 이용하셔야 합니다.

그리고 왼쪽에 카카로 로그인 동의항목을 들어가서 필요한 정보들을 체크해주세요.

 

자 이제 의존성을 추가해볼가요.

 

build.gradle (:app) -> dependencies

 

implementation group: 'com.kakao.sdk', name: 'usermgmt', version: '1.30.0'
// 카카오톡
implementation group: 'com.kakao.sdk', name: 'kakaotalk', version: '1.30.0'
// 카카오스토리
implementation group: 'com.kakao.sdk', name: 'kakaostory', version: '1.30.0'
// 카카오링크
implementation group: 'com.kakao.sdk', name: 'kakaolink', version: '1.30.0'
// 카카오내비
implementation group: 'com.kakao.sdk', name: 'kakaonavi', version: '1.30.0'

그리고...

 

gradle.properties

KAKAO_SDK_GROUP=com.kakao.sdk
KAKAO_SDK_VERSION=1.5.1

그다음에는

 

build.gradle(앱이름)

 

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        /* 카카오 추가 */
        maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' }
    }
}

 

그리고 메니페스트에 가보도록 할게요.

 

인터넷 권한 추가해줄게요.

 

<!-- 인터넷 사용 권한 설정 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

 

그다음에

<meta-data
android:name="com.kakao.sdk.AppKey"
android:value="@string/kakaoApi" />

자 여기서 value에는 아까 복사해두신 네이티브 앱 키를 넣어주시면 됩니다.

 

 

메니페스트 전체샷 입니다.

 

기본셋팅이 끝났습니다.

 

그다음에 KakaoSDKInit 이라는 클래스를 하나 만들어주세요.

 

import android.app.Application;
import com.kakao.auth.KakaoSDK;

public class KakaoSDKInit extends Application {

    private static volatile KakaoSDKInit instance = null;

    public static KakaoSDKInit getGlobalApplicationContext() {
        if(instance == null) {
            throw new IllegalStateException("this application does not inherit com.kakao.GlobalApplication");
        }
        return instance;
    }

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

    @Override
    public void onTerminate() {
        super.onTerminate();
        instance = null;
    }
}

그리고 해당 클래스명을 위에 보여드린 메니페스트처럼 추가해주세요.

 

android:name=".KakaoSDKInit"

 

그리고 KakaoSDKAdapter 클래스를 하나 만들어 보겠습니다.

 

import android.content.Context;
import com.kakao.auth.ApprovalType;
import com.kakao.auth.AuthType;
import com.kakao.auth.IApplicationConfig;
import com.kakao.auth.ISessionConfig;
import com.kakao.auth.KakaoAdapter;

class KakaoSDKAdapter extends KakaoAdapter {
    /**
     * Session Config에 대해서는 default값들이 존재한다.
     * 필요한 상황에서만 override해서 사용하면 됨.
     * @return Session의 설정값.
     */
    // 카카오 로그인 세션을 불러올 때의 설정값을 설정하는 부분.
    public ISessionConfig getSessionConfig() {

        return new ISessionConfig() {
            @Override
            public AuthType[] getAuthTypes() {
                return new AuthType[] {AuthType.KAKAO_LOGIN_ALL};
                   /**
                     * KAKAO_TALK: 카카오톡으로 로그인,
                     * KAKAO_STORY: 카카오스토리로 로그인,
                     * KAKAO_ACCOUNT: 웹뷰를 통한 로그인,
                     * KAKAO_TALK_EXCLUDE_NATIVE_LOGIN: 카카오톡으로만 로그인+계정 없으면 계정생성 버튼 제공
                     * KAKAO_LOGIN_ALL: 모든 로그인방식 사용 가능. 정확히는, 카카오톡이나 카카오스토리가 있으면 그 쪽으로 로그인 기능을 제공하고, 둘 다 없으면 웹뷰를 통한 로그인을 제공한다.
                     **/

            }

            @Override
            public boolean isUsingWebviewTimer() {
                return false;
                // SDK 로그인시 사용되는 WebView에서 pause와 resume시에 Timer를 설정하여 CPU소모를 절약한다.
                // true 를 리턴할경우 webview로그인을 사용하는 화면서 모든 webview에 onPause와 onResume 시에 Timer를 설정해 주어야 한다.
                // 지정하지 않을 시 false로 설정된다.
            }

            @Override
            public boolean isSecureMode() {
                return false;
                // 로그인시 access token과 refresh token을 저장할 때의 암호화 여부를 결정한다.
            }

            @Override
            public ApprovalType getApprovalType() {
                return ApprovalType.INDIVIDUAL;
                // 일반 사용자가 아닌 Kakao와 제휴된 앱에서만 사용되는 값으로, 값을 채워주지 않을경우 ApprovalType.INDIVIDUAL 값을 사용하게 된다.
            }

            @Override
            public boolean isSaveFormData() {
                return true;
                // Kakao SDK 에서 사용되는 WebView에서 email 입력폼의 데이터를 저장할지 여부를 결정한다.
                // true일 경우, 다음번에 다시 로그인 시 email 폼을 누르면 이전에 입력했던 이메일이 나타난다.
            }
        };
    }

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

 

다음으로 KaKaoCallBack 클래스를 하나 만들어주겠습니다.

 

이 클래스가 본격적으로 콜백을 받아서 저희가 긁어오고 싶은 정보를 긁어오는 곳입니다.

 

import android.util.Log;
import com.kakao.auth.ApiErrorCode;
import com.kakao.auth.ISessionCallback;
import com.kakao.network.ErrorResult;
import com.kakao.usermgmt.UserManagement;
import com.kakao.usermgmt.callback.MeV2ResponseCallback;
import com.kakao.usermgmt.response.MeV2Response;
import com.kakao.util.exception.KakaoException;

public class KaKaoCallBack implements ISessionCallback{

    MainActivity mainActivity = new MainActivity();

    @Override
    public void onSessionOpened() {
        UserManagement.getInstance().me(new MeV2ResponseCallback() {
            @Override
            public void onFailure(ErrorResult errorResult) {
                int result = errorResult.getErrorCode();

                if (result == ApiErrorCode.CLIENT_ERROR_CODE) mainActivity.kakaoError("네트워크 연결이 불안정합니다. 다시 시도해 주세요.");
                else mainActivity.kakaoError("로그인 도중 오류가 발생했습니다.");
            }

            @Override
            public void onSessionClosed(ErrorResult errorResult) {
                mainActivity.kakaoError("세션이 닫혔습니다. 다시 시도해 주세요.");
            }

            @Override
            public void onSuccess(MeV2Response result) {
                Log.d("닉네임 확인 : ",result.getNickname()); //닉네임
                Log.d("이메일 확인 : ",result.getKakaoAccount().getEmail()); //이메일
                Log.d("이미지 확인 : ",result.getThumbnailImagePath()); //프로필 사진
            }
        });
    }

    @Override
    public void onSessionOpenFailed (KakaoException e){
        mainActivity.kakaoError("로그인 도중 오류가 발생했습니다. 인터넷 연결을 확인해주세요.");
    }
}

 

이제 메인을 살펴볼게요.

 

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:gravity="center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.kakao.usermgmt.LoginButton
            android:id="@+id/loginButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        </com.kakao.usermgmt.LoginButton>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/kakaoLogin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="카카오 로그인"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        </Button>
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout">

        <Button
            android:id="@+id/kakaoLogout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="카카오 로그아웃"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        </Button>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

XML코드입니다.

 

대충 이런식입니다.

 

카카오 SDK에서 제공하는 버튼을 커스텀하기가 까다로워서 임의의 버튼을 하나 더 생성하여 

 

버튼을 클릭하면 뒤의 카카오 버튼이 클릭되도록 만들었습니다.

 

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.kakao.auth.Session;
import com.kakao.usermgmt.LoginButton;
import com.kakao.usermgmt.UserManagement;
import com.kakao.usermgmt.callback.LogoutResponseCallback;

public class MainActivity extends AppCompatActivity {

    Button kakaoLogin,kakaoLogout;
    LoginButton loginButton;
    LinearLayout linearLayout;
    private KaKaoCallBack kaKaoCallBack;

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

        viewInit();

        linearLayout.bringToFront();
        linearLayout.setVisibility(View.INVISIBLE);

        kaKaoCallBack = new KaKaoCallBack();
        Session.getCurrentSession().addCallback(kaKaoCallBack);
        Session.getCurrentSession().checkAndImplicitOpen();

        kakaoLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(),"카카오 로그인 버튼 클릭!",Toast.LENGTH_SHORT).show();
                loginButton.performClick();
            }
        });

        kakaoLogout.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "정상적으로 로그아웃되었습니다.", Toast.LENGTH_SHORT).show();

                UserManagement.getInstance().requestLogout(new LogoutResponseCallback() {
                    @Override
                    public void onCompleteLogout() {
                        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                        startActivity(intent);
                        finish();
                    }
                });
            }
        });
    }

    private void viewInit(){
        linearLayout = findViewById(R.id.linearLayout);
        loginButton = findViewById(R.id.loginButton);
        kakaoLogin = findViewById(R.id.kakaoLogin);
        kakaoLogout = findViewById(R.id.kakaoLogout);
    }
    
    public void kakaoError(String msg){
        Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(Session.getCurrentSession().handleActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Session.getCurrentSession().removeCallback(kaKaoCallBack);
    }
}

이렇게 INVISIBLE로 뷰를 가려줍니다.

 

그리고 버튼 리스너 performClick 을 넣어서 일반버튼을 클릭해도 카카오버튼까지 같이 클릭되는 효과를 볼수있습니다.

 

 

만약 X버튼이 기본컬러로 색칠되어있다면 제가 위에서 보여드린 메니페스트 테마랑 동일하게 설정해주세요.

android:theme="@style/Theme.AppCompat.Light.NoActionBar"



이상입니다.

728x90
반응형

댓글