2015-12-15 10 views
13

Ist es möglich, mit Google Drive zu integrieren, ohne die eigene Tätigkeit zu schaffen, anstatt nur die aktuelle Aktivität unter Verwendung von für die Anwendung ohne es mit Google Drive bezogenen Code zu verschmutzen?Google Drive Integration aktuelle Aktivität mit

Ich habe einen Hintergrund "Dienst" (kein Android-Dienst - nur eine UI-Agnostic-Klasse), die für das Laden von Daten aus Google Drive verantwortlich ist. Als Dienstleistung hat es kein wirkliches Geschäft, sondern eine Aktivität. Die samples for Drive integration haben jedoch eine Überschreibung von onActivityResult, um die Situation zu behandeln, in der eine Authentifizierung erforderlich ist. Ich bin nicht sicher, wie ich diese Informationen erhalten würde, wenn mein Dienst nicht als eine Aktivität implementiert wird.

Angenommen, ich kann einen Verweis auf den aktuellen Activity von meinem "Dienst" erhalten, gibt es eine Möglichkeit, die Google Drive-Integration vollständig eigenständig zu implementieren?

+0

tut Ihre App haben Google Plus anmelden –

+0

@war_Hero: um die Anmeldung soll durch die Google Drive API angestiftet werden. Das ist der Punkt meiner Frage - wie gehe ich damit sauber außerhalb des Kontexts einer Aktivität um? –

+0

der Grund, warum ich fragte, war zu wissen, ob Sie g + Login haben, dann Re-Auth ist nicht erforderlich –

Antwort

6

Ich habe etwas Ähnliches aus einer App getan, die eine Aktivität und eine SyncService hat. Sie können tatsächlich eine Menge der Funktionalität in der demo here sehen. Diese Demo verwendet keinen Dienst, aber die Idee bleibt gleich.

1/Erstellen Sie eine Singleton-Klasse (GDAA in diesem Fall) mit einer init() Methode, die Ihren Aktivitätskontext akzeptiert. Diese init() wird ein lokales statisches GoogleApiClient instanziieren, das am Leben bleibt, solange Sie die Konten nicht wechseln müssen (wird später erläutert).
init() ist mit einem Aktivitätskontext zu Beginn oder beim Aufruf gibt es einen Bedarf an ein anderes Benutzerkonto (verschiedene GooDrive für verschiedene Benutzer) zu wechseln. Die Aktivität wird in ihrem Kontext übergeben und liefert onConnFail(), onConnOK() Rückrufe.
Aus Gründen der Vollständigkeit sollte es auch eine Rückstellung für onConnectionSuspended() geben, falls die Verbindung unterbrochen wird (kein WIFI/CELL-Verbindungsabbruch, sondern GooPlaySvcs-Suspendierung).

  • onConnFail() Der Rückruf wird die Steuerung an GooPlaySvcs für Authentifizierung/Autorisierung, deren Ergebnis in onActivityResult() kommt zurück. Schließen Sie wieder, waschen, spülen, wiederholen ...
  • Die onConnOK() Rückruf Ihre Tätigkeit erzählt, dass alles bereit ist.

Als ich darauf hinwies, werden Sie die init() anrufen müssen, um wieder, wenn Sie mehrere Konten GooDrive um behandeln einen neuen GoogleApiClient für ein neues Konto zu erstellen. Folgen Sie einfach dem 'REQ_ACCPICK' Trail here. Sie müssen auch Ihre Konten verwalten, wie Sie in der Account Manager 'AM'-Klasse here sehen können. Die meisten dieser Tänze sind in der MainActivity zu sehen.
Der Vollständigkeit halber sollte ich auch erwähnen, dass Sie die Kontoverwaltung auf GooPlaySvcs verlassen können, indem Sie setAccountName(email) in GoogleApiClient.Builder() weglassen und clearDefaultAccountAndReconnect() verwenden, um die Kontoauswahl zurückzusetzen. Ihre App wird jedoch nicht wissen, wer der aktuelle Benutzer ist. Eine weitere Kontoverwaltung kann mit Hilfe des PlusApi (oder wie auch immer es heißt, nie benutzt) gehandhabt werden. Aber ich schweife ab.

2/Wenn die Initialisierung erfolgt ist und die private static GoogleApiClient mGAC nicht null ist und verbunden, GDAA statische Methoden können von überall in Ihrer Anwendung referenziert werden, mit einem Service. Die Methoden werden sicherlich fehlschlagen, wenn der GoogleApiClient nicht aktiv oder nicht verbunden ist.

