2015-10-09 3 views
13

Um Benutzereinstellungen zu verwalten, greife ich derzeit den Google-Benutzernamen (effektiv die E-Mail-Adresse, die sie auf dem Gerät registriert haben) und verwenden (ein Hash von), die als "Benutzer-ID" zwischen verschiedenen unterscheiden Benutzer. Etwas in Anlehnung an das, was beschrieben wird here.Android: Benutzer-ID erhalten, ohne scary (für Benutzer) Berechtigungen?

Das funktioniert alles gut, aber einige Benutzer sind (verständlicherweise) durch irgendeine Erlaubnis verängstigt, die der App die böse Macht zu geben scheint, durch ihre Kontoinformationen oder Kontakte zu graben.

EDIT: Dieses Problem ist noch akuter mit der Art und Weise, in der Google Permission Groups im Android 6 runtime permission Schema implementiert hat. Sie haben GET_ACCOUNTS in die Berechtigungsgruppe CONTACTS eingegeben. Um nun eine eindeutige anonyme Benutzer-ID zu generieren, muss dem Benutzer ein Dialogfeld mit folgenden Angaben angezeigt werden:

Ermöglicht dieser App den Zugriff auf Ihre Kontakte? | Verweigern | Erlaube |

Wie irreführend ist das ?? Meine App möchte nicht auf Kontakte zugreifen, aber der Benutzer wird aufgefordert, der App den Zugriff auf Kontakte zu gewähren. Ja, es gibt eine Möglichkeit, dem Benutzer mit einem separaten Dialog zu erklären, dass der Zugriff auf Kontakte zwar NICHT erforderlich ist, aber dann immer noch der Börsensystemdialog erscheint, der sie auffordert, Zugriff auf Kontakte zu gewähren ... natürlich sie wird denken "Warum werde ich gebeten, diese Erlaubnis zu erteilen, wenn der Zugang zu Kontakten nicht erforderlich ist?" und "vertraue ich wirklich dem Entwickler? Sie sagen, dass Zugriff auf Kontakte nicht erforderlich ist, aber ist das wirklich wahr?" ... sehr sehr verwirrend und eine sehr schlechte Benutzererfahrung IMHO (und die Meinung von others too).

Ich würde lieber all diese Hektik und Verwirrung vermeiden und eine eindeutige Benutzer-ID ohne spezielle Berechtigungen erhalten.

Gibt es im SDK eine Bestandsfunktion oder -methode, die eine eindeutige Benutzer-ID für den Benutzer zurückgibt, ohne dass zusätzliche Berechtigungen erforderlich sind? Ich bin etwas überrascht, wenn das nicht der Fall ist, denn es scheint ziemlich normal zu sein, eine Benutzer-ID für die Verwaltung von App-Benutzern zu haben.

Zwei Punkte:

(a) Ich brauche nur ein anonymes Benutzer-ID, ... Ich brauche nicht tatsächlich den E-Mail-Adresse des Nutzers, noch würde ich will immer den E-Mail-Adresse des Benutzers. Ich kann also nicht sehen, warum Google keine getUserID() Methode bereitstellen kann, die eine eindeutige anonymisierte ID zurückgibt, ohne der App spezielle Berechtigungen zu erteilen.

(b) Es muss sich um eine Benutzer-ID und nicht um eine Geräte-ID handeln, damit es auf allen Geräten des Benutzers funktioniert, die für dasselbe Google-Konto registriert sind.

Danke.

+0

vielleicht können Sie gcmid verwenden? –

+1

Die GCM-ID kann sich ändern, wenn der Nutzer die Daten der Google Play Services-App löscht, was beim Lesen im Internet geschieht. Dadurch wird die Aktualisierung der Android-Software beschleunigt oder einige Fehler behoben ... –

+1

Sie können ein einzigartiges Gerät erhalten ID: http://StackOverflow.com/a/17625641/1048340 Natürlich wird dies nicht Benutzer mit mehr als einem Gerät berücksichtigen. Dies könnte eine gute Option sein, um die E-Mail-Adresse ohne Berechtigungen zu erhalten: http://stackoverflow.com/a/19444640/1048340 –

Antwort

6

Wenn Sie die Google Play-Dienste verwenden, können Sie den Kontotyp und den Kontonamen ohne zusätzliche Berechtigungen abrufen.

Fügen Sie zunächst die folgende Abhängigkeit build.gradle:

compile 'com.google.android.gms:play-services-auth:8.4.0' 

Als nächstes starten Sie das Konto Chooser Absicht:

Intent intent = AccountPicker.newChooseAccountIntent(null, null, 
    new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, 
    false, null, null, null, null); 

try { 
    startActivityForResult(intent, REQUEST_CODE_EMAIL); 
} catch (ActivityNotFoundException e) { 
    // This device may not have Google Play Services installed. 
    // TODO: do something else 
} 

