Из учебника здесь я узнаю, как создать приложение с возможностями входа в Google, и столкнулся с некоторыми проблемами при попытке вернуться из действия navigation-drawer
. Как это работает, так это то, что сначала для входа в систему будет запущен GoogleSigninAcitivity
. После того, как вход будет одобрен, я бы затем запустил действие панели навигации Main2Activity
. Когда щелкнет какой-то конкретный предмет в ящике, я закончу Main2Activity
, вернусь к GoogleSigninAcitivity
и перейду к выходу. Однако в этом случае приложение вылетает, как только я щелкаю элемент ящика, который в этом случае называется nav_share
.
Вот код для GoogleSigninActivity
:
package nus.is3261.kotlinapp
import android.app.Activity
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_google_signin.*
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.common.api.GoogleApiClient
import com.google.firebase.auth.FirebaseAuth
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.ConnectionResult
import com.google.firebase.auth.FirebaseUser
import android.content.Intent
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.firebase.auth.GoogleAuthProvider
class GoogleSigninActivity : AppCompatActivity(), View.OnClickListener, GoogleApiClient.OnConnectionFailedListener {
private val TAG = "JSAGoogleSignIn"
private val REQUEST_CODE_SIGN_IN = 1234
private val REQUEST_CODE_SIGN_OUT = 123
private val WEB_CLIENT_ID = "xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com"
private var mAuth: FirebaseAuth? = null
private var mGoogleApiClient: GoogleApiClient? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_google_signin)
btn_sign_in.setOnClickListener(this)
btn_sign_out.setOnClickListener(this)
btn_disconnect.setOnClickListener(this)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(WEB_CLIENT_ID)
.requestEmail()
.build()
mGoogleApiClient = GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build()
mAuth = FirebaseAuth.getInstance()
}
override fun onStart() {
super.onStart()
// Check if user is signed in (non-null) and update UI accordingly.
val currentUser = mAuth!!.currentUser
updateUI(currentUser)
}
override fun onClick(v: View?) {
val i = v!!.id
when (i) {
R.id.btn_sign_in -> signIn()
R.id.btn_sign_out -> signOut()
R.id.btn_disconnect -> revokeAccess()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent();
if (requestCode == REQUEST_CODE_SIGN_IN) {
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
if (result.isSuccess) {
// successful -> authenticate with Firebase
val account = result.signInAccount
firebaseAuthWithGoogle(account!!)
} else {
// failed -> update UI
updateUI(null)
Toast.makeText(applicationContext, "SignIn: failed!",
Toast.LENGTH_SHORT).show()
}
} else if ((requestCode == REQUEST_CODE_SIGN_OUT)&&(resultCode == Activity.RESULT_OK)){
mGoogleApiClient?.connect()
signOut()
}
}
private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {
Log.e(TAG, "firebaseAuthWithGoogle():" + acct.id!!)
val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
mAuth!!.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success
Log.e(TAG, "signInWithCredential: Success!")
val user = mAuth!!.currentUser
updateUI(user)
} else {
// Sign in fails
Log.w(TAG, "signInWithCredential: Failed!", task.exception)
Toast.makeText(applicationContext, "Authentication failed!",
Toast.LENGTH_SHORT).show()
updateUI(null)
}
}
}
override fun onConnectionFailed(connectionResult: ConnectionResult) {
Log.e(TAG, "onConnectionFailed():" + connectionResult);
Toast.makeText(applicationContext, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}
private fun signIn() {
val intent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient)
startActivityForResult(intent, REQUEST_CODE_SIGN_IN)
}
private fun signOut() {
// sign out Firebase
mAuth!!.signOut()
// sign out Google
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback { updateUI(null) }
}
private fun revokeAccess() {
// sign out Firebase
mAuth!!.signOut()
// revoke access Google
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback { updateUI(null) }
}
private fun updateUI(user: FirebaseUser?) {
if (user != null) {
val myIntent = Intent(this, Main2Activity::class.java)
startActivityForResult(myIntent, REQUEST_CODE_SIGN_OUT)
// tvStatus.text = "Google User email: " + user.email!!
// tvDetail.text = "Firebase User ID: " + user.uid
// btn_sign_in.visibility = View.GONE
// layout_sign_out_and_disconnect.visibility = View.VISIBLE
} else {
tvStatus.text = "Signed Out"
tvDetail.text = null
btn_sign_in.visibility = View.VISIBLE
layout_sign_out_and_disconnect.visibility = View.GONE
}
}
}
Вот откуда я возвращаюсь Main2Activity
:
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
when (item.itemId) {
R.id.nav_basics -> {
basicFragment()
}
R.id.nav_loops -> {
loopFragment()
}
R.id.nav_functions -> {
functionFragment()
}
R.id.nav_chart -> {
}
R.id.nav_share -> {
signOut()
return true
}
}
drawer_layout.closeDrawer(GravityCompat.START)
return true
}
fun signOut(){
drawer_layout.closeDrawer(GravityCompat.START)
val myIntent = Intent()
myIntent.putExtra("SignOut", "SignOut")
setResult(Activity.RESULT_OK, myIntent)
finish()
}
Мне кажется, что я делаю что-то не так, но я не могу понять, где ошибка.
Вот ошибка LogCat, показанная, как только я нажимаю nav_share
: слова, которые обрезаны, говорят GoogleApiCliet is not connected yet