已经使用id 0pipe理GoogleApiClient在FRAGMENT中

一切正常,如果你第二次去这个片段接收错误。 我试图把null,如果查看,但不能改变任何东西。 码:

public class Login extends Fragment implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { private static final String TAG = "SignInActivity"; private static final int RC_SIGN_IN = 9001; private GoogleApiClient mGoogleApiClient; private TextView mStatusTextView; private ProgressDialog mProgressDialog; private static String url; private static View view; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (view != null) { ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) parent.removeView(view); } try { view = inflater.inflate(R.layout.activity_login, container, false); // Views mStatusTextView = (TextView) view.findViewById(R.id.status); // Button listeners view.findViewById(R.id.sign_in_button).setOnClickListener(this); view.findViewById(R.id.sign_out_button).setOnClickListener(this); view.findViewById(R.id.disconnect_button).setOnClickListener(this); // [START configure_signin] // Configure sign-in to request the user's ID, email address, and basic // profile. ID and basic profile are included in DEFAULT_SIGN_IN. GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build(); // [END configure_signin] // [START build_client] // Build a GoogleApiClient with access to the Google Sign-In API and the // options specified by gso. mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity()/* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); // [END build_client] // [START customize_button] // Customize sign-in button. The sign-in button can be displayed in // multiple sizes and color schemes. It can also be contextually // rendered based on the requested scopes. For example. a red button may // be displayed when Google+ scopes are requested, but a white button // may be displayed when only basic profile is requested. Try adding the // Scopes.PLUS_LOGIN scope to the GoogleSignInOptions to see the // difference. SignInButton signInButton = (SignInButton) view.findViewById(R.id.sign_in_button); signInButton.setSize(SignInButton.SIZE_STANDARD); signInButton.setScopes(gso.getScopeArray()); // [END customize_button] } catch (InflateException e) { /* map is already there, just return view as it is */ } super.onCreate(savedInstanceState); return view; } @Override public void onStart() { super.onStart(); OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); if (opr.isDone()) { // If the user's cached credentials are valid, the OptionalPendingResult will be "done" // and the GoogleSignInResult will be available instantly. Log.d(TAG, "Got cached sign-in"); GoogleSignInResult result = opr.get(); handleSignInResult(result); } else { // If the user has not previously signed in on this device or the sign-in has expired, // this asynchronous branch will attempt to sign in the user silently. Cross-device // single sign-on will occur in this branch. showProgressDialog(); opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { @Override public void onResult(GoogleSignInResult googleSignInResult) { //adaugat de mine sa porneacsa singur cererea de logare signIn(); //fin hideProgressDialog(); handleSignInResult(googleSignInResult); } }); } } // [START onActivityResult] @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); handleSignInResult(result); } } // [END onActivityResult] // [START handleSignInResult] private void handleSignInResult(GoogleSignInResult result) { Log.d(TAG, "handleSignInResult:" + result.isSuccess()); if (result.isSuccess()) { // Signed in successfully, show authenticated UI. GoogleSignInAccount acct = result.getSignInAccount(); mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName() + " Your token " + acct.getId())); url = "http://grupovrt.ddns.net:81/index.php?token="+acct.getId(); updateUI(true); } else { // Signed out, show unauthenticated UI. updateUI(false); } } // [END handleSignInResult] // [START signIn] private void signIn() { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } // [END signIn] // [START signOut] private void signOut() { Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status status) { // [START_EXCLUDE] updateUI(false); // [END_EXCLUDE] } }); } // [END signOut] // [START revokeAccess] private void revokeAccess() { Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status status) { // [START_EXCLUDE] updateUI(false); // [END_EXCLUDE] } }); } // [END revokeAccess] @Override public void onConnectionFailed(ConnectionResult connectionResult) { // An unresolvable error has occurred and Google APIs (including Sign-In) will not // be available. Log.d(TAG, "onConnectionFailed:" + connectionResult); } private void showProgressDialog() { if (mProgressDialog == null) { mProgressDialog = new ProgressDialog(getActivity()); mProgressDialog.setMessage(getString(R.string.loading)); mProgressDialog.setIndeterminate(true); } mProgressDialog.show(); } private void hideProgressDialog() { if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.hide(); } } private void updateUI(boolean signedIn) { if (signedIn) { getView().findViewById(R.id.sign_in_button).setVisibility(View.GONE); getView().findViewById(R.id.sign_out_and_disconnect).setVisibility(View.VISIBLE); } else { mStatusTextView.setText(R.string.signed_out); getView().findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE); getView().findViewById(R.id.sign_out_and_disconnect).setVisibility(View.GONE); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.sign_in_button: signIn(); break; case R.id.sign_out_button: signOut(); break; case R.id.disconnect_button: revokeAccess(); break; } } } 

日志:

