In the SDK provided by Android, there is an example called Samplesyncadapter in the Samples directory, which is an instance of the account and synchronization, such as Google's original Android phone can use Google account to synchronize data. Specific
For example, if you want to synchronize your contacts to the server in real-time, you can use this example to understand the synchronization mechanism provided by Android to achieve your own synchronization capabilities.
This blog post first introduces the management part of the account. As for the account Management code is mainly in the authenticator package under the three classes, there is a call authenticator XML file.
AuthenticationService class
AuthenticationService is a service that inherits the service, which is actually provided to other processes to use, Its action for the Android.accounts.accountauthenticator,android system will pass this
Action to find it, and through it to register our own account into the "settings", in fact, this is a aidl use, it belongs to cross-process calls. Here is the registration in manifest:
<service
Android:name= ". Authenticator. AuthenticationService "
Android:exported= "true" >
<intent-filter>
<action
Android:name= "Android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
Android:name= "Android.accounts.AccountAuthenticator"
Android:resource= "@xml/authenticator"/>
</service>
The service returns a IBinder to the client process in the Onbind method, as follows:
@Override
Public IBinder Onbind (Intent Intent) {
if (log.isloggable (TAG, log.verbose)) {
LOG.V (TAG, "Getbinder () ... returning the Accountauthenticator binder for Intent"
+ intent);
}
return Mauthenticator.getibinder ();
}
Authenticator class
Authenticator is a class inherited from the Abstractaccountauthenticator, Abstractaccountauthenticator is a virtual class, it defines the processing phone "settings" in "Account and synchronization" Add, delete, and
Verify the basic interface of such functions, and implement some basic functions. Inside the Abstractaccountauthenticator, there is an inner class that inherits from Iaccountauthenticator.stub, to be used for Abstractaccountauthenticator's
The remote interface call is wrapped. We can return the IBinder form of the inner class through the Abstractaccountauthenticator Getibinder () method to make a remote call to this class, as in the preceding code Onbind method
Use. The source location of the abstractaccountauthenticator is in the Frameworks\base\core\java\android\accounts directory.
Authenticator only need to inherit and implement a few methods of abstractaccountauthenticator, like we introduced the Samplesyncadapter instance of the main inheritance of two methods, as follows
When adding an account in "settings", this method is called to jump to the Add Account page
@Override
Public Bundle AddAccount (accountauthenticatorresponse response, String AccountType,
String Authtokentype, string[] requiredfeatures, Bundle options) {
LOG.V (TAG, "AddAccount ()");
Specify Authenticatoractivity as the page for adding accounts, as described below.
Final Intent Intent = new Intent (Mcontext, Authenticatoractivity.class);
Intent.putextra (Accountmanager.key_account_authenticator_response, RESPONSE);
Final bundle bundle = new bundle ();
Bundle.putparcelable (Accountmanager.key_intent, INTENT);
return bundle;
}
When the Maccountmanager.blockinggetauthtoken (Account,constants.authtoken_type, notify_auth_failure) is executed, the method is called.
@Override
Public Bundle Getauthtoken (accountauthenticatorresponse response, account account,
String Authtokentype, Bundle loginoptions) throws Networkerrorexception {
LOG.V (TAG, "Getauthtoken ()");
Constants.authtoken_type through the Blockinggetauthtoken method
if (!authtokentype.equals (Constants.authtoken_type)) {
Final bundle result = new bundle ();
Result.putstring (accountmanager.key_error_message, "Invalid Authtokentype");
return result;
}
Final Accountmanager am = Accountmanager.get (mcontext);
Final String password = am.getpassword (account);
if (password! = null) {
Final String AuthToken = networkutilities.authenticate (account.name, password);
if (! Textutils.isempty (AuthToken)) {
If the account has been authenticated to the server and saved to Accountmanager
Final bundle result = new bundle ();
Result.putstring (Accountmanager.key_account_name, account.name);
Result.putstring (Accountmanager.key_account_type, Constants.account_type);
Result.putstring (Accountmanager.key_authtoken, AUTHTOKEN);
return result;
}
}
If the account has not been verified to the server and saved to Accountmanager, then re-add the Account page to verify.
Final Intent Intent = new Intent (Mcontext, Authenticatoractivity.class);
Intent.putextra (Authenticatoractivity.param_username, account.name);
Intent.putextra (Authenticatoractivity.param_authtoken_type, Authtokentype);
Intent.putextra (Accountmanager.key_account_authenticator_response, RESPONSE);
Final bundle bundle = new bundle ();
Bundle.putparcelable (Accountmanager.key_intent, INTENT);
return bundle;
}
Authenticatoractivity class
Authenticatoractivity is an inherited from the accountauthenticatoractivity activity,accountauthenticatoractivity source code is also in the frameworks\ Base\core\java\android\accounts Directory
Under One of the main methods of Authenticatoractivity is Handlelogin (view view), which is called when the Sign In button is clicked, which initiates an asynchronous task to request the server to authenticate the user's account. After successful verification, there is
An important way to do this:
/**
* Called when response was received from the server for authentication
* Request. See Onauthenticationresult (). Sets the
* Accountauthenticatorresult which is sent back to the caller. We Store the
* AuthToken that's returned from the server as the ' password ' for this
* account-so we ' re never storing the user ' s actual password locally.
*
* @param result the confirmcredentials result.
*/
private void Finishlogin (String authToken) {
LOG.I (TAG, "Finishlogin ()");
Final Account Account = new Account (Musername, constants.account_type);
if (Mrequestnewaccount) {
Add an account directly to Accountmanager
maccountmanager.addaccountexplicitly (account, Mpassword, null);
Settings allow this account to automatically sync
Contentresolver.setsyncautomatically (account, contactscontract.authority, true);
} else {
Maccountmanager.setpassword (account, Mpassword);
}
Final Intent Intent = new Intent ();
Intent.putextra (Accountmanager.key_account_name, musername);
Intent.putextra (Accountmanager.key_account_type, Constants.account_type);
Setaccountauthenticatorresult (Intent.getextras ());
Setresult (RESULT_OK, intent);
Finish ();
}
Authenticator.xml
In the above AuthenticationService registration there is a meta-data name of Android.accounts.AccountAuthenticator, it points to the XML file is Authenticator.xml, its contents are as follows:
<account-authenticator xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:accounttype= "Com.example.android.samplesync"
android:icon= "@drawable/icon"
android:smallicon= "@drawable/icon"
Android:label= "@string/label"
/>
The account type is Com.example.android.samplesync, which is the value of Constants.account_type. This is a bit like a widget that requires an XML to provide the information you want.