Android中使用Kotlin實(shí)現(xiàn)Google、FaceBook、Twitter登錄的封裝

最近由于項(xiàng)目做國際化,所以需要接入Google、FaceBook、Twitter等各種第三方登錄的Api,于是查找官網(wǎng)資料,申請各種key和密鑰,最后成功完成了這三個(gè)第三方登錄Api的功能,但是由于很多地方需要調(diào)用,前期做得很粗糙,發(fā)現(xiàn)調(diào)用很麻煩,于是做了一次封裝,總結(jié)一下,關(guān)于資料的申請這里就不說了,本博客采用的是Kotlin代碼,不熟悉Kotlin的同學(xué)可以學(xué)習(xí)一下,直接上封裝的代碼:

一、接入Google、Facebook、Twitter之前需要安裝Google服務(wù),所以首先需要判斷用戶是否安裝Google服務(wù)插件,這里說特別說明一下,一定要安裝官網(wǎng)的正版Google服務(wù)插件,要不然會出現(xiàn)各種問題,這里就不展開了.檢測用戶是否安裝Google服務(wù)的方法如下:

/**

* 檢查用戶是否安裝Google Play 服務(wù)

*/

open fun onCheckGooglePlayService(activity:Activity,code:Int){

// 驗(yàn)證是否已在此設(shè)備上安裝并啟用Google Play服務(wù),以及此設(shè)備上安裝的舊版本是否為此客戶端所需的版本

GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(activity)

/**

* 通過isUserResolvableError來確定是否可以通過用戶操作解決錯(cuò)誤

*/

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 {

? ? ? ? //初始化谷歌登錄服務(wù)

? ? ? ? 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 服務(wù)

? ? */

? ? open fun onCheckGooglePlayServices(activity: Activity, code: Int) {

? ? ? ? // 驗(yàn)證是否已在此設(shè)備上安裝并啟用Google Play服務(wù),以及此設(shè)備上安裝的舊版本是否為此客戶端所需的版本

? ? ? ? GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(activity)

? ? ? ? /**

? ? ? ? * 通過isUserResolvableError來確定是否可以通過用戶操作解決錯(cuò)誤

? ? ? ? */

? ? ? ? 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登錄服務(wù)

? ? ? ? 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 {

? ? ? ? /**

? ? ? ? * 是否處在登陸狀態(tài)

? ? ? ? */

? ? ? ? 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登錄時(shí)需要先判斷用戶是否安裝Google服務(wù),

?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.點(diǎn)擊Google和FaceBook兩個(gè)按鈕分別調(diào)用不同的方法

R.id.iv_google -> {//先檢查是否安裝Google服務(wù)

? ? 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登錄回調(diào),在最開始繼承一下登錄回調(diào)監(jiān)聽方法:

?GoogleLoginUtils.GoogleSignListener, FacebookLoginUtils.FaceBookLoginListener

e.登錄成功、失敗、取消登錄后的回調(diào)

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回調(diào)結(jié)果:

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)

}

?六、登錄成功后處理自己的登錄邏輯,調(diào)用第三方登錄接口,這里Google登錄使用的是最新的api,如果找不到導(dǎo)包大家可以修改版本,后面會給出源碼地址,這里只是簡單說出使用步驟,這里基本上三種登錄都已經(jīng)在項(xiàng)目中成功使用,大家可以嘗試一下,如有問題,及時(shí)提出,我會修改.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容