Die App wurde in der "Google API Console" als "installierte Anwendung" registriert - scheint, dass dies die richtige Einstellung für eine Android App ist, nein?Wie richten Sie Google Drive-Anmeldedaten in der Android App ein?
Also ich habe eine Client-ID und keine Secret-ID. Um es klar zu stellen: Es ist keine Web-App und keine Google Drive-App - es ist eine Android-App, die auf andere Nutzerdaten in der Google Drive-Cloud zugreift.
Innerhalb der App hole ich das Konto (funktioniert) und ich fordere ein Token (funktioniert). Jetzt möchte ich mit diesem Token und der Client-ID eine Verbindung zu Google Drive herstellen. Das Ergebnis ist ein "401, ungültiger Berechtigungsnachweis". Was ist mit diesem Code falsch?
public class ActivityMain extends Activity implements DialogInterface.OnClickListener {
// https://developers.google.com/drive/scopes
private static final String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/drive";
// https://code.google.com/apis/console/
private static final String CLIENT_ID = "999999999999999.apps.googleusercontent.com";
private AccountManager accountManager;
private Account[] accounts;
private String authName;
private String authToken;
@Override
public void onClick(final DialogInterface dialogInterface, final int item) {
processAccountSelected(accounts[item]);
}
@Override
public void onCreate(final Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activitymain);
accountManager = AccountManager.get(this);
accounts = accountManager.getAccountsByType("com.google");
if (accounts == null || accounts.length == 0) {
// TODO
} else if (accounts.length == 1) {
processAccountSelected(accounts[0]);
} else if (accounts.length > 1) {
showDialog(MyConstants.DIALOG_ACCOUNTCHOSER);
}
}
@Override
protected Dialog onCreateDialog(final int id) {
switch (id) {
case MyConstants.DIALOG_ACCOUNTCHOSER:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
String[] names = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
names[i] = accounts[i].name;
}
alertDialogBuilder.setItems(names, this);
alertDialogBuilder.setTitle("Select a Google account");
return alertDialogBuilder.create();
}
return null;
}
private void processAccountSelected(final Account account) {
if (account != null) {
authName = account.name.toString();
if (!Tools.isEmpty(authName)) {
Toast.makeText(this, authName, Toast.LENGTH_LONG).show();
accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, null, this,
new AccountManagerCallback<Bundle>() {
public void run(final AccountManagerFuture<Bundle> future) {
try {
authToken = future.getResult().getString(
AccountManager.KEY_AUTHTOKEN);
processTokenReceived();
} catch (OperationCanceledException exception) {
// TODO
} catch (Exception exception) {
Log.d(this.getClass().getName(), exception.getMessage());
}
}
}, null);
}
}
}
private void processListFiles(final Drive drive) {
List<File> result = new ArrayList<File>();
Files.List request = null;
try {
request = drive.files().list();
} catch (IOException exception) {
}
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException exception) {
// --> 401 invalid credentials
}
} while (request.getPageToken() != null && request.getPageToken().length() > 0);
}
private void processTokenReceived() {
if (!Tools.isEmpty(authToken)) {
final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = new GsonFactory();
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(authToken);
Drive drive = new Drive.Builder(transport, jsonFactory, credential)
.setApplicationName(getString(R.string.txt_appname))
.setJsonHttpRequestInitializer(new GoogleKeyInitializer(CLIENT_ID))
.build();
if (drive != null) {
processListFiles(drive);
}
}
}
}
Ich muss sagen, dass dies eine volle Ladung Chaos ist. Es gibt so viele Seiten im Web, die nur Teile anzeigen und es gibt so viele Seiten, die veraltete, fehlende oder andere Methoden verwenden, um dasselbe zu tun. Es gibt meines Erachtens nicht zwei Seiten, die den gleichen Weg zeigen, Daten von Google Drive aus einer Android-App zu erhalten.
Jede Hilfe wird sehr geschätzt.
EDIT: Ich könnte es selbst lösen. Es war eine Kombination von verschiedenen Veränderungen:
- Hat Android zu setzen: minSdkVersion = "11" als Voraussetzung
- haben diese aktuellen Bibliotheken zu verwenden: google-api-client-1.11.0-beta.jar , google-api-client-android-1.11.0-beta.jar, google-api-services-drive-v2-rev9-1.8.0-beta.jar, google-http-client-1.11.0-beta.jar , google-http-client-android-1.11.0-beta.jar, google-http-client-gson-1.11.0-beta.jar, google-http-client-jackson2-1.11.0-beta.jar, google -oauth-client-1.11.0-beta.jar, Gson-2.1.jar, Guave-11.0.1.jar, Jackson-core-2.0.5.jar, jsr305-1.3.9.jar
Dies ist das Währungspaar t Teil, um das Laufwerk zu bekommen Objekt:
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(authToken);
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = new AndroidJsonFactory();
drive = new Drive.Builder(transport, jsonFactory, credential)
.setApplicationName(getString(R.string.txt_appname))
.setJsonHttpRequestInitializer(
new GoogleKeyInitializer(APIKEY_SIMPLE))
.build();
if (drive != null) {
}
Leider hat weder nicht. Gleicher Fehler: 401, ungültiger Berechtigungsnachweis. Der einfache API-Schlüsselabschnitt erwähnt "... wenn Sie nicht auf Benutzerdaten zugreifen müssen ...", aber das gilt auch für meine Android-App. Ich verstehe es nicht. Gibt es niemanden, der erfolgreich eine Android-App erstellt hat, die eine Verbindung zu Google Drive-Daten im Auftrag eines Nutzers herstellt, der die Erlaubnis dazu über AccountManager und Google Credentials erteilt hat? –
Nun, der einzige Unterschied zwischen Ihrem Code und dem [Beispiel für eine Aufgaben-API] (https://code.google.com/p/google-api-java-client/source/browse/tasks-android-sample/src/main/ java/com/google/api/services/samples/tasks/android/TasksSample.java? repo = samples) Ich sehe dann, ist, dass sie 'credential.setAccessToken (authToken)' * nach dem Erstellen der 'Tasks' aufrufen Beispiel. Vielleicht macht der Austausch dieser 2 Linien den Trick? –
Kein Glück. Scheint, dass da etwas kaputt ist. Danke trotzdem. –