OnActivityResult not called after startIntentSende

2019-05-01 10:54发布

问题:

I'm using a launch page to "Sign in with Google". When the user has multiple accounts...after they select which account they wish to sign in with, I'm trying to launch the apps main activity, but for some reason the onActivityResult is never called in my fragment.

Im the Activity, I call onActivityResult and let it call super so that the fragment can handle it, but it never fires.

Any suggestions?

Here is the fragment that is in question:

package com.garciaericn.goodeats.login;

import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.garciaericn.goodeats.R;
import com.garciaericn.goodeats.helpers.CheckConnection;
import com.garciaericn.goodeats.main.FavoritesActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.plus.Plus;

public class LoginFragment extends Fragment implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    public static final String TAG = "com.garciaericn.goodeats.login.LoginFragment.TAG";

    /* Request code used to invoke sign in user interactions. */
    private static final int RC_SIGN_IN = 0;
    private static final int RC_LOGGED_IN = 1034553;
    public static final int RC_SIGN_OUT = 34458392;
    /* Client used to interact with Google APIs. */
    private GoogleApiClient mGoogleApiClient;
    /* A flag indicating that a PendingIntent is in progress and prevents
     * us from starting further intents.
     */
    private boolean mIntentInProgress;
    /* Store the connection result from onConnectionFailed callbacks so that we can
     * resolve them when the user clicks sign-in.
     */
    private ConnectionResult mConnectionResult;
    private boolean mSignInClicked;
    private boolean mSignedIn;
    private CheckConnection checkConnection;

    public LoginFragment() {
    }

    public static LoginFragment getInstance() {
        return new LoginFragment();
    }

    private void signOut() {
        if (mGoogleApiClient.isConnected()) {
            Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
            mGoogleApiClient.disconnect();
            mGoogleApiClient.connect();
            mIntentInProgress = false;
            mSignInClicked = false;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        checkConnection = new CheckConnection(getActivity());
        setHasOptionsMenu(true);

        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Plus.API)
                .addScope(Plus.SCOPE_PLUS_LOGIN)
                .build();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_login, container, false);

        SignInButton signInButton = (SignInButton) view.findViewById(R.id.g_plus_login);
        signInButton.setSize(SignInButton.SIZE_WIDE);
        signInButton.setOnClickListener(this);

        return view;
    }

    @Override
    public void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_sign_out:
                if (mGoogleApiClient.isConnected()) {
                    Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
                    mGoogleApiClient.disconnect();
                    mGoogleApiClient.connect();
                }
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        checkConnection.isConnected();
        switch (v.getId()) {
            case R.id.g_plus_login:
                if (!mGoogleApiClient.isConnected()) {
                    mSignInClicked = true;
                    resolveSignInError();
                }
                break;
            default:
                // If default action is needed.
                break;
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        mSignInClicked = false;
        mSignedIn = true;
        // User is connected


        String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
        Toast.makeText(getActivity(), accountName, Toast.LENGTH_SHORT).show();
        //        String accountID = GoogleAuthUtil.getAccountId(getActivity(), accountName);
        //        try {
        //            accountID = GoogleAuthUtil.getAccountId(getActivity().getApplicationContext(),accountName);
        //        } catch (GoogleAuthException e) {
        //            e.printStackTrace();
        //        } catch (IOException e) {
        //            e.printStackTrace();
        //        }

        //        if (accountID != null) {
        //            // TODO: createLocalAccount() = Store account name and id with DB of restaurants
        //        }


        // Launch main activity
        Intent intent = new Intent(getActivity(), FavoritesActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if (!mIntentInProgress) {
            // Store the ConnectionResult so that we can use it later when the user clicks
            // 'sign-in'.
            mConnectionResult = connectionResult;

            if (mSignInClicked) {
                resolveSignInError();
            }

        }
        checkConnection.isConnected();
        //        if (!checkConnection.isConnected()) {
        //            Toast.makeText(getActivity(), "No network connection", Toast.LENGTH_SHORT).show();
        //        }

    }

    public void resolveSignInError() {
        if (mConnectionResult.hasResolution()) {
            try {
                mIntentInProgress = true;
                getActivity().startIntentSenderForResult(mConnectionResult.getResolution().getIntentSender(), RC_SIGN_IN, null, 0, 0, 0);
            } catch (IntentSender.SendIntentException e) {
                // The intent was canceled before it was sent.  Return to the default
                // state and attempt to connect to get an updated ConnectionResult.
                mIntentInProgress = false;
                mGoogleApiClient.connect();
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RC_SIGN_IN) {
            if (resultCode != Activity.RESULT_OK) {
                mSignInClicked = false;
            }

            mIntentInProgress = false;

            if (!mGoogleApiClient.isConnected()) {
                mGoogleApiClient.connect();
            }
        } else if (requestCode == RC_LOGGED_IN) {
            if (resultCode == RC_SIGN_OUT) {
                signOut();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

回答1:

The key was to call the below method in the first activity.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}


回答2:

Add this in your outer Activity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.change_to_your_id);
  fragment.onActivityResult(requestCode, resultCode, data);
}


回答3:

To properly solve this problem You might use already prepared solution accountPicker.
However - If You want to devise Your own solution - one idea is to start Your second activity (from first activity obviously) with:

Intent intent = this.getIntent();
intent.putExtra(... /* some code that will control second activity */
startActivityForResult(intent, request_code);

and then when activity did all it had to do You allow it to return:

Intent intent = this.getIntent();
intent.putExtra(... /* all needed results to return */ );
this.setResult(RESULT_OK, intent);
finish();

finally it is Your first activity that then gets result in its onActivityResult.