I have created my own custom account and that is working fine to add an account and to use it in the app.
I now want to be able to edit the account information instead of removing and adding an account. I have a number of fields on my account and some can be a bit lengthy, so removing and adding is rather cumbersome.
I have created the basics for this by adding my own PreferenceScreen and connected it via the android:accountPreferences in my account-authenticator XML file as per the example here: AbstractAccountAuthenticator.
In my PreferenceScreen I define an intent to open my activity that is used to enter the user data for the account.
<PreferenceScreen
android:key="edit"
android:title="Edit Account Details"
android:summary="Change System ID, user name, password etc.">
<intent
android:action="my.app.accountmanager.UserCredentialsActivity.ACCOUNT_SETUP"
android:targetPackage="my.app.accountmanager"
android:targetClass="my.app.accountmanager.UserCredentialsActivity" />
</PreferenceScreen>
My issue is, how do I either pass along as extras in the intent or find the account information for the account I selected in the Settings/Accounts & Sync. It is possible to have multiple accounts of this custom account type, so I can't just search for any account of that type. I need the data from the selected account.
My thoughts have roughly been in these areas:
Include something in the xml to add extras. Don't see how this can be possible.
Have the target for the intent be my AccountAuthenticator class or the authenciation service, but how do I pass in that I want to edit the data? Since AbstractAccountAuthenticator has a method updateCredentials that returns a bundle with the intent to my data entry activity, that could perhaps work if I could pass in an EDIT action or something like that.
Override some method somewhere to create my own intent with the account data.
I hope this is possible to do as both a Samsung app and the Dropbox app do this from the Accounts & Sync, although neither allow multiple accounts...
I think the accountPreferences attribute in AbstractAccountAuthenticator is going to be obsolete soon. If you look at the accounts in JB, if you add multiple accounts, it is going to be displayed like this
account1#gmail.com
account2#gmail.com
Preference
Instead of
account1#gmail.com -> Preference
account2#gmail.com -> Preference
And if you take a look at the Gmail app, the preferences (notifcation ringtone) for Gmail is configured within the Gmail app itself, and can't be configured from the Accounts & Settings page.
So, you should only use the accountPreferences attributes for preferences that are common to all accounts.
Related
I have a usual screen with "email" and "password" EditText fields. I have marked my fields with autofillHints, so that Android AutofillService could propose user already saved passwords. It's working. But looks like it only propose only that passwords which where previously entered in browser or somewhere else and where saved to my Google's accound via Google Password Manager. But those successful pairs of email and password, which where entered via native app Fragment -- it is not saving them after the login procedure. But I want to save those users credentials after successful Login/Register flow to be able them to be used via AutofillService to propose user to login with them.
So I assume there should be some sort of API which I can trigger in onLoginSuccess() method and save those credentials in Google Password Manager or whenever available Google Service to make it available to Autofill Service next time.
Offer to save passwords - enabled, AutofillService also enabled:
https://www.lifewire.com/how-to-manage-android-autofill-settings-4801221
AutofillService: https://developer.android.com/guide/topics/text/autofill-optimize
AutofillService for Jetpack compose: https://developer.android.com/reference/kotlin/androidx/compose/ui/autofill/package-summary
So How to trigger Google Password Manager in native XML view or Jetpack Compose to show popup to save user's password to use later in AutofillService? Thanks.
I have solved my issue with such libraries from Google:
Smart Lock for Passwords: https://developers.google.com/identity/smartlock-passwords/android/overview (outdated)
One Tap sign-in on Android: https://developers.google.com/identity/one-tap/android/overview (new one)
I personaly have used Smart Lock for Passwords (it's already outdated), but for my solution it works great and needs only little customization.
Because One Tap needs more time to proper set it up on server side to work with security tokens.
But pay attention - both of these libraries don't work in conjunction with Autofill Service with Jatpack compose. Probably they work with Autofill Service which is used with XML layouts, but is what I have discovered.
Just wondering how to do this on Android. My application needs to store a list of the user's accounts. Each account would have, account name username, password, server address etc.
I first tried to implement this with Preference Activity, this worked well but it seems to only result in a user interface for a single account. I am missing how to arrange this so the data is stored for an array of accounts, so if Account 3 is selected from a top level list the Preferences will display the settings for Account 3.
For example if you have an email app with multiple accounts, you want to be able to configure each account individually. They have the same settings, but different instances, so each account would have it's own preference file.
Thanks
You will most likely need a database (local sqlite usually) to store the data then you will have you use either the ListView and implement onClick methods OR as you say the PreferenceScreen and add preferences programmatically when you retrieve your data from the database for each account.
In order to achieve it take a look here
Dynamic ListPreference in android
or here
How can I keep on adding preferences when i click one?
hope this helps abit
I have created an android application where user need to login to store some info like their score, level and so on which are not needed to make secured or open for all.
Now don't want to prompt user to login or sign up, My question is how my application can automatically grab users identical info like his gmail address for his android account ?
After getting the email i can send the email associating with the application result.
Thanks.
You can store information on SharedPreferences
First register and play...blah blah, done gaming, write result to SharedPreferences
Next time loading, check/read SharedPreferences whether such info/data exists then process ... blah blah
Look up info on SharedPreferences: http://developer.android.com/reference/android/content/SharedPreferences.html
There is a very good example of this in the Google IO videos, unfortunately I cannot remember which one it is.
Basically you create a UUID and store it in the shared preferences so that if it is uninstalled then it respects privacy.
That UUID is then used to key all information, if the user wishes to sign up proplery then this key is used and can later be associated with a google ID making the process completely seamless other than a single sign in.
I think it's in the 2010 videos, but I cannot remember the speaker's name.
There is a link that covers some of the basics here:
How can I get the UUID of my Android phone in an application?
I've integrated android's account management in my application and I can manage accounts from the Accounts & Sync settings.
I want to have the classic login activity that forwards the user to his home activity on successful login, having the option to remember the user's password. However, the AccountAuthenticatorActivity must return its result to the AccountManager with the credentials and the rest of the account information, calling an explicit finish() and returning the intent.
How can I give the AccountManager the info it needs without having to finish() my login activity?
AccountManager is not meant to be called by an interactive application, but rather by a Sync Adapter. (A great tutorial is "Did You Win Yet? » Writing an Android Sync Provider" Part 1 and Part 2 which gives great code examples but doesn't do as great a job of explaining the data flow.) It's like this:
You develop a ContentProvider which wraps a database. You build a SyncAdapter (this is a background Service) to connect to a server and fetch data and sync the ContentProvider to match the server. Then, your UI queries to the ContentProvider to show the fetched data. There are some methods to directly query for specific information as well, if you want to search and cache results for example. See Developing RESTful Android Apps for a nice hour-long session on how the data model should look. They give three architecture examples, starting from a "naïve" implementation then progressing to the proper SyncAdapter model.
As for authentication itself, the way SyncAdapter uses the AccountManager is to obtain an authentication token. This is a (often) a big hexidecimal value, that is passed as part of the HTML headers in lieu of a username/password pair. Think of it as a one-session unique key. Posession of the key is proof of authentication, and they expire periodically. When they expire, you reauthenticate and fetch a new one. SyncAdapater asks AccountManager for an auth token for a specific account-type / username combination. AccountManager auths with the server (asking the user for a new password if necessary due to change) and returns the token to the SyncAdapter, which uses it from then on.
If this model isn't appropriate for your application, you need to manually handle login/logout in your app code instead. Kind of a pain, I know.
#jcwenger That is not entirely correct. You can use the AccountManager from an interactive application as well. For example, you can add accounts without invoking the account manager interface by using AccountManager's addAccountExplicitly() method.
On the "Did You Win Yet?" article you can clearly see that the account manager is invoked from the application's own Activity. This is useful if the application has its own account management interface.
My version of the 'classic flow' using AccountManager:
I use my AuthenticatorActivity both for the normal case where it's used via. Accounts & Sync Settings, but I also open it out for use by applications that rely upon the same Accounts.
I have a separate apk with the Authenticator implemented and other apps (separate apks) that rely upon these Accounts.
Cases handled:
the normal case: the user adds/authenticates via. Accounts & Sync (as per the Android sample project)
handle authentication requests from external apps:
How? I provide an intent filter in the Authenticator app's Manifest so other apps can instantiate the AuthenticatorActivity via. startActivityForResult (they must include an intent extra that indicates who they are (their app's package)). In the AuthenticatorActivity I detect this case and refrain from calling setAccountAuthenticatorResult when the authentication process has come to a end because I reserved it's use for the normal case above. The user enters their credentials and presses Sign In: AccountManger is checked for a matching account and if matched I
persist that Account's username as the active user for the calling app's package. I then return an intent to the calling app via. setResult indicating success, the username and account type. In the case where the Account didn't exist I go through the process that the normal case goes through, i.e. calling addAccountExplicitly and then set the active user and then as before calling setResult and finish.
Hope this helps someone.
Under the 'Accounts & Sync' settings graphical OS menu, there are listings of user-configured Google accounts.
Please could someone point me in the right direction to programmatically change the sync settings associated with one of these accounts?
Thanks
Those settings use the new AccountManager APIs. Here's some sample code that shows how to add a new account. I'd assume that you'd want to get the credentials of one of the existing accounts and simply modify the data.
Unfortunately, I haven't had a chance to try out those APIs yet.
Maybe ContentResolver#setIsSyncable() can do what you want.
Perhaps would be better to fire the android.provider.Settings.ACCOUNT_SYNC_SETTINGS intent with either the EXTRA_AUTHORITIES extra set to ["google.com"], or possibly put the extra named "account" as the Account object you got from AccountManager. Then your user can turn their sync on or off for themselves.
ContentResolver.setSyncAutomatically(account, authority, true/false): sets whether or not the provider is synced when it receives a network tickle.