관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 카카오톡 로그인 본문

안드로이드/자바 & Previous

[안드로이드] 카카오톡 로그인

막무가내막내 2019. 7. 19. 22:53
728x90

구글로그인과 페이스북로그인에 이어서 카카오톡 로그인을 해본 걸 정리하는 포스팅을 갖도록 해보겠습니다.

 

 

 

[2020-06-21 업데이트]

참고로 저는 구글 파이어베이스의 OAuth 토큰을 사용하기 위해서 카카오톡 로그인과 구글 로그인을 통합해야했습니다.

그래서 카카오톡 로그인 성공시 해당 정보를 갖고 구글로그인 가입이 되게 하여 토큰을 받을 수 있게 했었습니다.

즉 카카오톡 로그인 -> 구글 로그인 -> 가입 완료가 되는 절차입니다.

 

카카오 디빌로퍼 UI가 좀 바꼇네요. 활성화 하시고 키는 여깄습니다.

 

https://developers.kakao.com/docs/latest/ko/kakaologin/android

 

Kakao Developers

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

developers.kakao.com

 

그리고 플랫폼도 등록해주세요

키 해시는  다음 코드를 안드로이드 스튜디오에서 실행해서 세팅해주시면 되요.

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;
    }
}

manifiest 에 주입해주어야한다

 

 

 

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

 

mtjin/DalkommPhotoEditApp

달콤스터디 사진편집어플 만들기 openCV +안드로이드+파이어베이스 사용. Contribute to mtjin/DalkommPhotoEditApp development by creating an account on GitHub.

github.com

 

댓글과 공감은 큰 힘이됩니다. 감사합니다!

728x90
Comments