Reputation: 1527
Right now I have to convert the whole codebase of my project to Kotlin, and one of the parts in this involves the Facebook Account Kit, where I have to use my mobile phone number to login to the app, as follows:
val intent = Intent(activity, AccountKitActivity::class.java)
val uiManager = CustomUIManager(ButtonType.CONTINUE, ButtonType.NEXT, TextPosition.ABOVE_BODY, R.style.AccountKitTheme)
val configurationBuilder = AccountKitConfiguration.AccountKitConfigurationBuilder(LoginType.PHONE,
AccountKitActivity.ResponseType.CODE)
//TODO: disable until I figure out what's going on
//configurationBuilder.setUIManager(uiManager)
configurationBuilder.setReadPhoneStateEnabled(true)
configurationBuilder.setReceiveSMS(true)
val config = configurationBuilder.build();
intent.putExtra(AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION, config)
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
activity.overridePendingTransition(0, 0)
Log.i("account_kit_login", "start "+config.notificationChannels)
activity.startActivityForResult(intent, ACCOUNT.FACEBOOK.code)
This uiManager
's class looks like this:
class CustomUIManager : BaseUIManager {
private var confirmButton: ButtonType? = null
private var entryButton: ButtonType? = null
private var textPosition: TextPosition? = null
constructor(
confirmButton: ButtonType,
entryButton: ButtonType,
textPosition: TextPosition,
themeResourceId: Int) : super(themeResourceId) {
this.confirmButton = confirmButton
this.entryButton = entryButton
this.textPosition = textPosition
}
private constructor(source: Parcel) : super(source) {
var s: String? = source.readString()
val confirmButton = if (s == null) null else ButtonType.valueOf(s)
s = source.readString()
val entryButton = if (s == null) null else ButtonType.valueOf(s)
s = source.readString()
val textPosition = if (s == null) null else TextPosition.valueOf(s)
this.confirmButton = confirmButton
this.entryButton = entryButton
this.textPosition = textPosition
}
override fun getHeaderFragment(state: LoginFlowState): Fragment? {
val prefix: Int
val type = 0
when (state) {
LoginFlowState.PHONE_NUMBER_INPUT -> prefix = R.string.header_phone_number_input
LoginFlowState.SENDING_CODE -> {
prefix = R.string.header_sending_code
return PlaceholderFragment.newInstance(prefix, type, R.dimen.loading_placeholder_height)
}
LoginFlowState.SENT_CODE -> {
prefix = R.string.header_sent_code
return PlaceholderFragment.newInstance(prefix, type, R.dimen.loading_placeholder_height)
}
LoginFlowState.CODE_INPUT -> prefix = R.string.header_code_input
LoginFlowState.VERIFYING_CODE -> prefix = R.string.header_verifying_code
LoginFlowState.VERIFIED, LoginFlowState.ACCOUNT_VERIFIED, LoginFlowState.CONFIRM_ACCOUNT_VERIFIED, LoginFlowState.CONFIRM_INSTANT_VERIFICATION_LOGIN -> prefix = R.string.header_account_verified
LoginFlowState.ERROR -> prefix = R.string.header_error
else -> return super.getHeaderFragment(state)
}
return PlaceholderFragment.newInstance(prefix, type)
}
override fun getBodyFragment(state: LoginFlowState): Fragment? {
val prefix: Int
val type = 0
when (state) {
LoginFlowState.VERIFIED -> {
prefix = R.string.body_verified
return PlaceholderFragment.newInstance(prefix, type, R.dimen.loading_placeholder_height)
}
LoginFlowState.ERROR -> {
prefix = R.string.body_error
return PlaceholderFragment.newInstance(prefix, type, R.dimen.loading_placeholder_height)
}
LoginFlowState.CONFIRM_ACCOUNT_VERIFIED -> {
prefix = R.string.body_confirm_account_verified
return PlaceholderFragment.newInstance(prefix, type, R.dimen.loading_placeholder_height)
}
else -> return super.getBodyFragment(state)
}
}
//
// @Nullable
// @Override
// public Fragment getFooterFragment(LoginFlowState state) {
// String prefix = "";
// switch (state) {
// case PHONE_NUMBER_INPUT:
// prefix = "custom footer phone input";
// break;
// case EMAIL_INPUT:
// prefix = "custom footer email input";
// break;
// case SENDING_CODE:
// prefix = "custom footer sending code";
// break;
// case SENT_CODE:
// prefix = "custom footer sent code";
// break;
// case CODE_INPUT:
// prefix = "custom footer code input";
// break;
// case EMAIL_VERIFY:
// prefix = "custom footer email verify";
// break;
// case CONFIRM_ACCOUNT_VERIFIED:
// prefix = "custom footer confirm account";
// break;
// case VERIFYING_CODE:
// prefix = "custom footer verified code";
// break;
// case CONFIRM_INSTANT_VERIFICATION_LOGIN:
// prefix = "custom footer confirm instant verification login";
// break;
// case VERIFIED:
// prefix = "custom footer verified";
// break;
// case RESEND:
// prefix = "custom footer resend";
// break;
// case ERROR:
// prefix = "custom footer error";
// break;
// case NONE:
// break;
// }
// return PlaceholderFragment.newInstance(prefix);
// }
override fun getButtonType(state: LoginFlowState): ButtonType? {
when (state) {
LoginFlowState.PHONE_NUMBER_INPUT -> return entryButton
LoginFlowState.EMAIL_INPUT -> return entryButton
LoginFlowState.CODE_INPUT -> return confirmButton
else -> return null
}
}
override fun onError(error: AccountKitError?) {
// handle error
Trace.d("onError Custom AK: " + error!!.userFacingMessage)
}
override fun writeToParcel(dest: Parcel, flags: Int) {
super.writeToParcel(dest, flags)
dest.writeString(if (confirmButton != null) confirmButton!!.name else null)
dest.writeString(if (entryButton != null) entryButton!!.name else null)
dest.writeString(if (textPosition != null) textPosition!!.name else null)
}
companion object {
val CREATOR: Parcelable.Creator<CustomUIManager> = object : Parcelable.Creator<CustomUIManager> {
override fun createFromParcel(source: Parcel): CustomUIManager {
return CustomUIManager(source)
}
override fun newArray(size: Int): Array<CustomUIManager?> {
return arrayOfNulls(size)
}
}
}
}
As seen in the invocation code in the first block, I had to disable the custom UI so the app won't crash. The following is the stacktrace of the crash:
onCommon()-- Feedback channel: {category=2, app_is_inner=0, is_root=0, sub_category=0, exp_key=java.lang.RuntimeException: Unable to start activity ComponentInfo{net.inovidea.playday/com.facebook.accountkit.ui.AccountKitActivity}: java.lang.ArrayIndexOutOfBoundsException: length=3; index=4522062
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2505)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2577)
at android.app.ActivityThread.access$1000(ActivityThread.java:164)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1462)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
*****
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=3; index=4522062
at com.facebook.accountkit.ui.AccountKitConfiguration.<init>(AccountKitConfiguration.java:167)
at com.facebook.accountkit.ui.AccountKitConfiguration.<init>(AccountKitConfiguration.java:38)
at com.facebook.accountkit.ui.AccountKitConfiguration$1.createFromParcel(AccountKitConfiguration.java:209)
at com.facebook.accountkit.ui.AccountKitConfiguration$1.createFromParcel(AccountKitConfiguration.java:207)
at android.os.Parcel.readParcelable(Parcel.java:2265)
at android.os.Parcel.readValue(Parcel.java:2165)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2527)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.Bundle.getParcelable(Bundle.java:755)
at android.content.Intent.getParcelableExtra(Intent.java:5127)
at com.facebook.accountkit.ui.AccountKitActivityBase.onCreate(AccountKitActivityBase.java:58)
at com.facebook.accountkit.ui.AccountKitActivity.onCreate(AccountKitActivity.java:246)
at android.app.Activity.performCreate(Activity.java:6093)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2458)
... 10 more, app_pack=net.inovidea.playday, client_time=2018-08-24 16:29:48}
When I tried to look at the problematic line in the stacktrace, inside the AccountKitConfiguration
class, it apparently points towards the part where it creates a new Int array and fills it up with the designated NotificationChannel
s. Then again, the class file was a decompiled file, so I 'm not sure if its pointing there is correct or not.
This error does NOT show when I comment out that UIManager
setting, weirdly enough.
Is there something wrong with my CustomUIManager
?
Upvotes: 1
Views: 200