├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── pavlospt │ │ └── signindemo │ │ ├── MainActivity.kt │ │ └── SignInActivity.kt │ └── res │ ├── layout │ ├── activity_main.xml │ └── activity_sign_in.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── authmanager ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── github │ └── charbgr │ └── authmanager │ ├── AuthManager.kt │ ├── AuthManagerCodes.kt │ ├── GoogleAuthManager.kt │ ├── HintsManager.kt │ ├── SmartLockManager.kt │ ├── models │ └── SuccessPayload.java │ └── views │ ├── BaseView.kt │ ├── GoogleView.kt │ ├── HintView.kt │ └── SmartLockView.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | 38 | # Keystore files 39 | *.jks 40 | *.iml 41 | /.idea/ 42 | .idea/ 43 | .gradle 44 | /local.properties 45 | /.idea/workspace.xml 46 | /.idea/libraries 47 | .DS_Store 48 | /build 49 | /captures 50 | .externalNativeBuild 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Pavlos-Petros Tournaris 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-AuthManager-brightgreen.svg?style=flat)]() 2 | 3 | # Auth Manager 4 | 5 | AuthManager is a library which eliminates the boilerplate of Google SignIn and SmartLock integration. 6 | 7 | # Usage 8 | 9 | ```groovy 10 | compile 'com.github.charbgr:authmanager:1.0' 11 | ``` 12 | 13 |
14 | AuthManager includes all of the managers below. 15 | 16 | ```kotlin 17 | AuthManager 18 | .Builder(this) 19 | .withGoogleApiClient(googleApiClient) 20 | .withGoogle(this) 21 | .withHints(this, hintRequest) 22 | .withSmartLock(this, smartlockRequest) 23 | .build() 24 | 25 | override fun onDestroy() { 26 | super.onDestroy() 27 | authManager.destroy() 28 | } 29 | 30 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 31 | super.onActivityResult(requestCode, resultCode, data) 32 | authManager?.handle(requestCode, resultCode, data) 33 | } 34 | 35 | ``` 36 | 37 | # Standalone Managers 38 | 39 | ## Google Manager 40 | _Functionality included: Google Sign-In, Google Sign-Out, Google Revoke Access_ 41 | 42 | ```kotlin 43 | GoogleAuthManager 44 | .Builder(this) 45 | .withGoogleApiClient(googleApiClient) 46 | .withGoogleView(this) 47 | .build() 48 | 49 | override fun onDestroy() { 50 | super.onDestroy() 51 | googleAuthManager?.clear() 52 | } 53 | 54 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 55 | super.onActivityResult(requestCode, resultCode, data) 56 | when (requestCode) { 57 | RC_SIGN_IN -> googleAuthManager?.handle(resultCode, data) 58 | } 59 | } 60 | ``` 61 | 62 | ### API Overview 63 | 64 | ```kotlin 65 | fun signInWithGoogle() 66 | fun signOutOfGoogle() 67 | fun revokeGoogleAccess() 68 | fun handle(resultCode: Int, data: Intent?) 69 | fun clear() 70 | ``` 71 | 72 | ## Smartlock Manager 73 | _Functionality included: SmartLock Credentials Request, SmartLock Credentials Save, SmartLock Credentials Delete_ 74 | 75 | ```kotlin 76 | SmartLockManager 77 | .Builder(this) 78 | .withGoogleApiClient(googleApiClient) 79 | .withSmartLockView(this) 80 | .build() 81 | 82 | 83 | override fun onDestroy() { 84 | super.onDestroy() 85 | smartLockManager?.clear() 86 | } 87 | 88 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 89 | super.onActivityResult(requestCode, resultCode, data) 90 | when (requestCode) { 91 | RC_CREDENTIAL_SAVE -> smartLockManager?.handleCredentialSave(resultCode) 92 | RC_CREDENTIALS_REQUEST -> smartLockManager?.handleCredentialRequest(resultCode, data) 93 | } 94 | } 95 | ``` 96 | ### API Overview 97 | 98 | ```kotlin 99 | fun requestCredentials() 100 | fun saveCredential(credential: Credential) 101 | fun deleteCredential(credential: Credential?) 102 | fun handleCredentialSave(resultCode: Int) 103 | fun handleCredentialRequest(resultCode: Int, data: Intent?) 104 | fun clear() 105 | ``` 106 | 107 | ## Hints Manager 108 | _Functionality included: E-mail Addresses Hints_ 109 | 110 | ```kotlin 111 | HintsManager 112 | .Builder(this) 113 | .withGoogleApiClient(googleApiClient) 114 | .withHintsView(this) 115 | .build() 116 | 117 | 118 | override fun onDestroy() { 119 | super.onDestroy() 120 | hintsManager?.clear() 121 | } 122 | 123 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 124 | super.onActivityResult(requestCode, resultCode, data) 125 | when (requestCode) { 126 | RC_HINT_REQUEST -> hintsManager?.handle(resultCode, data) 127 | } 128 | } 129 | ``` 130 | ### API Overview 131 | 132 | ```kotlin 133 | fun requestEmailHints() 134 | fun handle(resultCode: Int, data: Intent?) 135 | fun clear() 136 | ``` 137 | 138 | You need to call in ```Activity.onDestroy()``` to clear view references otherwise you risk having a memory leak. 139 | 140 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | compileSdkVersion 25 6 | buildToolsVersion "25.0.1" 7 | defaultConfig { 8 | applicationId "com.github.pavlospt.signindemo" 9 | minSdkVersion 21 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(include: ['*.jar'], dir: 'libs') 25 | compile 'com.android.support:appcompat-v7:25.1.0' 26 | compile 'com.android.support:design:25.1.0' 27 | compile 'com.google.android.gms:play-services-auth:10.0.1' 28 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 29 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 30 | exclude group: 'com.android.support', module: 'support-annotations' 31 | }) 32 | testCompile 'junit:junit:4.12' 33 | compile project(path: ':authmanager') 34 | } -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "1071636679426", 4 | "project_id": "ac-schedule" 5 | }, 6 | "client": [ 7 | { 8 | "client_info": { 9 | "mobilesdk_app_id": "1:1071636679426:android:988a70013241dfe3", 10 | "android_client_info": { 11 | "package_name": "com.github.pavlospt.signindemo" 12 | } 13 | }, 14 | "oauth_client": [ 15 | { 16 | "client_id": "1071636679426-2uv97ohle2q838i0dpv6j4bqblgncp06.apps.googleusercontent.com", 17 | "client_type": 1, 18 | "android_info": { 19 | "package_name": "com.github.pavlospt.signindemo", 20 | "certificate_hash": "2968F8DCC4C9A51B7A2D2AD8F90970BAE780CBD0" 21 | } 22 | }, 23 | { 24 | "client_id": "1071636679426-bulvu8g7mq2goir8t6vmgvr5icjv26r9.apps.googleusercontent.com", 25 | "client_type": 3 26 | } 27 | ], 28 | "api_key": [ 29 | { 30 | "current_key": "AIzaSyCJ9W7RZIlO7a3rbH2zGwI7i_VHc9_Hvag" 31 | } 32 | ], 33 | "services": { 34 | "analytics_service": { 35 | "status": 1 36 | }, 37 | "appinvite_service": { 38 | "status": 1, 39 | "other_platform_oauth_client": [] 40 | }, 41 | "ads_service": { 42 | "status": 1 43 | } 44 | } 45 | } 46 | ], 47 | "configuration_version": "1" 48 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/pavlostournaris/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/pavlospt/signindemo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.pavlospt.signindemo 2 | 3 | import android.content.Intent 4 | import android.support.v7.app.AppCompatActivity 5 | import android.os.Bundle 6 | import android.widget.TextView 7 | 8 | class MainActivity : AppCompatActivity() { 9 | 10 | companion object { 11 | @JvmField 12 | val USER_EMAIL_KEY: String = "user-email-key" 13 | 14 | @JvmStatic 15 | fun startActivity(activity: AppCompatActivity, userEmail: String?) { 16 | val intent: Intent = Intent(activity, MainActivity::class.java) 17 | intent.putExtra(USER_EMAIL_KEY, userEmail) 18 | activity.startActivity(intent) 19 | } 20 | } 21 | 22 | private lateinit var userEmailTextView: TextView 23 | 24 | private val userEmail: String by lazy { 25 | intent.getStringExtra(USER_EMAIL_KEY) 26 | } 27 | 28 | override fun onCreate(savedInstanceState: Bundle?) { 29 | super.onCreate(savedInstanceState) 30 | setContentView(R.layout.activity_main) 31 | 32 | initViews() 33 | initData() 34 | } 35 | 36 | private fun initData() { 37 | userEmailTextView.text = userEmail 38 | } 39 | 40 | private fun initViews() { 41 | userEmailTextView = findViewById(R.id.user_email_text_view) as TextView 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/pavlospt/signindemo/SignInActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.pavlospt.signindemo 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.support.design.widget.TextInputLayout 6 | import android.support.v7.app.AlertDialog 7 | import android.support.v7.app.AppCompatActivity 8 | import android.util.Log 9 | import android.widget.Button 10 | import android.widget.Toast 11 | import com.github.charbgr.authmanager.AuthManager 12 | import com.github.charbgr.authmanager.models.SuccessPayload 13 | import com.github.charbgr.authmanager.views.GoogleView 14 | import com.github.charbgr.authmanager.views.HintView 15 | import com.github.charbgr.authmanager.views.SmartLockView 16 | import com.google.android.gms.auth.api.Auth 17 | import com.google.android.gms.auth.api.credentials.Credential 18 | import com.google.android.gms.auth.api.credentials.CredentialPickerConfig 19 | import com.google.android.gms.auth.api.credentials.CredentialRequest 20 | import com.google.android.gms.auth.api.credentials.HintRequest 21 | import com.google.android.gms.auth.api.signin.GoogleSignInOptions 22 | import com.google.android.gms.common.ConnectionResult 23 | import com.google.android.gms.common.SignInButton 24 | import com.google.android.gms.common.api.GoogleApiClient 25 | import com.google.android.gms.common.api.Status 26 | 27 | 28 | class SignInActivity : AppCompatActivity(), 29 | GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, 30 | GoogleView, SmartLockView, HintView { 31 | 32 | private var authManager: AuthManager? = null 33 | 34 | /* 35 | * Views 36 | * */ 37 | private lateinit var signInButton: SignInButton 38 | private lateinit var signOutButton: Button 39 | private lateinit var revokeAccessButton: Button 40 | private lateinit var requestHintsButton: Button 41 | private lateinit var requestUserCredentials: Button 42 | private lateinit var saveCredentialsButton: Button 43 | private lateinit var emailAddressTextInput: TextInputLayout 44 | private lateinit var passwordTextInput: TextInputLayout 45 | 46 | override fun onCreate(savedInstanceState: Bundle?) { 47 | super.onCreate(savedInstanceState) 48 | 49 | setContentView(R.layout.activity_sign_in) 50 | 51 | initViews() 52 | initAuthManager() 53 | } 54 | 55 | private fun initViews() { 56 | saveCredentialsButton = findViewById(R.id.save_credentials_button) as Button 57 | requestUserCredentials = findViewById(R.id.request_user_credentials_button) as Button 58 | requestHintsButton = findViewById(R.id.request_hints_button) as Button 59 | 60 | signInButton = findViewById(R.id.sign_in_button) as SignInButton 61 | signOutButton = findViewById(R.id.sign_out_google) as Button 62 | revokeAccessButton = findViewById(R.id.revoke_access_button) as Button 63 | 64 | emailAddressTextInput = findViewById(R.id.email_address_text_input) as TextInputLayout 65 | passwordTextInput = findViewById(R.id.password_text_input) as TextInputLayout 66 | 67 | emailAddressTextInput.clearFocus() 68 | passwordTextInput.clearFocus() 69 | 70 | signInButton.setSize(SignInButton.SIZE_WIDE) 71 | 72 | requestUserCredentials.setOnClickListener { 73 | authManager?.requestCredential() 74 | } 75 | 76 | requestHintsButton.setOnClickListener { 77 | authManager?.requestEmailHints() 78 | } 79 | 80 | signInButton.setOnClickListener { 81 | authManager?.signInWithGoogle() 82 | } 83 | 84 | signOutButton.setOnClickListener { 85 | authManager?.signOutOfGoogle() 86 | } 87 | 88 | revokeAccessButton.setOnClickListener { 89 | authManager?.revokeGoogleAccess() 90 | } 91 | 92 | saveCredentialsButton.setOnClickListener { 93 | saveCredentials() 94 | } 95 | } 96 | 97 | //region Initializations 98 | 99 | private fun initAuthManager() { 100 | val googleApiClient = createGoogleApiClient() 101 | val hintRequest = createHintRequest() 102 | val smartlockRequest = createSmartlockCredentialsRequest() 103 | 104 | authManager = AuthManager 105 | .Builder(this) 106 | .withGoogleApiClient(googleApiClient) 107 | .withGoogle(this) 108 | .withHints(this, hintRequest) 109 | .withSmartLock(this, smartlockRequest) 110 | .build() 111 | } 112 | 113 | /* 114 | * Initialize Hint request 115 | * */ 116 | private fun createHintRequest() = HintRequest.Builder() 117 | .setHintPickerConfig( 118 | CredentialPickerConfig.Builder() 119 | .setShowCancelButton(true) 120 | .setPrompt(CredentialPickerConfig.Prompt.SIGN_IN) 121 | .build() 122 | ) 123 | .setEmailAddressIdentifierSupported(true) 124 | .build() 125 | 126 | /* 127 | * Initialize Google Sign-in options 128 | * */ 129 | private fun createGoogleSignInOptions() = GoogleSignInOptions 130 | .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 131 | .requestEmail() 132 | .build() 133 | 134 | /* 135 | * Initialize Smartlock credentials request 136 | * */ 137 | private fun createSmartlockCredentialsRequest() = CredentialRequest.Builder() 138 | .setPasswordLoginSupported(true) 139 | .build() 140 | 141 | /* 142 | * Initialize Google API Client 143 | * */ 144 | private fun createGoogleApiClient() = GoogleApiClient.Builder(this) 145 | .addConnectionCallbacks(this) 146 | .enableAutoManage(this, this) 147 | .addApi(Auth.GOOGLE_SIGN_IN_API, createGoogleSignInOptions()) 148 | .addApi(Auth.CREDENTIALS_API) 149 | .build() 150 | 151 | //endregion 152 | 153 | //region GoogleSignIn 154 | 155 | /* 156 | * Google Sign-In Failure 157 | * */ 158 | override fun googleSignInResultFailure() { 159 | Toast.makeText(this, "Authentication failure", Toast.LENGTH_SHORT).show() 160 | } 161 | 162 | /* 163 | * User Cancelled Google Sign-In 164 | * */ 165 | override fun userCancelledGoogleSignIn() { 166 | Toast.makeText(this, "User cancelled Google Sign-In flow", Toast.LENGTH_SHORT).show() 167 | } 168 | //endregion 169 | 170 | //region CredentialsRequest 171 | 172 | 173 | /* 174 | * Credential Request Cancelled 175 | * */ 176 | override fun credentialRequestCancelled() { 177 | Toast.makeText(this, "Credential Request cancelled", Toast.LENGTH_SHORT).show() 178 | } 179 | 180 | /* 181 | * Credential Request Resolution Failed 182 | * */ 183 | override fun credentialRequestResolutionFailure() { 184 | Toast.makeText(this, "Credential Request Resolution failure", Toast.LENGTH_SHORT).show() 185 | } 186 | 187 | /* 188 | * Credential Request Failed 189 | * */ 190 | override fun credentialRequestFailure() { 191 | Toast.makeText(this, "Credential Request failure", Toast.LENGTH_SHORT).show() 192 | } 193 | 194 | //endregion 195 | 196 | /* 197 | * Hint Request Cancelled 198 | * */ 199 | override fun emailHintRequestCancelled() { 200 | Toast.makeText(this, "Hint Request cancelled by user", Toast.LENGTH_SHORT).show() 201 | } 202 | 203 | /* 204 | * Hint Request Failed 205 | * */ 206 | override fun emailHintRequestFailure() { 207 | Toast.makeText(this, "Hint Request failure", Toast.LENGTH_SHORT).show() 208 | } 209 | 210 | //endregion 211 | 212 | //region CredentialsSave 213 | 214 | /* 215 | * Initiate Credential save flow 216 | * */ 217 | private fun saveCredentials() { 218 | 219 | val emailInvalid: Boolean = emailAddressTextInput.editText?.text.toString().trim().isNullOrEmpty() ?: false 220 | val passwordInvalid: Boolean = passwordTextInput.editText?.text.toString().trim().isNullOrEmpty() ?: false 221 | 222 | if (emailInvalid) { 223 | emailRequirementError() 224 | return 225 | } 226 | 227 | if (passwordInvalid) { 228 | passwordRequirementError() 229 | return 230 | } 231 | 232 | val credentialToSave: Credential = 233 | Credential 234 | .Builder(emailAddressTextInput.editText?.text.toString()) 235 | .setPassword(passwordTextInput.editText?.text.toString().trim()) 236 | .build() 237 | 238 | authManager?.saveCredential(credentialToSave) 239 | } 240 | 241 | /* 242 | * User Cancelled Credential Save Resolution 243 | * */ 244 | override fun credentialSaveResolutionCancelled() { 245 | Toast.makeText(this, "User cancelled credential save resolution", Toast.LENGTH_SHORT).show() 246 | } 247 | 248 | /* 249 | * Credential Save Resolution Failed 250 | * */ 251 | override fun credentialSaveResolutionFailure() { 252 | Toast.makeText(this, "Credential save resolution failed", Toast.LENGTH_SHORT).show() 253 | } 254 | 255 | /* 256 | * Credential Save Failed 257 | * */ 258 | override fun credentialSaveFailure() { 259 | Toast.makeText(this, "Credential save failed", Toast.LENGTH_SHORT).show() 260 | } 261 | 262 | /* 263 | * Credential Save Success 264 | * */ 265 | override fun credentialSaveSuccess() { 266 | Toast.makeText(this, "Credentials successfully saved", Toast.LENGTH_SHORT).show() 267 | } 268 | 269 | /* 270 | * Require Email Address Not Empty 271 | * */ 272 | private fun emailRequirementError() { 273 | Toast.makeText(this, "Email address must not be empty", Toast.LENGTH_SHORT).show() 274 | } 275 | 276 | /* 277 | * Require Password Not Empty 278 | * */ 279 | private fun passwordRequirementError() { 280 | Toast.makeText(this, "Password must not be empty", Toast.LENGTH_SHORT).show() 281 | } 282 | //endregion 283 | 284 | override fun emailHintSelected(credential: Credential?) { 285 | MainActivity.startActivity(this, credential?.id) 286 | } 287 | 288 | override fun signInSuccess(signInSuccess: SuccessPayload) { 289 | if (signInSuccess.hasCredential()) { 290 | showCredentialDialog(signInSuccess.credential) 291 | } else if (signInSuccess.hasGoogleSignInAccount()) { 292 | MainActivity.startActivity(this, signInSuccess.googleSignInAccount.email) 293 | } 294 | } 295 | 296 | private fun showCredentialDialog(credential: Credential?) { 297 | val alertDialogBuilder: AlertDialog.Builder = AlertDialog 298 | .Builder(this) 299 | .setTitle(R.string.credential_received) 300 | .setMessage(getString(R.string.what_do_you_want_to_do_with_credential, credential?.id)) 301 | .setPositiveButton(getString(R.string.use_credential), { dialogInterface, i -> 302 | MainActivity.startActivity(this@SignInActivity, credential?.id) 303 | }) 304 | .setNegativeButton(getString(R.string.delete_credential), { dialogInterface, i -> 305 | authManager?.deleteCredential(credential) 306 | dialogInterface.dismiss() 307 | dialogInterface.cancel() 308 | }) 309 | 310 | val alertDialog: AlertDialog = alertDialogBuilder.create() 311 | alertDialog.show() 312 | } 313 | 314 | override fun googleSignOut(status: Status) { 315 | Toast.makeText(this, "Google Sign-out with status: $status", Toast.LENGTH_SHORT).show() 316 | } 317 | 318 | override fun googleAccessRevoked(status: Status) { 319 | Toast.makeText(this, "Google Access Revoked with status: $status", Toast.LENGTH_SHORT).show() 320 | } 321 | 322 | 323 | override fun credentialDelete(status: Status) { 324 | Toast.makeText(this, "Credential deleted with status: $status", Toast.LENGTH_SHORT).show() 325 | } 326 | 327 | /* 328 | * Google API Connection Failed 329 | * */ 330 | override fun onConnectionFailed(p0: ConnectionResult) { 331 | Log.e(localClassName, "GoogleApiClient connection failed") 332 | } 333 | 334 | /* 335 | * Google API Connection Connected 336 | * */ 337 | override fun onConnected(p0: Bundle?) { 338 | Log.e(localClassName, "GoogleApiClient connected") 339 | } 340 | 341 | /* 342 | * Google API Connection Suspended 343 | * */ 344 | override fun onConnectionSuspended(p0: Int) { 345 | Log.e(localClassName, "GoogleApiClient connection suspended") 346 | } 347 | 348 | /* 349 | * Handle activity result after Google Sign-In, Credential Request or Hints requested resolution 350 | * */ 351 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 352 | super.onActivityResult(requestCode, resultCode, data) 353 | authManager?.handle(requestCode, resultCode, data) 354 | } 355 | 356 | override fun onDestroy() { 357 | super.onDestroy() 358 | authManager?.destroy() 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_sign_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 21 | 22 | 27 | 28 | 29 | 30 | 34 | 35 | 40 | 41 | 42 | 43 |