Schließlich überschreiben onActivityResult den Kontotyp zu erhalten und Account-Name:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == REQUEST_CODE_EMAIL && resultCode == RESULT_OK) { 
    String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); 
    String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE); 
    // TODO: do something with the accountName 
    return; 
    } 
    super.onActivityResult(requestCode, resultCode, data); 
} 

Quelle: https://stackoverflow.com/a/19444640/1048340

+0

Hmm, kann ich bitte etwas klären? Die [API-Dokumentation] (https://developers.google.com/android/reference/com/google/android/gms/common/AccountPicker.html) sagt, dass, wenn '' alwaysPromptForAccount' 'false' ist, wie Sie es haben oben, dann "wird der Kontoauswahlbildschirm ... nur angezeigt, wenn mehr als ein Konto ausgewählt werden kann oder die aufrufende App nicht über die Berechtigung GET_ACCOUNTS verfügt." Und wir möchten die Berechtigung GET_ACCOUNTS nicht anfordern. Das bedeutet, dass der Kontoauswahlbildschirm IMMER angezeigt wird, selbst wenn nur ein Konto vorhanden ist. Ist das wahr? – snark

+0

Der Grund, warum ich frage, ist, weil ich die In-App-Käufe der Benutzer mit ihrem Benutzerkonto verknüpfe. Zurzeit beantrage ich die GET_ACCOUNTS-Berechtigung, aber ich würde gerne diese Anforderung entfernen. Es hört sich jedoch so an, als müsste ich jedes Mal, wenn sie die App nutzen, um das Konto des Benutzers bitten, auch wenn sie nur ein Konto haben. Dies ist eine noch schlechtere Benutzererfahrung, als wenn sie nur einmal im Voraus nach der Berechtigung "Kontakte" gefragt werden. – snark

+0

Ich kann jetzt meine eigene Frage beantworten, nachdem ich den obigen Code in eine einfache Test-App geschrieben habe. Ja, die App zeigt die Kontoauswahl jedes Mal an, wenn Sie nur ein Konto haben, wenn die App nicht über die Berechtigung GET_ACCOUNTS verfügt. Natürlich könnten Sie den zurückgegebenen Kontonamen speichern, aber dann müssten Sie davon ausgehen, dass er sich nicht ändert, was keine sichere Annahme ist, da [Apps weiterhin installiert bleiben, wenn ein Benutzer sein Konto auf einem Gerät ändert] (http: //android.stackexchange.com/a/24484/155892). Die Verwendung des Kontopickers ist daher bei In-App-Käufen keine wirklich praktikable Lösung. – snark

-1

Leider gibt es dafür keine Lösung, selbst der grundlegendste Kontozugriff erfordert Benutzerrechte.

+0

** AccountPicker ** benötigt keine Berechtigungen. Haben Sie Folgendes gesehen: https://developers.google.com/android/reference/com/google/android/gms/common/AccountPicker –

0

Sie können eine Google-Werbung ID als UUID verwenden, aber es ist nicht Cross-Device (noch?):

https://support.google.com/googleplay/android-developer/answer/6048248?hl=en

Das zumindest wird von der unheimlichen Erlaubnisanfrag loszuwerden.

Ich glaube nicht, dass Android/Google eine geräteübergreifende UUID hat, die keine Erlaubnis erfordert, obwohl Doubleclick von Google angeblich eine entwickelte.

+0

~ "** Geräteübergreifende UUID, für die keine Berechtigung erforderlich ist **". AccountPicker benötigt keine Berechtigungen und zeigt die gleichen Benutzer-IDs für mehrere Geräte an. –

2

Sie die genaue gmail E-Mail-Adresse erhalten können mit AccountPickerohne die Berechtigungen hinzuzufügen, erforderlich ist.

Ihre App muss die Google Play-Dienste schließen, aber es braucht nicht alle Berechtigungen.

Dieser ganze Prozess auf ältere Versionen von Android wird scheitern (2.2+ ist erforderlich), oder wenn Google Play nicht zur Verfügung steht so sollten Sie dieser Fall in Betracht ziehen.

Beispielcode aus der Quelle:

private static final int REQUEST_CODE_EMAIL = 1; 
    private TextView email = (TextView) findViewById(R.id.email); 

    // ... 

    try { 
     Intent intent = AccountPicker.newChooseAccountIntent(null, null, 
       new String[] { GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE }, false, null, null, null, null); 
     startActivityForResult(intent, REQUEST_CODE_EMAIL); 
    } catch (ActivityNotFoundException e) { 
     // TODO 
    } 

    // ... 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == REQUEST_CODE_EMAIL && resultCode == RESULT_OK) { 
      String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); 
      email.setText(accountName); 
     } 
    } 

Quelle der oben genannten Informationen ist: This Answer on SO - zu einer ähnlichen, aber etwas anderen Frage in der Vergangenheit gefragt.

This Post - hat auch einige nette Ansätze, die Ihren Zweck erfüllen würden.