Android: How to resolve Google API connection fail from a Service?

匿名 (未验证) 提交于 2019-12-03 03:06:01

问题:

here is the code provided by the official guide, while this is a snippet causing problems.

@Override public void onConnectionFailed(ConnectionResult result) {     if (mResolvingError) {         // Already attempting to resolve an error.         return;     } else if (result.hasResolution()) {         try {             mResolvingError = true;             result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);         } catch (IntentSender.SendIntentException e) {             // There was an error with the resolution intent. Try again.             mGoogleApiClient.connect();         }     } else {         // Show dialog using GooglePlayServicesUtil.getErrorDialog()         mResolvingError = true;         GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, REQUEST_RESOLVE_ERROR)                 .setOnDismissListener(new DialogInterface.OnDismissListener() {                     @Override                     public void onDismiss(DialogInterface dialog) {                         mResolvingError = false;                     }                 });     } } 

If I use it in a Service, when you read the variable this passed as argument to those functions, they expect an Activity type. How should I do? It's a Service.

For the same reason I can't get activity result

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_RESOLVE_ERROR) {     mResolvingError = false;     if (resultCode == RESULT_OK) {         // Make sure the app is not already connected or attempting to connect         if (!mGoogleApiClient.isConnecting() &&                 !mGoogleApiClient.isConnected()) {             mGoogleApiClient.connect();         }     } } } 

回答1:

This answer assumes your service is a "started" service. If it is a bound service or intent service, indicate that in a comment and I'll update the description and code included here.

The solution I suggest is to implement the activity shown below to handle the resolution UI. Replace the onConnectionFailed() method in your service with this code to hand off the resolution processing to the ResolverActivity:

@Override public void onConnectionFailed(ConnectionResult result) {     Intent i = new Intent(this, ResolverActivity.class);     i.putExtra(ResolverActivity.CONNECT_RESULT_KEY, result);     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);     startActivity(i); } 

Add the activity shown below to your app. When the connection request in your service fails, the connection result, which is a Parcelable, is passed to the activity. The activity handles the resolution UI and when finished, returns the status to the service as an intent extra. You will need to modify the code in your service's onStartCommand() to examine the extras in the intent to determine if it is being called to start the service for the first time, or to receive resolution status from the ResolverActivity.

An enhancement to this approach would be to post a notification with a PendingIntent for ResolverActivity instead of launching the activity immediately. That would give the user the option of deferring resolution of the connection failure.

public class ResolverActivity extends AppCompatActivity {     public static final String TAG = "ResolverActivity";      public static final String CONNECT_RESULT_KEY = "connectResult";      public static final String CONN_STATUS_KEY = "connectionStatus";     public static final int CONN_SUCCESS = 1;     public static final int CONN_FAILED  = 2;     public static final int CONN_CANCELLED = 3;      // Request code to use when launching the resolution activity     private static final int REQUEST_RESOLVE_ERROR = 1111;      private static final String ERROR_CODE_KEY = "errorCode";     private static final String DIALOG_FRAG_TAG = "errorDialog";      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);          Log.i(TAG, "onCreate()");          // No content needed.         //setContentView(R.layout.activity_main);          Intent i = getIntent();          ConnectionResult result = i.getParcelableExtra(CONNECT_RESULT_KEY);          if (result.hasResolution()) {             try {                 Log.i(TAG, "Starting error resolution...");                 result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);             } catch (IntentSender.SendIntentException e) {                 // There was an error with the resolution intent.                 sendStatusToService(CONN_FAILED);                 finish();             }         } else {             // Show dialog using GooglePlayServicesUtil.getErrorDialog()             ErrorDialogFragment.newInstance(result.getErrorCode())                     .show(getSupportFragmentManager(), DIALOG_FRAG_TAG);         }     }      @Override     public void onActivityResult(int requestCode, int resultCode, Intent result) {          if (requestCode == REQUEST_RESOLVE_ERROR) {             if (resultCode == RESULT_OK) {                 Log.i(TAG, "onActivityResult(): Connection problem resolved");                 sendStatusToService(CONN_SUCCESS);             } else {                 sendStatusToService(CONN_CANCELLED);                 Log.w(TAG, "onActivityResult(): Resolution cancelled");             }             // Nothing more to do in this activity             finish();         }     }      private void sendStatusToService(int status) {         Intent i = new Intent(this, MyGoogleApiService.class);         i.putExtra(CONN_STATUS_KEY, status);         startService(i);     }      // Fragment to display an error dialog     public static class ErrorDialogFragment extends DialogFragment {          public static ErrorDialogFragment newInstance(int errorCode) {             ErrorDialogFragment f = new ErrorDialogFragment();             // Pass the error that should be displayed             Bundle args = new Bundle();             args.putInt(ERROR_CODE_KEY, errorCode);             f.setArguments(args);             return f;         }          @Override         @NonNull         public Dialog onCreateDialog(Bundle savedInstanceState) {             // Get the error code and retrieve the appropriate dialog             int errorCode = getArguments().getInt(ERROR_CODE_KEY);             return GooglePlayServicesUtil.getErrorDialog(                     errorCode, getActivity(), REQUEST_RESOLVE_ERROR);         }          @Override         public void onDismiss(DialogInterface dialog) {             Log.i(TAG, "Dialog dismissed");         }     } } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!