Sprechen Sie über das Abrufen einer Kontakt-E-Mail-Adresse?
Austyn Mahoney
1
Nein, die primäre E-Mail-Adresse des Geräts.
Brandon O'Rourke
Es gibt eine oder mehrere E-Mail-Adressen, die mit einem Android-Gerät verknüpft sind, oder? Das würde ich wollen.
Brandon O'Rourke
2
@ BrandonO'Rourke Meinst du "die primäre E-Mail-Adresse des Geräts" als die mit dem Android Market verknüpfte? Weil es einen Unterschied zwischen der mit dem Android Market verknüpften Google Mail-ID und anderen E-Mails gibt. Werfen
Gaurav Agarwal
Antworten:
749
Es gibt verschiedene Möglichkeiten, dies zu tun (siehe unten).
Seien Sie als freundliche Warnung vorsichtig und offen gegenüber dem Benutzer, wenn Sie mit Konto-, Profil- und Kontaktdaten umgehen. Wenn Sie die E-Mail-Adresse eines Benutzers oder andere persönliche Informationen missbrauchen, können schlimme Dinge passieren.
Sie können AccountManager.getAccountsoder verwenden AccountManager.getAccountsByType, um eine Liste aller Kontonamen auf dem Gerät abzurufen. Glücklicherweise sind die Kontonamen für bestimmte Kontotypen (einschließlich com.google) E-Mail-Adressen. Beispielausschnitt unten.
Ab Android 4.0 (Ice Cream Sandwich) können Sie die E-Mail-Adressen des Benutzers abrufen, indem Sie auf sein Profil zugreifen. Der Zugriff auf das Benutzerprofil ist etwas schwerfällig, da zwei Berechtigungen erforderlich sind (mehr dazu weiter unten), aber E-Mail-Adressen sind ziemlich vertrauliche Daten, daher ist dies der Eintrittspreis.
Im Folgenden finden Sie ein vollständiges Beispiel, CursorLoaderin dem Profildatenzeilen mit E-Mail-Adressen mit a abgerufen werden.
publicclassExampleActivityextendsActivityimplementsLoaderManager.LoaderCallbacks<Cursor>{publicvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLoaderManager().initLoader(0,null,this);}@OverridepublicLoader<Cursor> onCreateLoader(int id,Bundle arguments){returnnewCursorLoader(this,// Retrieve data rows for the device user's 'profile' contact.Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,ContactsContract.Contacts.Data.CONTENT_DIRECTORY),ProfileQuery.PROJECTION,// Select only email addresses.ContactsContract.Contacts.Data.MIMETYPE +" = ?",newString[]{ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE},// Show primary email addresses first. Note that there won't be// a primary email address if the user hasn't specified one.ContactsContract.Contacts.Data.IS_PRIMARY +" DESC");}@Overridepublicvoid onLoadFinished(Loader<Cursor> cursorLoader,Cursor cursor){List<String> emails =newArrayList<String>();
cursor.moveToFirst();while(!cursor.isAfterLast()){
emails.add(cursor.getString(ProfileQuery.ADDRESS));// Potentially filter on ProfileQuery.IS_PRIMARY
cursor.moveToNext();}...}@Overridepublicvoid onLoaderReset(Loader<Cursor> cursorLoader){}privateinterfaceProfileQuery{String[] PROJECTION ={ContactsContract.CommonDataKinds.Email.ADDRESS,ContactsContract.CommonDataKinds.Email.IS_PRIMARY,};int ADDRESS =0;int IS_PRIMARY =1;}}
Dies erfordert sowohl die READ_PROFILEals auch die READ_CONTACTSBerechtigungen:
Ich habe eine ähnliche Frage mit Ihrem Code. Ich kann alle mit meinem Telefon verknüpften Google Mail-IDs abrufen, aber ich möchte die primäre. Ich habe eine Lösung gefunden, wie wenn wir mehr Mail-IDs hinzufügen, um sie mit dem Telefon zu synchronisieren. Wenn ich die 0. Position von com.google IDs erhalte, erhalte ich die primäre, weil sie zuerst eingegeben wird und die 0. Position in einem Stapel erhält . Hier ist mein Code Account [] accounts = AccountManager.get (this) .getAccountsByType ("com.google"); String myEmailid = accounts [0] .toString (); Log.d ("Meine E-Mail-ID, die ich möchte", myEmailid); Ich weiß, es ist nicht der richtige Weg.
PiyushMishra
59
Die Profilmethode ist (meiner Meinung nach) stark fehlerhaft. Eine App, die meine E-Mail möchte / benötigt, ist keine große Sache im Vergleich zu einer App, die alle meine Kontakte lesen möchte, aber Sie haben es so gemacht, dass beide die gleichen Berechtigungen benötigen. Als Benutzer kann ich den Unterschied zwischen einer App, die meine E-Mails liest, und einer App, die meine über 500 Kontakte liest, nicht erkennen. Dies ist ein sehr reales, praktisches Problem, da die Anzahl der Apps, die Ihre Kontakte missbrauchen, zunimmt!
Tom
3
@ Muzikant Es ist keineswegs eine offizielle Erklärung, aber es ist ziemlich unwahrscheinlich, dass sich daran etwas ändert. Die "richtige" Art, auf die E-Mail-Adressen eines Benutzers zuzugreifen, ist jedoch Methode B. Das ist "offizieller" und die Tatsache, dass es hinter einigen Schwergewichtsberechtigungen steckt, sollte die Sensibilität anzeigen, mit der Sie sich solchen Daten nähern sollten.
Roman Nurik
15
Ich stimme @Tom darin zu. Es ist lächerlich, nur nach dem Vor- und Nachnamen des Benutzers um Erlaubnis für die Daten aller Kontakte auf dem Telefon zu bitten.
Tasomaniac
3
Methode B funktioniert bei Android 4.4 nicht und kopiert den gesamten Beispielcode. cursor.isAfterLast()gibt immer true zurück. Irgendeine Idee?
Dies ist eine sehr hilfreiche Antwort. Ich denke, dies sollte die bevorzugte Option sein, da primäre E-Mail normalerweise das Google-Konto bedeutet, das Sie wiederum in Verbindung mit Google Play haben
Alex.F
@ Alex.F Funktioniert das für Android-Versionen nach / von Marshmellow?
Eswar
27
Ich würde den in ICS eingeführten AccountPicker von Android verwenden .
Beachten Sie, dass Sie Spieldienste verwenden müssen und in einigen Fällen ein Dialogfeld angezeigt wird, in dem der Benutzer das Konto auswählen muss.
Android-Entwickler
Verwenden Sie AccountManager.newChooseAccountIntent (), um denselben Job auszuführen, und benötigen Sie nicht die Play-Services-Bibliothek.
Denis
Wird dem Benutzer ein Popup zur Kontoauthentifizierung im Kontext der neuesten Android-Version angezeigt? Wenn ja, wie kann ich das für ein Gerät mit nur einem Konto umgehen?
Eswar
14
publicString getUsername(){AccountManager manager =AccountManager.get(this);Account[] accounts = manager.getAccountsByType("com.google");List<String> possibleEmails =newLinkedList<String>();for(Account account : accounts){// TODO: Check possibleEmail against an email regex or treat// account.name as an email address only for certain account.type values.
possibleEmails.add(account.name);}if(!possibleEmails.isEmpty()&& possibleEmails.get(0)!=null){String email = possibleEmails.get(0);String[] parts = email.split("@");if(parts.length >1)return parts[0];}returnnull;}
Beachten Sie, dass dies eine android.permission.GET_ACCOUNTS"gefährliche" Berechtigung erfordert (Laufzeitanforderung erforderlich): developer.android.com/reference/android/…
SagiLow
@SagiLow Wie bist du damit umgegangen? Ich möchte den Benutzer nicht um eine weitere Erlaubnis bitten, nur um ihn faul zu machen, seine E-Mail-Adresse einzugeben :)
Codebasiert
1
@codebased Ich habe nicht ... es ist meines Wissens nicht möglich.
SagiLow
2
manager.getAccountsByType ("com.google"); funktioniert nicht mit späteren Versionen von Android.
Android wurde GET_ACCOUNTSkürzlich gesperrt, sodass einige der Antworten bei mir nicht funktionierten. Ich habe dies auf Android 7.0 mit der Einschränkung funktioniert, dass Ihre Benutzer einen Berechtigungsdialog ertragen müssen.
Dies unterscheidet sich nicht von anderen Antworten und es funktioniert nicht für mich - anscheinend, weil in neueren Versionen von Android nur Konten zurückgegeben werden, die mit der App verknüpft sind, und keine Berechtigung mehr erforderlich ist.
<Verwendet-Erlaubnis android: name = "android.permission.GET_ACCOUNTS" />
Keshav Gera
1
Antworten auf Konten abrufen hat bei mir nicht funktioniert (0 Konten zurückgeben) - und ich kann bestätigen, dass das Aufrufen des Codes in einem Tastenrückruf keinen Unterschied gemacht hat.
csga5000
Dieser Code funktioniert, aber vor kurzem habe ich Zeitprobleme, also überprüfen Sie bitte unsere Seite
Keshav Gera
0
Fügen Sie diese einzelne Zeile im Manifest hinzu ( zur Erlaubnis )
Antworten:
Es gibt verschiedene Möglichkeiten, dies zu tun (siehe unten).
Seien Sie als freundliche Warnung vorsichtig und offen gegenüber dem Benutzer, wenn Sie mit Konto-, Profil- und Kontaktdaten umgehen. Wenn Sie die E-Mail-Adresse eines Benutzers oder andere persönliche Informationen missbrauchen, können schlimme Dinge passieren.
Methode A: Verwenden Sie AccountManager (API Level 5+)
Sie können
AccountManager.getAccounts
oder verwendenAccountManager.getAccountsByType
, um eine Liste aller Kontonamen auf dem Gerät abzurufen. Glücklicherweise sind die Kontonamen für bestimmte Kontotypen (einschließlichcom.google
) E-Mail-Adressen. Beispielausschnitt unten.Beachten Sie, dass hierfür die
GET_ACCOUNTS
Berechtigung erforderlich ist :Weitere Informationen zur Verwendung
AccountManager
finden Sie im Contact Manager Beispielcode im SDK.Methode B: Verwenden Sie ContactsContract.Profile (API Level 14+)
Ab Android 4.0 (Ice Cream Sandwich) können Sie die E-Mail-Adressen des Benutzers abrufen, indem Sie auf sein Profil zugreifen. Der Zugriff auf das Benutzerprofil ist etwas schwerfällig, da zwei Berechtigungen erforderlich sind (mehr dazu weiter unten), aber E-Mail-Adressen sind ziemlich vertrauliche Daten, daher ist dies der Eintrittspreis.
Im Folgenden finden Sie ein vollständiges Beispiel,
CursorLoader
in dem Profildatenzeilen mit E-Mail-Adressen mit a abgerufen werden.Dies erfordert sowohl die
READ_PROFILE
als auch dieREAD_CONTACTS
Berechtigungen:quelle
cursor.isAfterLast()
gibt immer true zurück. Irgendeine Idee?Dies könnte für andere nützlich sein:
Verwenden von AccountPicker, um die E-Mail-Adresse des Benutzers ohne globale Berechtigungen abzurufen und dem Benutzer zu ermöglichen, den Vorgang zu kennen und zu autorisieren oder abzubrechen.
quelle
Ich würde den in ICS eingeführten AccountPicker von Android verwenden .
Und dann warten Sie auf das Ergebnis:
quelle
quelle
android.permission.GET_ACCOUNTS
"gefährliche" Berechtigung erfordert (Laufzeitanforderung erforderlich): developer.android.com/reference/android/…Es gibt eine Android-API, mit der der Benutzer seine E-Mail-Adresse ohne Erlaubnis auswählen kann. Schauen Sie sich Folgendes an: https://developers.google.com/identity/smartlock-passwords/android/retrieve-hints
Dies zeigt eine Auswahl an, in der der Benutzer eine E-Mail-Adresse auswählen kann. Das Ergebnis wird in geliefert
onActivityResult()
quelle
Leider funktioniert die akzeptierte Antwort nicht.
Ich bin spät dran, aber hier ist die Lösung für die interne Android-E-Mail-Anwendung, es sei denn, die Inhalts-URL wird vom Anbieter geändert:
quelle
Dies ist ziemlich schwierig in Android und ich habe es noch nicht getan. Aber vielleicht helfen Ihnen diese Links:
quelle
Verwenden Sie diese Methode:
Beachten Sie, dass hierfür die
GET_ACCOUNTS
Berechtigung erforderlich ist :Dann:
quelle
Die vorgeschlagenen Antworten funktionieren nicht mehr, da ab Android 8 eine neue Einschränkung gilt.
Weitere Informationen hier: https://developer.android.com/about/versions/oreo/android-8.0-changes.html#aaad
quelle
Android wurde
GET_ACCOUNTS
kürzlich gesperrt, sodass einige der Antworten bei mir nicht funktionierten. Ich habe dies auf Android 7.0 mit der Einschränkung funktioniert, dass Ihre Benutzer einen Berechtigungsdialog ertragen müssen.AndroidManifest.xml
MainActivity.java
quelle
Arbeiten im MarshMallow-Betriebssystem
quelle
Fügen Sie diese einzelne Zeile im Manifest hinzu ( zur Erlaubnis )
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Fügen Sie diesen Code dann in Ihre Aktivität ein
quelle