2015-07-09 30 views
9

here to kod dostarczany przez oficjalny przewodnik, a jest to usterka powodująca problemy.Android: jak rozwiązać problem niepowodzenia połączenia interfejsu Google API z usługą?

@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; 
        } 
       }); 
    } 
} 

Jeśli używam go w usługę, kiedy czytasz zmienną this przekazany jako argument do tych funkcji, oni oczekują typu aktywności. Jak mam to zrobić? To usługa.

Z tego samego powodu nie mogę uzyskać wynik aktywności

@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(); 
     } 
    } 
} 
} 
+0

Twój problem polega na uzyskaniu odwołania do działania? w życiu usługi są aktywności również żywe? – Elltz

+0

Jaki rodzaj usługi: rozpoczęty, związany, intencyjny? –

+0

rozpoczęte, gdy aktywność mogła być w jakimkolwiek stanie – user3290180

Odpowiedz

6

Ta odpowiedź zakłada usługa jest „rozpoczął” usługa. Jeśli jest to usługa związana lub zamierzona, zaznacz to w komentarzu, a zaktualizuję opis i kod w tym miejscu.

Rozwiązaniem, które sugeruję, jest zaimplementowanie poniższej czynności do obsługi interfejsu użytkownika rozdzielczości. Wymień metody w usłudze onConnectionFailed() z tego kodu, aby przekazać wyłączyć przetwarzanie rozdzielczości do 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); 
} 

Dodaj aktywności pokazany poniżej do swojej aplikacji. Gdy żądanie połączenia w usłudze nie powiedzie się, wynik połączenia, który jest Parcelable, jest przekazywany do działania. Działanie obsługuje interfejs użytkownika rozdzielczości, a po zakończeniu zwraca stan do usługi jako dodatkowy cel. Konieczne będzie zmodyfikowanie kodu w usłudze onStartCommand() w celu sprawdzenia dodatków w celu określenia, czy jest on wywoływany, aby uruchomić usługę po raz pierwszy, lub aby uzyskać status rozdzielczości od ResolverActivity.

Udoskonaleniem tego podejścia byłoby wysłanie powiadomienia o numerze PendingIntent dla ResolverActivity zamiast natychmiastowego rozpoczęcia działania. Dałoby to użytkownikowi opcję opóźnienia rozwiązania problemu z połączeniem.

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"); 
     } 
    } 
} 
+0

Działa, ale dodałem mResolving boolean, jak mówi przewodnik, aby uniknąć powtórzeń nieudanego rozwiązania, wciąż rozwiązując poprzednie. – user3290180

+0

również zwraca błąd podczas zamykania okna dialogowego – user3290180

+0

onActivityResult zawsze zwraca błędną requestCode w moim przypadku możesz pomóc w tym zakresie – ingsaurabh