 FATAL EXCEPTION: main Process: ro.vrt.videoplayerstreaming, PID: 23662 java.lang.IllegalStateException: Already managing a GoogleApiClient with id 0 at com.google.android.gms.common.internal.zzx.zza(Unknown Source) at com.google.android.gms.common.api.internal.zzw.zza(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.zza(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.zze(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source) at ro.vrt.videoplayerstreaming.Login.onCreateView(Login.java:75) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5849) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:763) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653) 

据我了解,问题来自这里

  mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity()/* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); 

我试图把0,但仍然无法正常工作。

 .enableAutoManage(getActivity(), 0 /* FragmentActivity */, this /* OnConnectionFailedListener */) 

我能做什么 ? 谢谢。

您可以尝试在onPuase()或片段的任何其他生命周期事件中调用stopAutoManage()

 @Override public void onPause() { super.onPause(); mGoogleClient.stopAutoManage(getActivity()); mGoogleClient.disconnect(); } 

您也应该在片段的onPause()方法中添加对stopAutoManage()的调用:

 @Override public void onPause() { super.onPause(); mGoogleApiClient.stopAutoManage(getActivity()); mGoogleApiClient.disconnect(); } 

避免进一步的问题

 @Override public void onStop() { super.onStop(); if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { mGoogleApiClient.stopAutoManage((Activity) context); mGoogleApiClient.disconnect(); } } 

enableAutoManage官方文档说:

在任何时候,每个ID只允许一个自动pipe理的客户端。 要重用一个id,你必须先在前一个客户端上调用stopAutoManage(FragmentActivity)。

你的代码使用enableAutoManage的版本,没有一个clientId参数,所以它默认为0.下面我解释为什么你将有多个自动pipe理的客户端clientId 0,这是上面的文档是警告。

在您的Login Fragment附加到FragmentActivity后,它会告知该活动开始pipe理一个新的GoogleApiClient实例。 但是,如果FragmentActivity已经在pipe理另一个GoogleApiClient实例呢? 那是当你得到错误。

有几个可能的情况,可能导致这个多谷歌API每个FragmentActivity情况。

  • 除了创buildGoogleApiClient的Login之外,FragmentActivity还有另外一个片段,并且要求FragmentActivity来pipe理它。
  • FragmentActivity本身创build一个GoogleApiClient并在Login Fragment附加到FragmentActivity之前开始pipe理它。
  • 也许你在FragmentTransaction中添加Login Fragment,然后调用addToBackStack。 然后,用户轻点,然后以某种方式login片段重新连接。 在这种情况下,重要的Login Activity方法调用是onCreateView – > onDestroyView – > onCreateView,如下所示:

    片段生命周期图

这是有问题的,因为第二次调用Login.onCreateView试图让FragmentActivitypipe理第二个GoogleApiClient。

如果我是你,我会认真考虑在活动中创buildGoogleApiClient,而不是在任何片段中。 然后,您可以在Activity中执行需要GoogleApiClient的工作,或者在从Activity获取GoogleApiClient之后继续在Login Fragment中执行此操作,如下所示:

 private GoogleApiClient googleApiClient; @Override void onAttach(Activity activity) { super.onAttach(activity); googleApiClient = activity.getGoogleApiClient(); } @Override void onDetach() { super.onDetach(); googleApiClient = null; } 

我遇到了类似的问题,因为我已经在属于同一个Activity的两个不同片段上放置了loginbutton。

所以为了解决这个问题,我在创buildGoogleApiClient的新对象时分配了不同的id来启用 AutoManage。

例如,在片段1中,在创buildGoogleApiClient对象时, 赋值为0

 mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity(), 0, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); 

在Fragment 2中,在创buildGoogleApiClient对象时, id 赋值为1,如下所示:

 mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity(), 1, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); 

尝试从您的活动中使用您的mGoogleApiClient 。 如果您已经在您的活动中声明了GoogleApiClient ,那么您无法在您的片段上重新声明。 而是从片段中重新使用该活动中的variables

 mGoogleApiClientInFragment = ((Youractivityclass)getActivity()).mGoogleApiClient; 

用您的片段的活动replaceYouractivityClass ,并确保将您的活动中的mGoogleApiClient字段设置为公开