2015-07-09 6 views
9

here ist der Code von der offiziellen Anleitung zur Verfügung gestellt, während dies ein Schnipsel ist, das Probleme verursacht.Android: Wie löst man eine Google API-Verbindung, die von einem Dienst fehlschlägt?

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

Wenn ich es in einem Service verwenden, wenn Sie die Variable this geben als Argument für diese Funktionen zu lesen, sie erwarten eine Art Aktivität. Wie soll ich tun? Es ist ein Service.

Aus dem gleichen Grund kann ich nicht bekommen Aktivitätsergebnis

@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

so Ihr Problem ist eine Referenz auf eine Aktivität bekommen ?? Lebendige Aktivitäten im Leben des Dienstes? – Elltz

+0

Welche Art von Service: gestartet, gebunden, Absicht? –

+0

gestartet, während die Aktivität in einem beliebigen Zustand sein konnte – user3290180

Antwort

6

Diese Antwort nimmt an Ihren Dienst ein „gestartet“ Service ist. Wenn es sich um einen gebundenen Service oder einen beabsichtigten Service handelt, geben Sie dies in einem Kommentar an und ich aktualisiere die Beschreibung und den Code, die hier enthalten sind.

Die Lösung, die ich vorschlage, ist, die unten gezeigte Aktivität zu implementieren, um die UI der Auflösung zu behandeln. Ersetzen Sie die onConnectionFailed() Methode in Ihren Dienst mit diesem Code die Auflösung Verarbeitung an die ResolverActivity zu übergeben:

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

Fügen Sie die Aktivität unter Ihrer App angezeigt. Wenn die Verbindungsanforderung in Ihrem Dienst fehlschlägt, wird das Verbindungsergebnis, das eine Parcelable ist, an die Aktivität übergeben. Die Aktivität behandelt die UI für die Auflösung und gibt nach Abschluss den Status als zusätzliche Absicht an den Dienst zurück. Sie müssen den Code in Ihrem Dienst ändern onStartCommand(), um die Extras in der Absicht zu überprüfen, ob es aufgerufen wird, um den Dienst zum ersten Mal zu starten, oder um den Auflösungsstatus von der ResolverActivity zu erhalten.

Eine Verbesserung dieses Ansatzes wäre, eine Benachrichtigung mit PendingIntent für ResolverActivity zu posten, anstatt die Aktivität sofort zu starten. Dies würde dem Benutzer die Möglichkeit geben, die Auflösung des Verbindungsfehlers zu verschieben.

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

Es funktioniert, aber ich habe mResolving boolean wie der Leitfaden sagt, um Wiederholungen von Fehlern zu vermeiden, während immer noch die vorherigen zu lösen. – user3290180

+0

auch zurückkehren FAILED auf Dialog entlassen – user3290180

+0

onActivityResult immer falsch requestCode in meinem Fall können Sie in dieser Hinsicht helfen – ingsaurabh