最近由于項目做國際化,所以需要接入Google、FaceBook、Twitter等各種第三方登錄的Api,于是查找官網資料,申請各種key和密鑰,最后成功完成了這三個第三方登錄Api的功能,但是由于很多地方需要調用,前期做得很粗糙,發現調用很麻煩,于是做了一次封裝,總結一下,關于資料的申請這里就不說了,本博客采用的是Kotlin代碼,不熟悉Kotlin的同學可以學習一下,直接上封裝的代碼:
一、接入Google、Facebook、Twitter之前需要安裝Google服務,所以首先需要判斷用戶是否安裝Google服務插件,這里說特別說明一下,一定要安裝官網的正版Google服務插件,要不然會出現各種問題,這里就不展開了.檢測用戶是否安裝Google服務的方法如下:
/**
* 檢查用戶是否安裝Google Play 服務
*/
open fun onCheckGooglePlayService(activity:Activity,code:Int){
// 驗證是否已在此設備上安裝并啟用Google Play服務,以及此設備上安裝的舊版本是否為此客戶端所需的版本
GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(activity)
/**
* 通過isUserResolvableError來確定是否可以通過用戶操作解決錯誤
*/
if (GoogleApiAvailability.getInstance().isUserResolvableError(code)) {
? ? GoogleApiAvailability.getInstance().getErrorDialog(activity, code, 200).show()
}
}
fun checkGooglePlayServiceExist(activity: Activity): Int {
? ? return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity)
}
二.Google登錄工具類的封裝:
/**
* @author: njb
* @date: 2021/5/8 14:37
* @desc: Google登錄工具類
*/
open class GoogleLoginUtils(private val activity: Activity, var listener: GoogleSignListener) {
? ? var requestCode = 10
? ? private var mGoogleSignInClient: GoogleSignInClient? = null
? ? private var googleSignListener: GoogleSignListener? = null
? ? init {
? ? ? ? //初始化谷歌登錄服務
? ? ? ? val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
? ? ? ? ? ? ? ? .requestEmail()
? ? ? ? ? ? ? ? .build()
? ? ? ? mGoogleSignInClient = GoogleSignIn.getClient(activity, gso)
? ? }
? ? /**
? ? * 登錄
? ? */
? ? open fun signIn() {
? ? ? ? val signInIntent: Intent = mGoogleSignInClient!!.signInIntent
? ? ? ? activity.startActivityForResult(signInIntent, requestCode)
? ? }
? ? /**
? ? * 退出登錄
? ? */
? ? open fun signOut() {
? ? }
? ? fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
? ? ? ? try {
? ? ? ? ? ? val account: GoogleSignInAccount? = completedTask.getResult(ApiException::class.java)
? ? ? ? ? ? val status: Task<GoogleSignInAccount> = completedTask
? ? ? ? ? ? if (status.isSuccessful) {
? ? ? ? ? ? ? ? if (account != null) {
? ? ? ? ? ? ? ? ? ? //ToastUtils.showShort(activity.getString(R.string.login_success))
? ? ? ? ? ? ? ? ? ? googleSignListener?.googleLoginSuccess(account)
? ? ? ? ? ? ? ? ? ? LogUtils.d("account" + account?.account)
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? googleSignListener?.googleLoginFail(activity.getString(R.string.login_failed))
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } catch (e: ApiException) {
? ? ? ? ? ? LogUtils.d("signInResult:failed code=" + e.statusCode)
? ? ? ? }
? ? }
? ? open fun setGoogleSignListener(googleSignListener: GoogleSignListener?) {
? ? ? ? this.googleSignListener = googleSignListener
? ? }
? ? interface GoogleSignListener {
? ? ? ? fun googleLoginSuccess(account: GoogleSignInAccount)
? ? ? ? fun googleLoginFail(message: String?)
? ? ? ? fun googleLogoutSuccess()
? ? ? ? fun googleLogoutFail()
? ? }
? ? /**
? ? * 檢查 Google Play 服務
? ? */
? ? open fun onCheckGooglePlayServices(activity: Activity, code: Int) {
? ? ? ? // 驗證是否已在此設備上安裝并啟用Google Play服務,以及此設備上安裝的舊版本是否為此客戶端所需的版本
? ? ? ? GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(activity)
? ? ? ? /**
? ? ? ? * 通過isUserResolvableError來確定是否可以通過用戶操作解決錯誤
? ? ? ? */
? ? ? ? if (GoogleApiAvailability.getInstance().isUserResolvableError(code)) {
? ? ? ? ? ? GoogleApiAvailability.getInstance().getErrorDialog(activity, code, 200).show()
? ? ? ? }
? ? }
? ? fun checkGooglePlayServiceExist(activity: Activity): Int {
? ? ? ? return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity)
? ? }
}
三、FaceBook登錄工具類的封裝:
/**
*@author: njb
*@date:? 2021/5/8 14:26
*@desc:? FaceBook登錄工具類
*/
open class FacebookLoginUtils(private val activity: Activity) {
? ? private var loginManager: LoginManager? = null
? ? private val permissions: List<String>
? ? private var callbackManager: CallbackManager? = null
? ? private var requestSuccessCode = 2896
? ? private var requestCancelCode = 2897
? ? private var requestFailedCode = 2898
? ? private var mFaceBookLoginListener: FaceBookLoginListener? = null
? ? var infoBean: FaceLoginInfoBean? = null
? ? init {
? ? ? ? //初始化facebook登錄服務
? ? ? ? callbackManager = CallbackManager.Factory.create()
? ? ? ? getLoginManager().registerCallback(callbackManager, object : FacebookCallback<LoginResult> {
? ? ? ? ? ? override fun onSuccess(result: LoginResult?) {
? ? ? ? ? ? ? ? activity.setResult(requestSuccessCode)
? ? ? ? ? ? ? ? getLoginInfo(result?.accessToken)
? ? ? ? ? ? }
? ? ? ? ? ? override fun onCancel() {
? ? ? ? ? ? ? ? activity.setResult(requestCancelCode)
? ? ? ? ? ? ? ? mFaceBookLoginListener?.onLoginCancel(activity.getString(R.string.login_cancel))
? ? ? ? ? ? }
? ? ? ? ? ? override fun onError(error: FacebookException?) {
? ? ? ? ? ? ? ? activity.setResult(requestFailedCode)
? ? ? ? ? ? ? ? mFaceBookLoginListener?.onLoginFail(error?.message)
? ? ? ? ? ? ? ? LogUtils.d(error?.message)
? ? ? ? ? ? }
? ? ? ? })
? ? ? ? permissions = listOf("email", "user_likes", "user_status", "user_photos", "user_birthday", "public_profile", "user_friends");
? ? }
? ? /**
? ? * 登陸
? ? */
? ? fun login() {
? ? ? ? getLoginManager().logIn(activity, permissions)
? ? }
? ? /**
? ? * 退出登陸
? ? */
? ? fun loginOut() {
? ? ? ? var logout = activity.resources.getString(R.string.com_facebook_loginview_log_out_action)
? ? ? ? var cancel = activity.resources.getString(R.string.com_facebook_loginview_cancel_action)
? ? ? ? val message: String
? ? ? ? val profile: Profile = Profile.getCurrentProfile()
? ? ? ? message = if (profile?.name != null) {
? ? ? ? ? ? java.lang.String.format(
? ? ? ? ? ? ? ? ? ? activity.resources.getString(
? ? ? ? ? ? ? ? ? ? ? ? ? ? R.string.com_facebook_loginview_logged_in_as),
? ? ? ? ? ? ? ? ? ? profile.name)
? ? ? ? } else {
? ? ? ? ? ? activity.resources.getString(
? ? ? ? ? ? ? ? ? ? R.string.com_facebook_loginview_logged_in_using_facebook)
? ? ? ? }
? ? ? ? val builder: AlertDialog.Builder = AlertDialog.Builder(activity)
? ? ? ? builder.setMessage(message)
? ? ? ? ? ? ? ? .setCancelable(true)
? ? ? ? ? ? ? ? .setPositiveButton(logout) { _, _ ->
? ? ? ? ? ? ? ? ? ? getLoginManager().logOut()
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? .setNegativeButton(cancel, null)
? ? ? ? builder.create().show()
? ? }
? ? /**
? ? * 獲取登錄信息
? ? * @param accessToken
? ? */
? ? private fun getLoginInfo(accessToken: AccessToken?) {
? ? ? ? var request = GraphRequest.newMeRequest(accessToken, object : GraphRequest.GraphJSONObjectCallback {
? ? ? ? ? ? override fun onCompleted(`object`: JSONObject?, response: GraphResponse?) {
? ? ? ? ? ? ? ? `object`?.run {
? ? ? ? ? ? ? ? ? ? val id = optString("id") //比如:13813813888
? ? ? ? ? ? ? ? ? ? val name = optString("name") //比如:Zhang San
? ? ? ? ? ? ? ? ? ? val gender = optString("gender") //性別:比如 male (男)? female (女)
? ? ? ? ? ? ? ? ? ? val email = optString("email") //郵箱:比如:11111@qq.com
? ? ? ? ? ? ? ? ? ? //獲取用戶頭像
? ? ? ? ? ? ? ? ? ? val object_pic = optJSONObject("picture")
? ? ? ? ? ? ? ? ? ? val object_data = object_pic.optJSONObject("data")
? ? ? ? ? ? ? ? ? ? val photo = object_data.optString("url")
? ? ? ? ? ? ? ? ? ? //獲取地域信息
? ? ? ? ? ? ? ? ? ? val locale = optString("locale") //zh_CN 代表中文簡體
? ? ? ? ? ? ? ? ? ? infoBean = FaceLoginInfoBean()
? ? ? ? ? ? ? ? ? ? infoBean?.id = id
? ? ? ? ? ? ? ? ? ? infoBean?.name = name
? ? ? ? ? ? ? ? ? ? infoBean?.email = email
? ? ? ? ? ? ? ? ? ? infoBean?.gender = gender
? ? ? ? ? ? ? ? ? ? infoBean?.picture = object_pic.toString()
? ? ? ? ? ? ? ? ? ? infoBean?.data = object_data.toString()
? ? ? ? ? ? ? ? ? ? infoBean?.photo = photo
? ? ? ? ? ? ? ? ? ? infoBean?.locale = locale
? ? ? ? ? ? ? ? ? ? infoBean?.let { mFaceBookLoginListener?.onLoginSuccess(it) }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? })
? ? ? ? val parameters = Bundle()
? ? ? ? parameters.putString("fields", "id,name,link,gender,birthday,email,picture,locale,updated_time,timezone,age_range,first_name,last_name")
? ? ? ? request.parameters = parameters
? ? ? ? request.executeAsync()
? ? }
? ? fun getCallbackManager(): CallbackManager? {
? ? ? ? return callbackManager
? ? }
? ? /**
? ? * 獲取loginMananger
? ? * @return
? ? */
? ? private fun getLoginManager(): LoginManager {
? ? ? ? if (loginManager == null) {
? ? ? ? ? ? loginManager = LoginManager.getInstance();
? ? ? ? }
? ? ? ? return loginManager!!
? ? }
? ? companion object {
? ? ? ? /**
? ? ? ? * 是否處在登陸狀態
? ? ? ? */
? ? ? ? fun isLogin(): Boolean {
? ? ? ? ? ? val accessToken = AccessToken.getCurrentAccessToken()
? ? ? ? ? ? val isLoggedIn = accessToken != null && !accessToken.isExpired
? ? ? ? ? ? return isLogin()
? ? ? ? }
? ? }
? ? open fun setFaceBookLoginListener(faceBookLoginListener: FaceBookLoginListener?) {
? ? ? ? this.mFaceBookLoginListener = faceBookLoginListener
? ? }
? ? interface FaceBookLoginListener {
? ? ? ? fun onLoginSuccess(infoBean: FaceLoginInfoBean)
? ? ? ? fun onLoginCancel(message: String?)
? ? ? ? fun onLoginFail(message: String?)
? ? ? ? fun onLogoutSuccess()
? ? ? ? fun onLogoutFail()
? ? }
}
四、Twitter登錄工具類的封裝:
**
* @author: njb
* @date: 2021/5/14 10:08
* @desc: Twitter登錄工具類
*/
class TwitterLoginUtils(activity: Activity) {
? ? ? ? private var activityRef: WeakReference<Activity>? = null
? ? ? ? var callback: Callback<TwitterSession>? = null
? ? @Volatile
? ? var authClient: TwitterAuthClient? = null
? ? companion object {
? ? ? ? const val ERROR_MSG_NO_ACTIVITY = ("TwitterLoginButton requires an activity."
? ? ? ? ? ? ? ? + " Override getActivity to provide the activity for this button.")
? ? }
? ? init {
? ? ? ? activityRef = WeakReference(activity)
? ? ? ? TwitterCore.getInstance()
? ? }
? ? fun setOnLoginByTwitterClick(callback: Callback<TwitterSession>?) {
? ? ? ? this.callback = callback
? ? ? ? checkCallback(callback)
? ? ? ? checkActivity(activityRef?.get())
? ? ? ? twitterAuthClient!!.authorize(activityRef?.get(), callback)
? ? }
? ? private val twitterAuthClient: TwitterAuthClient?
? ? ? ? get() {
? ? ? ? ? ? if (authClient == null) {
? ? ? ? ? ? ? ? synchronized(TwitterLoginButton::class.java) {
? ? ? ? ? ? ? ? ? ? if (authClient == null) {
? ? ? ? ? ? ? ? ? ? ? ? authClient = TwitterAuthClient()
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return authClient
? ? ? ? }
? ? private fun checkCallback(callback: Callback<*>?) {
? ? ? ? if (callback == null) {
? ? ? ? ? ? CommonUtils.logOrThrowIllegalStateException(TwitterCore.TAG,
? ? ? ? ? ? ? ? ? ? "Callback must not be null, did you call setCallback?")
? ? ? ? }
? ? }
? ? private fun checkActivity(activity: Activity?) {
? ? ? ? if (activity == null || activity.isFinishing) {
? ? ? ? ? ? CommonUtils.logOrThrowIllegalStateException(TwitterCore.TAG, ERROR_MSG_NO_ACTIVITY)
? ? ? ? }
? ? }
? ? /**
? ? * Call this method when [Activity]
? ? * is called to complete the authorization flow.
? ? *
? ? * @param requestCode the request code used for SSO
? ? * @param resultCode? the result code returned by the SSO activity
? ? * @param data? ? ? ? the result data returned by the SSO activity
? ? */
? ? fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
? ? ? ? if (requestCode == twitterAuthClient!!.requestCode) {
? ? ? ? ? ? twitterAuthClient!!.onActivityResult(requestCode, resultCode, data)
? ? ? ? }
? ? }
}
?五、具體使用代碼如下:
5.1------使用Google登錄時需要先判斷用戶是否安裝Google服務,
?5.2------使用具體步驟如下:
?a. 先聲明工具類
private var mGoogleLogin: GoogleLoginUtils? = null
private var mFacebookLoginUtils: FacebookLoginUtils? = null
?b.Google和FaceBook工具類的初始化
private fun initGoogle() {
? ? mGoogleLogin = GoogleLoginUtils(this, this)
? ? mGoogleLogin?.setGoogleSignListener(this)
}
private fun initFaceBook() {
? ? mFacebookLoginUtils = FacebookLoginUtils(this)
? ? mFacebookLoginUtils?.setFaceBookLoginListener(this)
}
c.點擊Google和FaceBook兩個按鈕分別調用不同的方法
R.id.iv_google -> {//先檢查是否安裝Google服務
? ? checkGoogleService()
}
R.id.iv_face_book -> {//檢查是否安裝FaceBook客戶端
? ? if (!CheckApkExist.checkFacebookExist(this)) {
? ? ? ? ToastUtils.showShort(getString(com.jiaoday.base.R.string.please_install_face_book_first))
? ? } else {
? ? ? ? mFacebookLoginUtils?.login()
? ? }
}
private fun checkGoogleService() {
? ? val code = mGoogleLogin?.checkGooglePlayServiceExist(this)
? ? if (code == ConnectionResult.SUCCESS) {
? ? ? ? mGoogleLogin?.signIn()
? ? } else {
? ? ? ? code?.let { mGoogleLogin?.onCheckGooglePlayServices(this, it) }
? ? }
}
d.Google和FaceBook登錄回調,在最開始繼承一下登錄回調監聽方法:
?GoogleLoginUtils.GoogleSignListener, FacebookLoginUtils.FaceBookLoginListener
e.登錄成功、失敗、取消登錄后的回調
override fun googleLoginSuccess(account: GoogleSignInAccount) {
? ? //google登錄成功后返回的信息
? ? if (account.email != null) {
? ? ? ? thirdAccountLogin(account.email.toString(), account.email.toString(), "4")
? ? }
}
override fun googleLoginFail(message: String?) {
? ? ToastUtils.showShort(message)
}
override fun googleLogoutSuccess() {
}
override fun googleLogoutFail() {
}
?f.onActivityResult回調結果:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
? ? super.onActivityResult(requestCode, resultCode, data)
? ? if (requestCode == mGoogleLogin?.requestCode) {
? ? ? ? val task: Task<GoogleSignInAccount> = GoogleSignIn.getSignedInAccountFromIntent(data)
? ? ? ? mGoogleLogin?.handleSignInResult(task)
? ? }
? ? mFacebookLoginUtils?.getCallbackManager()?.onActivityResult(requestCode, resultCode, data)
}
?六、登錄成功后處理自己的登錄邏輯,調用第三方登錄接口,這里Google登錄使用的是最新的api,如果找不到導包大家可以修改版本,后面會給出源碼地址,這里只是簡單說出使用步驟,這里基本上三種登錄都已經在項目中成功使用,大家可以嘗試一下,如有問題,及時提出,我會修改.