前提條件
已完成賬號及用戶SDK的開發,詳細請參見賬號及用戶SDK。
定制項
Android App的OA UI定制項如下。
App界面圖示 | 可定制內容 |
修改原生元素
| |
新增元素
|
Android不支持客戶端修改失敗提示信息,且不支持對現有控件增加自定義事件。您僅可以修改現有控件的事件或新增控件來自定義事件。
顯示手機區號
登錄和注冊頁面中的手機區號默認不顯示,如果您需要顯示手機區號,如+86,請根據以下內容來操作。
在App工程中添加以下代碼,并通過設置supportForeignMobileNumbers參數的值來控制手機區號的顯示和隱藏。
//登錄頁顯示手機區號
OpenAccountUIConfigs.AccountPasswordLoginFlow.supportForeignMobileNumbers=true; //true為顯示,false為隱藏
//忘記密碼頁顯示手機區號
OpenAccountUIConfigs.MobileResetPasswordLoginFlow.supportForeignMobileNumbers=true; //true為顯示,false為隱藏
修改登錄和注冊按鈕的顏色
登錄和注冊按鈕默認為淺灰色,如果您需要修改App登錄和注冊按鈕的顏色,請根據以下步驟來操作。
在代碼工程的styles.xml中新增一個style。
修改style中登錄和注冊按鈕的顏色,其對應的參數為ali_sdk_openaccount_attrs_next_step_bg。
<style name="NewLogin" parent="@style/Login"> //修改item屬性的值 <item name="ali_sdk_openaccount_attrs_next_step_bg">@color/color_1FC88B</item> </style>
修改AndroidManifest中的activity的主題配置,使設置的顏色生效。
//AndroidManifest中的activity的主題配置修改 <activity android:name="com.aliyun.iot.ilop.demo.page.login3rd.OALoginActivity" android:configChanges="orientation|screenSize|keyboardHidden|locale|layoutDirection|keyboard" android:theme="@style/NewLogin" />
修改現有控件的事件
如果您需要修改現有控件的事件,只需重新設置控件事件即可。以重寫登錄界面中的登錄事件為例,即重新定義下圖所示內容。
修改登錄超限提示信息樣式
登錄App時,如果輸入登錄密碼的次數達到上限,App會限制繼續操作,并提示重置密碼。如果您需要修改該失敗提示對話框的樣式,只需修改toastUtils.alert()
即可。
重寫
toastUtils.alert()
的代碼。//OALoginActivity中的LoginTask protected class LoginTask extends TaskWithDialog<Void, Void, Result<LoginResult>> { private String loginId; private String password; private String sig; private String nocToken; private String cSessionId; public LoginTask(Activity activity, String loginId, String password, String sig, String nocToken, String cSessionId) { super(activity); this.loginId = loginId; this.password = password; this.sig = sig; this.nocToken = nocToken; this.cSessionId = cSessionId; } protected Result<LoginResult> asyncExecute(Void... params) { Map<String, Object> loginRequest = new HashMap(); if (this.loginId != null) { loginRequest.put("loginId", this.loginId); } if (this.password != null) { try { String rsaKey = RSAKey.getRsaPubkey(); if (TextUtils.isEmpty(rsaKey)) { return null; } loginRequest.put("password", Rsa.encrypt(this.password, rsaKey)); } catch (Exception var4) { return null; } } LoginActivity.this.hideSoftInputForHw(); Result result; if (!CommonUtils.isNetworkAvailable()) { if (ConfigManager.getInstance().isSupportOfflineLogin()) { return LoginActivity.this.tryOfflineLogin(this.loginId, this.password); } else { result = new Result(); result.code = 10014; result.message = MessageUtils.getMessageContent(10014, new Object[0]); return result; } } else { if (this.sig != null) { loginRequest.put("sig", this.sig); } if (!TextUtils.isEmpty(this.cSessionId)) { loginRequest.put("csessionid", this.cSessionId); } if (!TextUtils.isEmpty(this.nocToken)) { loginRequest.put("nctoken", this.nocToken); } result = OpenAccountUtils.toLoginResult(RpcUtils.pureInvokeWithRiskControlInfo("loginRequest", loginRequest, "login")); return ConfigManager.getInstance().isSupportOfflineLogin() && result.code == 10019 ? LoginActivity.this.tryOfflineLogin(this.loginId, this.password) : result; } } protected void doWhenException(Throwable t) { this.executorService.postUITask(new Runnable() { public void run() { ToastUtils.toastSystemError(LoginTask.this.context); } }); } protected void onPostExecute(Result<LoginResult> result) { this.dismissProgressDialog(); super.onPostExecute(result); try { if (result == null) { if (ConfigManager.getInstance().isSupportOfflineLogin()) { ToastUtils.toastNetworkError(this.context); } else { ToastUtils.toastSystemError(this.context); } } else { android.net.Uri.Builder builder; Intent h5Intent; String accountName; switch(result.code) { case 1: if (result.data != null && ((LoginResult)result.data).loginSuccessResult != null) { SessionData sessionData = OpenAccountUtils.createSessionDataFromLoginSuccessResult(((LoginResult)result.data).loginSuccessResult); if (sessionData.scenario == null) { sessionData.scenario = 1; } LoginActivity.this.sessionManagerService.updateSession(sessionData); accountName = ((LoginResult)result.data).userInputName; if (TextUtils.isEmpty(accountName)) { accountName = this.loginId; } if (ConfigManager.getInstance().isSupportOfflineLogin()) { OpenAccountSDK.getSqliteUtil().saveToSqlite(this.loginId, this.password); } boolean isExist = LoginActivity.this.loginIdEdit.saveInputHistory(accountName); if (AccountPasswordLoginFlow.showTipAlertAfterLogin && !isExist) { String message = ResourceUtils.getString(LoginActivity.this.getApplicationContext(), "ali_sdk_openaccount_dynamic_text_alert_msg_after_login"); LoginActivity.this.showTipDialog(String.format(message, this.loginId)); } else { LoginActivity.this.loginSuccess(); } return; } break; case 2: SessionData sessionData1 = OpenAccountUtils.createSessionDataFromLoginSuccessResult(((LoginResult)result.data).loginSuccessResult); if (sessionData1.scenario == null) { sessionData1.scenario = 1; } LoginActivity.this.sessionManagerService.updateSession(sessionData1); LoginActivity.this.loginSuccess(); break; case 4037: if (AccountPasswordLoginFlow.showAlertForPwdErrorToManyTimes) { String postive = LoginActivity.this.getResources().getString(string.ali_sdk_openaccount_text_confirm); accountName = LoginActivity.this.getResources().getString(string.ali_sdk_openaccount_text_reset_password); final ToastUtils toastUtils = new ToastUtils(); android.content.DialogInterface.OnClickListener postiveListener = new android.content.DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { toastUtils.dismissAlertDialog(LoginActivity.this); } }; android.content.DialogInterface.OnClickListener negativeListener = new android.content.DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { LoginActivity.this.forgetPassword((View)null); } }; //重寫toastUtils類的alert()方法 toastUtils.alert(LoginActivity.this, "", result.message, postive, postiveListener, accountName, negativeListener); } else { ToastUtils.toast(this.context, result.message, result.code); } break; case 26053: if (result.data != null && ((LoginResult)result.data).checkCodeResult != null && !TextUtils.isEmpty(((LoginResult)result.data).checkCodeResult.clientVerifyData)) { builder = Uri.parse(((LoginResult)result.data).checkCodeResult.clientVerifyData).buildUpon(); builder.appendQueryParameter("callback", "https://www.alipay.com/webviewbridge"); h5Intent = new Intent(LoginActivity.this, LoginDoubleCheckWebActivity.class); h5Intent.putExtra("url", builder.toString()); h5Intent.putExtra("title", result.message); h5Intent.putExtra("callback", "https://www.alipay.com/webviewbridge"); LoginActivity.this.startActivityForResult(h5Intent, RequestCode.NO_CAPTCHA_REQUEST_CODE); return; } break; case 26152: if (result.data != null && ((LoginResult)result.data).checkCodeResult != null && !TextUtils.isEmpty(((LoginResult)result.data).checkCodeResult.clientVerifyData)) { builder = Uri.parse(((LoginResult)result.data).checkCodeResult.clientVerifyData).buildUpon(); builder.appendQueryParameter("callback", "https://www.alipay.com/webviewbridge"); h5Intent = new Intent(LoginActivity.this, LoginIVWebActivity.class); h5Intent.putExtra("url", builder.toString()); h5Intent.putExtra("title", result.message); h5Intent.putExtra("callback", "https://www.alipay.com/webviewbridge"); LoginActivity.this.startActivityForResult(h5Intent, RequestCode.RISK_IV_REQUEST_CODE); } break; default: if (TextUtils.equals(result.type, "CALLBACK") && LoginActivity.this.getLoginCallback() != null) { LoginActivity.this.getLoginCallback().onFailure(result.code, result.message); return; } LoginActivity.this.onPwdLoginFail(result.code, result.message); } } } catch (Throwable var8) { AliSDKLogger.e("oa", "after post execute error", var8); ToastUtils.toastSystemError(this.context); } } }
定制彈出的對話框,并顯示
result.message
的錯誤信息。toastUtils.alert(LoginActivity.this, "", result.message, postive, postiveListener, accountName, negativeListener);
新增控件和單擊事件
當您需要在App中新增一個控件,并添加相應的單擊事件時,可以根據以下步驟來操作。
在界面上新增一個控件,并在重寫的xml文件中添加控件信息。
在activity中添加該控件的單擊事件。
新增郵箱登錄方式
如果您需要App支持通過郵箱方式登錄,您需要開發郵箱相關的功能,包括郵箱登錄(圖示中①)、郵箱注冊(圖示中②)、郵箱重置密碼(圖示中③)等。
在App登錄頁面增加郵箱登錄的方式。
Android賬號及用戶SDK的OALoginActivity已默認支持手機號登錄和郵箱登錄。此時您只需要將手機區號隱藏,并修改登錄提示即可。
隱藏手機區號。
//隱藏手機區號 OpenAccountUIConfigs.AccountPasswordLoginFlow.supportForeignMobileNumbers = false;
修改郵箱登錄信息。
//修改登錄提示信息 this.loginIdEdit.getEditText().setHint("請輸入手機號或郵箱賬號");
新增郵箱注冊功能。
在登錄頁面增加郵箱注冊按鈕。
請參見本文檔中新增控件和單擊事件來實現。
定義注冊的回調函數。
//注冊的回調函數 private EmailRegisterCallback getEmailRegisterCallback() { return new EmailRegisterCallback() { @Override public void onSuccess(OpenAccountSession session) { //注冊成功 } @Override public void onFailure(int code, String message) { //注冊失敗 } @Override public void onEmailSent(String email) { } }; }
跳轉到郵箱注冊界面。
//跳轉到郵箱注冊界面 OpenAccountUIService openAccountUIService = OpenAccountSDK.getService(OpenAccountUIService.class); openAccountUIService.showEmailRegister(OALoginActivity.this, getEmailRegisterCallback());
新增郵箱重置密碼功能。
通過郵箱方式登錄App時,如果忘記了郵箱注冊的密碼,需要通過郵箱重置密碼的功能來找回密碼。
在登錄頁面增加郵箱找回按鈕。
請參見本文檔中新增控件和單擊事件來實現。
定義郵箱密碼找回的回調方法。
private EmailResetPasswordCallback getEmailResetPasswordCallback() { return new EmailResetPasswordCallback() { @Override public void onSuccess(OpenAccountSession session) { //修改成功 } @Override public void onFailure(int code, String message) { //修改失敗 } @Override public void onEmailSent(String email) { //發送驗證碼郵件 } }; }
跳轉到修改密碼界面。
OpenAccountUIService openAccountUIService = (OpenAccountUIService) OpenAccountSDK.getService(OpenAccountUIService.class); openAccountUIService.showEmailResetPassword(this, this.getEmailResetPasswordCallback());
更多UI定制參考
如果您還需定制更多的UI,例如修改更多原生元素,您可以根據以下內容來自行實現。
修改更多組件的樣式
賬號及用戶SDK開放了所有組件的樣式,在SDK的deali_sdk_openaccount_styles.xml里定義了可以直接覆蓋的所有樣式。您可以繼承對應的style再修改AndroidManifest.xml中activity的配置。詳細操作請參見本文檔中修改登錄和注冊按鈕的顏色來實現。
修改OA界面布局
控件或Activity通過LayoutMapping類來加載layout文件。建議您不要修改現有控件的ID,直接新增控件來加載自定義的layout文件。
com.alibaba.sdk.android.openaccount.ui.LayoutMapping.put(控件(或activity).class,R.layout.xxx);
您可以在下圖所示目錄下查找所需的layout文件。
定制OA模塊界面
如果您需要自定義整個界面,建議您集成原先界面的activity后,再替換SDK中整個界面的內容。您可以參照以下示例代碼來實現。
//以登錄界面為例 //1.繼承LoginActivity,重寫登錄界面為OALoginActivity public class OALoginActivity extends LoginActivity{} //2.在 OALoginActivity中重寫getLayoutName方法,將布局文件的名稱返回 @Override protected String getLayoutName() { //替換成自己的布局文件名稱 return "ali_sdk_openaccount_login2"; } //3.在賬號及用戶SDK初始化后,將登錄界面替換到SDK中 OALoginAdapter adapter = (OALoginAdapter) LoginBusiness.getLoginAdapter(); adapter.setDefaultLoginClass(OALoginActivity.class);
說明在重寫界面時,需將原界面中的控件全部添加上,且保持ID不變。不需要的控件隱藏處理,請勿刪除,否則可能出現找不到控件的錯誤。
如果您還需定制除原生元素以外的內容,可以參考以下信息來實現。