KakaoTalk 이 설치되어있고 로긴이 되어는데도 불구하고 가입 유도하는 로긴 웹뷰를 띄웁니다. 로그에 아래와 같이 남습니다.
08-23 13:52:28.018 1408-2584/? E/Parcel: Class not found when unmarshalling: com.kakao.auth.authorization.authcode.GetterAuthCode$1
java.lang.ClassNotFoundException: com.kakao.auth.authorization.authcode.GetterAuthCode$1
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:324)
at android.os.Parcel.readParcelableCreator(Parcel.java:2404)
at android.os.Parcel.readParcelable(Parcel.java:2358)
at android.os.Parcel.readValue(Parcel.java:2264)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2614)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.BaseBundle.getString(BaseBundle.java:920)
at android.content.Intent.getStringExtra(Intent.java:6195)
at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:2695)
at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:2157)
at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:6320)
at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:6098)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:170)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3988)
at android.os.Binder.execTransact(Binder.java:453)
Caused by: java.lang.ClassNotFoundException: com.kakao.auth.authorization.authcode.GetterAuthCode$1
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:324)
at android.os.Parcel.readParcelableCreator(Parcel.java:2404)
at android.os.Parcel.readParcelable(Parcel.java:2358)
at android.os.Parcel.readValue(Parcel.java:2264)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2614)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.BaseBundle.getString(BaseBundle.java:920)
at android.content.Intent.getStringExtra(Intent.java:6195)
at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:2695)
at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:2157)
at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:6320)
at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:6098)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:170)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3988)
at android.os.Binder.execTransact(Binder.java:453)
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
SDK는 1.1.20 / 1.1.21 둘다 테스트해 보았고, 관련 코드와 설정들은 다음과 같습니다.
- app/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22" />
<application>
<meta-data android:name="com.kakao.sdk.AppKey"
android:value="13425bebec14a97e8d6f98485596c0f7" />
<activity
android:name="com.kakao.auth.authorization.authcode.KakaoWebViewActivity"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
- gradle.properties
...
KAKAO_SDK_GROUP=com.kakao.sdk
KAKAO_SDK_VERSION=1.1.21
- bundle.gradle
allprojects {
repositories {
mavenLocal()
jcenter()
...
maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' }
}
}
- app/bundle.gradle
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
...
}
...
dependencies {
...
// 카카오톡 sdk를 사용하기 위해 필요.
compile group: project.KAKAO_SDK_GROUP, name: 'usermgmt', version: project.KAKAO_SDK_VERSION
...
}
- app/proguard-rules.pro
-keep class com.kakao.** { *; }
-keepattributes Signature
-keepclassmembers class * {
public static <fields>;
public *;
}
- Login
private class KakaoSessionOpenCallback implements ISessionCallback {
private Promise _promise;
public KakaoSessionOpenCallback(Promise promise) {
_promise = promise;
}
@Override
public void onSessionOpened() {
Session session = Session.getCurrentSession();
session.removeCallback(this);
_promise.resolve(session.getAccessToken());
}
@Override
public void onSessionOpenFailed(KakaoException exception) {
Session.getCurrentSession().removeCallback(this);
if (exception == null) {
Log.d("kakao", "kakao-login-closed");
_promise.reject("kakao-login-cancel", "kakao-login-cancel");
} else {
Log.e("kakao", exception.getLocalizedMessage());
_promise.reject("kakao-login-error", exception);
}
}
}
public void login(Promise promise) {
Session session = Session.getCurrentSession();
if(session.hasValidAccessToken()) {
promise.resolve(session.getAccessToken());
} else {
session.addCallback(new KakaoSessionOpenCallback(promise));
session.open(AuthType.KAKAO_LOGIN_ALL, MainApplication.getCurrentActivity());
}
}
- MainActivity
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// KAKAO
if (Session.getCurrentSession().handleActivityResult(requestCode, resultCode, data)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onResume() {
super.onResume();
MainApplication.setCurrentActivity(this);
}
@Override
protected void onPause() {
Beacon.disconnect();
clearReferences();
super.onPause();
}
@Override
protected void onDestroy() {
Beacon.disconnect();
clearReferences();
super.onDestroy();
}
private void clearReferences() {
Activity currActivity = MainApplication.getCurrentActivity();
if (currActivity != null && currActivity.equals(this)) {
MainApplication.setCurrentActivity(null);
}
}
- KakaoSDKAdapter
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_LOGIN_ALL};
}
@Override
public boolean isUsingWebviewTimer() {
return false;
}
@Override
public boolean isSecureMode() {
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 MainApplication.getCurrentActivity();
}
@Override
public Context getApplicationContext() {
return MainApplication.getGlobalApplicationContext();
}
};
}
}
- MainApplication
private static volatile MainApplication instance = null;
private static FragmentActivity currentActivity;
@Override
public void onCreate() {
super.onCreate();
// KAKAO
instance = this;
KakaoSDK.init(new KakaoSDKAdapter());
// FACEBOOK
FacebookSdk.sdkInitialize(getApplicationContext());
// If you want to use AppEventsLogger to log events.
AppEventsLogger.activateApp(this);
}
public static FragmentActivity getCurrentActivity() {
return currentActivity;
}
// KAKAO
/**
* singleton 애플리케이션 객체를 얻는다.
* @return singleton 애플리케이션 객체
*/
public static MainApplication getGlobalApplicationContext() {
if(instance == null)
throw new IllegalStateException("this application does not inherit MainApplication");
return instance;
}
// Activity가 올라올때마다 Activity의 onCreate에서 호출해줘야한다.
public static void setCurrentActivity(FragmentActivity currentActivity) {
MainApplication.currentActivity = currentActivity;
}
/**
* 애플리케이션 종료시 singleton 어플리케이션 객체 초기화한다.
*/
@Override
public void onTerminate() {
super.onTerminate();
instance = null;
}
그외에 iOS에서는 UserManagement.requestMe 도 작동을 안해서 accessToken 얻어서 API 호출하고 있습니다. Callback호출이 안되네요