In der Demo, die hier erwähnt wird, sind alle GDAA-Aufrufe der 'erwarten()' (sync) Geschmack. Es ist kein Problem, wenn sie von einem Nicht-UI-Thread wie ein Dienst aufgerufen werden. Sie lassen sich leicht in Asynchron-Versionen wie in diesem Beispiel gedreht werden:

DriveFile df = ...; 
// sync version 
DriveContentsResult rslt = df.open(mGAC, DriveFile.MODE_READ_ONLY, null).await(); 
if ((rslt != null) && rslt.getStatus().isSuccess()) { 
    DriveContents cont = rslt.getDriveContents(); 
    InputStream is = cont.getInputStream(); 
    cont.discard(mGAC); // or cont.commit(); they are equiv if READONLY 
} 
// async version 
df.open(mGAC, DriveFile.MODE_READ_ONLY, null).setResultCallback(
    new ResultCallback<DriveContentsResult>() { 
    @Override 
    public void onResult(DriveContentsResult rslt) { 
    if ((rslt != null) && rslt.getStatus().isSuccess()) { 
     DriveContents cont = rslt.getDriveContents(); 
     InputStream is = cont.getInputStream(); 
     cont.discard(mGAC); // or cont.commit(); they are equiv if READONLY 
    } 
    } 
}); 

Der Geschmack hängt von Ihnen App Bedürfnisse (Spaghetti-Code mit verbrauchten Rückgabewerte vs. Asynchron-Verarbeitung).

Es sollte erwähnt werden, dass diese Demo die GDAA Version des Api verwendet. Es gibt auch eine REST Api, die auf die gleiche Weise gehandhabt werden kann (nur sync flavour). Eine alternative Demo, die genau die gleiche Logik und die gleichen Methoden verwendet, ist verfügbar here. Sie können die beiden sogar zu einer Singleton-Klasse kombinieren, wobei sowohlals auch com.google.android.gms.common.api.GoogleApiClient vorhanden sind.

Es ist jedoch gefährlich, die GDAA und die REST API zu mischen, da Sie sicherlich auf Probleme stoßen werden, die durch die Tatsache verursacht werden, dass GDAA nach eigenem Zeitplan synchronisiert, während REST unter Ihrer Kontrolle steht.

Hoffe, es half, viel Glück

6

Der onActivityResult Codepfad verwendet zu erreichen, fordert, wenn ein Authentifizierungsfehler ist Eingreifen des Benutzers erforderlich ist. Somit kann es per definitionem nicht einfach "im Hintergrund" von Ihrem Dienst behandelt werden.

Im Fall von Hintergrund-Service, denke ich, eine geeignete Möglichkeit, Authentifizierung Fehler zu behandeln, ist eine Benachrichtigung mit dem Argument "Sie müssen sich authentifizieren, um fortzufahren". Sie können der Benachrichtigung einen Intent hinzufügen, damit sie Ihre eigene "ResolveAuthActivity" startet, wenn der Benutzer auf die Benachrichtigung tippt. Diese ResolveAuthActivity versucht einfach, eine Verbindung mit der API herzustellen, behebt den Fehler in onConnectionFailed und startet dann die Auflösungsabsicht. Sobald der Fehler behoben ist, kann Ihre ResolveAuthActivity Ihren Dienst veranlassen, erneut eine Verbindung mit der API herzustellen.

+0

Das Beispiel scheint Ihrer ersten Aussage zu widersprechen. Das heißt, es handelt sich um eine _erfolgreiche_ Authentifizierung - nicht um einen Fehler. https://github.com/googledrive/android-demos/blob/master/app/src/main/java/com/google/android/gms/drive/sample/demo/BaseDemoActivity.java#L98 –

+0

Es ist zu handhaben a erfolgreiche Authentifizierung Auflösung * nach * eine vorherige Verbindung fehlgeschlagen. Wenn Sie bemerken, wird REQUEST_CODE_AUTHENTICATION von innen onConnectionFailed gestartet und das onActivityResult wird aufgerufen, sobald REQUEST_CODE_AUTHENTICATION abgeschlossen ist. Der vollständige Code-Ablauf lautet also: 1. Versuchen Sie, eine Verbindung mit GoogleApiClient.connect herzustellen. 2. Wenn die Verbindung fehlgeschlagen ist (d. H. OnConnectionFailed wird aufgerufen), starten Sie die Authentifizierungsauflösung. 3. Behandeln Sie das Ergebnis der Auflösung in onActivityResult. Wenn Sie bei (1) keinen Fehler erhalten, würden Sie den onActivityResult-Flow überhaupt nicht aufrufen. – Prima