AccountManager - dem Geheimnis auf der Spur

  • Antworten:3
  • OffenNicht stickyNicht beantwortet

28.08.2010 21:36:38

Lange Zeit hatten Anwendungsentwickler das Problem, vom Benutzer Dinge abfragen zu müssen, die dem System (seinem Handy) eigentlich bekannt sind: zum Beispiel die Daten zu seinem Google Konto. Schon seit Eclair gibt es deshalb die Klasse AccountManager, die als zentrale Speicherstelle der vom Benutzer angemeldeten Onlinekonten fungiert. Die Idee ist, sich vom AccountManager einfach ein so genanntes Token geben zu lassen, um dann mit diesem Token auf einen Webservice zuzugreifen. Damit müsste es dann eigentlich ganz einfach sein, zum Beispiel mit Google Contacts oder Google Calendar zu reden, oder? Wer sich mal den Spaß gemacht hat, das Web daraufhin abzusuchen, wird wahrscheinlich zu dem Schluss kommen, dass es so ohne weiteres offenbar doch nicht geht.

Der folgende Codeschnipsel zeigt, dass es funktioniert. Eine Erklärung findet sich hier: http://kuennetht.blogspot.com/2010/08/accountmanager-dem-geheimnis-auf-der.html

1package com.thomaskuenneth;
2
3import java.io.InputStream;
4
5import org.apache.http.HttpResponse;
6import org.apache.http.client.HttpClient;
7import org.apache.http.client.methods.HttpGet;
8import org.apache.http.impl.client.DefaultHttpClient;
9
10import android.accounts.Account;
11import android.accounts.AccountManager;
12import android.accounts.AccountManagerCallback;
13import android.accounts.AccountManagerFuture;
14import android.app.Activity;
15import android.os.Bundle;
16import android.util.Log;
17import android.widget.TextView;
18
19public class TKSimpleTasks extends Activity {
20
21 private static final String TAG = TKSimpleTasks.class.getSimpleName();
22
23 @Override
24 public void onCreate(Bundle savedInstanceState) {
25 super.onCreate(savedInstanceState);
26 setContentView(R.layout.main);
27
28 AccountManager am = AccountManager.get(this);
29 Account[] accounts = am.getAccountsByType("com.google");
30 if (accounts.length < 1) {
31 finish();
32 }
33 String authTokenType = "cl";
34 Bundle options = null;
35 am.getAuthToken(accounts[0], authTokenType, options, this,
36 new AccountManagerCallback<Bundle>() {
37
38 public void run(AccountManagerFuture<Bundle> arg0) {
39 try {
40 Bundle b = arg0.getResult();
41 String token = b
42 .getString(AccountManager.KEY_AUTHTOKEN);
43 Log.d(TAG, token);
44
45 HttpGet get = new HttpGet(
46 "https://www.google.com/calendar/feeds/default/owncalendars/full");
47 get.addHeader("Authorization", "GoogleLogin auth="
48 + token);
49
50 HttpClient httpclient = new DefaultHttpClient();
51 HttpResponse r = httpclient.execute(get);
52 InputStream is = r.getEntity().getContent();
53 StringBuilder sb = new StringBuilder();
54 int ch;
55 while ((ch = is.read()) != -1) {
56 sb.append((char) ch);
57 }
58
59 ((TextView) findViewById(R.id.tv)).setText(sb
60 .toString());
61
62 } catch (Throwable thr) {
63 Log.e(TAG, thr.getMessage(), thr);
64 }
65 }
66 }, null);
67 }
68}

29.08.2010 00:47:10

Danke für das Snippet!

Kurze Frage dazu, ohne groß selbst auf Recherche gegangen zu sein, aber für den User macht es keinen Unterschied bei den Rechten, er sieht nur, dass die App die Benutzerdaten liest. Interessant wäre hier ein neues (?) Recht, um dem User zu zeigen, dass eine App nur indirekt auf die Login-Daten zugreift - sprich sie nicht in Klartext auslesen kann, sondern sich nur das Token holt. Oder gibt es so etwas schon? Auf dem Gebiet kenne ich mich nicht ganz so aus.

— geändert am 29.08.2010 00:47:54

29.08.2010 10:12:34

An Rechten muss die App GET_ACCOUNTS, USE_CREDENTIALS und INTERNET anfordern. Um auf deine Frage zu antworten, so ein "Sammelrecht" gibt es meines Wissens nach nicht. INTERNET braucht man übrigens nicht für das Abfragen und Auslesen der Konten, aber halt, um die http-Zugriffe machen zu können.

17.11.2011 19:46:22

Hallo,

ich habe in meiner App die Permissions get_accounts und _use_credentials eingebunden.
Trotzdem möchte die App beim ersten Anmelden mit einem Account nochmal "Berechtigung zulassen" und ein Passwort. Diese Activity öffnet sich aber nur im Hintergrund. Wie kann ich diese in den Vordergrund öffnen lassen?
Vielen Dank